Spicing up old date input forms using Dojo's DateTextBox widget
Posted November 2nd, 2007 by achillean in
I've recently been working a lot w/ Django and have used some of its facilities to automatically generate forms. While that's pretty nifty, I wanted the date fields to be assisted by javascript, more specifically Dojo. I think it's fair to say that most new websites need to have a dropdown date calendar when letting the user select a date. Fortunately, this turns out to be very simple using Dojo.
The general gist of the way I implemented this was to:
For obvious reasons I'm going to keep the form short and simple, but just wanted to make sure we're all on the same page (no pun intended). Anyways, here's the javascript code that I use (Warning: assumes that you've already loaded the dojo.js file, please refer to the xhrGet/ xhrPost story for details on how to do that).
The first function in the code is string_to_date. I couldn't find a good Dojo function that simply takes a string (in the 'YYYY-MM-DD' format) and converts it to a Date object, so I hacked that together briefly (got parts of it from old Dojo code). You should do more error-checking in a production environment, but it'll do for this example.
Afterwards, I define the init_form function, which finds the form element, takes its value (if it exists) and converts it to a Date object, and then finally feeds all of the info the the DateTextBox constructor. It's important that you give the constructor the name parameter to make sure your current form-parsing code (in PHP, Python, whatever) still works, since Dojo by default doesn't assign a name to the DateTextBox input field.
And lastly, we tell dojo to call the init_form function once the page has been loaded. And that's it! It's really not a lot of code or complicated logic, so I hope you'll try and spice up ye olde web forms you've got lying around using Dojo.
The general gist of the way I implemented this was to:
- Let Django create the HTML form.
- Create a function that gets called onLoad and turns specific fields into DateTextBoxes by programmatically creating them.
<form action='.' method='POST'>
Birth Date: <input type='input' name='birth_date' />
</form>
Birth Date: <input type='input' name='birth_date' />
</form>
For obvious reasons I'm going to keep the form short and simple, but just wanted to make sure we're all on the same page (no pun intended). Anyways, here's the javascript code that I use (Warning: assumes that you've already loaded the dojo.js file, please refer to the xhrGet/ xhrPost story for details on how to do that).
function string_to_date (args) {
args = dojo.string.trim(args);
arr = args.split('-');
return new Date (parseInt(arr[0]), parseInt(arr[1], 10) - 1, parseInt(arr[2].substr(0,2), 10));
}
// Add the DateTextBox widget
function init_form () {
dojo.require('dijit.form.DateTextBox');
dojo.require('dojo.date');
dojo.require('dojo.string');
// Birth Day
var div = document.getElementsByName('birth_date')[0];
var val = ''
if (dojo.string.trim(div.value) != '') {
val = string_to_date (div.value);
}
var w = new dijit.form.DateTextBox ({
name: div.name,
value: val
}, div);
}
dojo.addOnLoad (init_form);
args = dojo.string.trim(args);
arr = args.split('-');
return new Date (parseInt(arr[0]), parseInt(arr[1], 10) - 1, parseInt(arr[2].substr(0,2), 10));
}
// Add the DateTextBox widget
function init_form () {
dojo.require('dijit.form.DateTextBox');
dojo.require('dojo.date');
dojo.require('dojo.string');
// Birth Day
var div = document.getElementsByName('birth_date')[0];
var val = ''
if (dojo.string.trim(div.value) != '') {
val = string_to_date (div.value);
}
var w = new dijit.form.DateTextBox ({
name: div.name,
value: val
}, div);
}
dojo.addOnLoad (init_form);
The first function in the code is string_to_date. I couldn't find a good Dojo function that simply takes a string (in the 'YYYY-MM-DD' format) and converts it to a Date object, so I hacked that together briefly (got parts of it from old Dojo code). You should do more error-checking in a production environment, but it'll do for this example.
Afterwards, I define the init_form function, which finds the form element, takes its value (if it exists) and converts it to a Date object, and then finally feeds all of the info the the DateTextBox constructor. It's important that you give the constructor the name parameter to make sure your current form-parsing code (in PHP, Python, whatever) still works, since Dojo by default doesn't assign a name to the DateTextBox input field.
And lastly, we tell dojo to call the init_form function once the page has been loaded. And that's it! It's really not a lot of code or complicated logic, so I hope you'll try and spice up ye olde web forms you've got lying around using Dojo.
Dojo Example: xhrGet and xhrPost
Posted October 12th, 2007 by achillean
Before I start covering more advanced topics, I'll focus the next few weeks on the basics of the Dojo Toolkit. As such, the first topic that needs to be discussed is the work-horse of any modern AJAX application: the asynchronous calls to a website. There are 2 functions of importance in Dojo: xhrGet and xhrPost. But enough talk, let me show the examples:
Example: http://www.dojoforum.com/demo-0.9/xhr/xhrGet.html
The above code should be self-explanatory for the most part, though I did slip in a small function call that might be unfamiliar to people that have never seen Dojo: dojo.byId(). There's not much magic in the function, it's simply a much shorter alias for document.getElementById().
Example: http://www.dojoforum.com/demo-0.9/xhr/xhrPost.html
Most of the above code should look very familiar, as it's basically the same as xhrGet. In fact, xhrGet also supports the 'form' argument to its function call, but it's advised not to use it. If you want to see the source of the PHP file 'parse_form.php' then click here
I hope these brief examples have given you a glimpse into the most basic asynchronous XMLHttpRequest calls provided by the Dojo Toolkit. From here you should take a look at dojo.io.iframe.send(), dojox.io.xhrMultiPart() and for eye-candy dojox.widget.Loader.
xhrGet
Description: The work-horse of the dojotoolkit, it allows you to send HTTP GET requests asynchronously.Use it anytime you need to grab information from the server asynchronously. The only exception is that you shouldn't use xhrGet for forms, use xhrPost!Example: http://www.dojoforum.com/demo-0.9/xhr/xhrGet.html
<html>
<head>
<title>Dojo xhrGet and xhrPost</title>
<!-- Initialize Dojo -->
<script src='/dojo-0.9/dojo/dojo.js' type='text/javascript'></script>
<script type='text/javascript'>
//<!--
// Function that retrieves the remote HTML and puts it into
// the <div> with an id of 'html-content'.
function getHtml () {
dojo.xhrGet ({
// Location of the HTML content we want to grab
url: '/demo-0.9/xhr/content.html',
// Called when the page loaded successfully
load: function (data) {
dojo.byId('html-content').innerHTML = data;
},
// Called if there was an error (such as a 404 response)
error: function (data) {
console.error('Error: ', data);
}
});
}
// Function that retrieves a JSON object and puts the information
// into the <div> with an id of 'json-content'. Notice how we're defining
// 'handleAs' to be of type 'json' now. That lets Dojo know that the data being
// retrieved from the URL should be eval()-ed and converted to a javascript object.
function getJson () {
dojo.xhrGet ({
url: '/demo-0.9/xhr/content.json',
handleAs: 'json', // IMPORTANT: tells Dojo to automatically parse the HTTP response into a JSON object
load: function (data) {
dojo.byId('json-content').innerHTML = data.content;
},
error: function (error) {
console.error('Error: ', error);
}
});
}
//-->
</script>
</head>
<body>
<div id='html-content'><a href='#' onClick='getHtml();'>Click me to get some HTML content</a></div>
<div id='json-content'><a href='#' onClick='getJson();'>Click me to get some JSON content</a></div>
</body>
</html>
<head>
<title>Dojo xhrGet and xhrPost</title>
<!-- Initialize Dojo -->
<script src='/dojo-0.9/dojo/dojo.js' type='text/javascript'></script>
<script type='text/javascript'>
//<!--
// Function that retrieves the remote HTML and puts it into
// the <div> with an id of 'html-content'.
function getHtml () {
dojo.xhrGet ({
// Location of the HTML content we want to grab
url: '/demo-0.9/xhr/content.html',
// Called when the page loaded successfully
load: function (data) {
dojo.byId('html-content').innerHTML = data;
},
// Called if there was an error (such as a 404 response)
error: function (data) {
console.error('Error: ', data);
}
});
}
// Function that retrieves a JSON object and puts the information
// into the <div> with an id of 'json-content'. Notice how we're defining
// 'handleAs' to be of type 'json' now. That lets Dojo know that the data being
// retrieved from the URL should be eval()-ed and converted to a javascript object.
function getJson () {
dojo.xhrGet ({
url: '/demo-0.9/xhr/content.json',
handleAs: 'json', // IMPORTANT: tells Dojo to automatically parse the HTTP response into a JSON object
load: function (data) {
dojo.byId('json-content').innerHTML = data.content;
},
error: function (error) {
console.error('Error: ', error);
}
});
}
//-->
</script>
</head>
<body>
<div id='html-content'><a href='#' onClick='getHtml();'>Click me to get some HTML content</a></div>
<div id='json-content'><a href='#' onClick='getJson();'>Click me to get some JSON content</a></div>
</body>
</html>
The above code should be self-explanatory for the most part, though I did slip in a small function call that might be unfamiliar to people that have never seen Dojo: dojo.byId(). There's not much magic in the function, it's simply a much shorter alias for document.getElementById().
xhrPost
Description: It submits a HTTP POST request asynchronously. Use xhrPost when you want to send form data to a website and the form doesn't contain any file-input fields. (use dojo.io.iframe.send() instead)Example: http://www.dojoforum.com/demo-0.9/xhr/xhrPost.html
<html>
<head>
<title>Dojo Example: xhrGet and xhrPost</title>
<!-- Initialize Dojo -->
<script src='/dojo-0.9/dojo/dojo.js' type='text/javascript'></script>
<script type='text/javascript'>
//<!--
// The following function submits the data from the 'post-form' form
// to a PHP script located at
// 'http://www.dojoforum.com/demo-0.9/xhr/parse_form.php'
// The PHP script simply outputs a string in the format of
// 'Hello $name!', which is then put in the <div> w/ the id
// of 'response'.
//
// NOTE: As with xhrGet, you can also use handleAs to accept
// JSON objects in your load() function.
function submitForm() {
dojo.xhrPost ({
// The page that parses the POST request
url: '/demo-0.9/xhr/parse_form.php',
// Name of the Form we want to submit
form: 'post-form',
// Loads this function if everything went ok
load: function (data) {
// Put the data into the appropriate <div>
dojo.byId('response').innerHTML = data;
},
// Call this function if an error happened
error: function (error) {
console.error ('Error: ', error);
}
});
}
//-->
</script>
</head>
<body>
<div id='response'></div>
<div>
<form method='post' id='post-form'>
<input type='text' name='name' />
<a href='#' onClick='submitForm();'>Submit Form</a>
</form>
</div>
</body>
</html>
<head>
<title>Dojo Example: xhrGet and xhrPost</title>
<!-- Initialize Dojo -->
<script src='/dojo-0.9/dojo/dojo.js' type='text/javascript'></script>
<script type='text/javascript'>
//<!--
// The following function submits the data from the 'post-form' form
// to a PHP script located at
// 'http://www.dojoforum.com/demo-0.9/xhr/parse_form.php'
// The PHP script simply outputs a string in the format of
// 'Hello $name!', which is then put in the <div> w/ the id
// of 'response'.
//
// NOTE: As with xhrGet, you can also use handleAs to accept
// JSON objects in your load() function.
function submitForm() {
dojo.xhrPost ({
// The page that parses the POST request
url: '/demo-0.9/xhr/parse_form.php',
// Name of the Form we want to submit
form: 'post-form',
// Loads this function if everything went ok
load: function (data) {
// Put the data into the appropriate <div>
dojo.byId('response').innerHTML = data;
},
// Call this function if an error happened
error: function (error) {
console.error ('Error: ', error);
}
});
}
//-->
</script>
</head>
<body>
<div id='response'></div>
<div>
<form method='post' id='post-form'>
<input type='text' name='name' />
<a href='#' onClick='submitForm();'>Submit Form</a>
</form>
</div>
</body>
</html>
Most of the above code should look very familiar, as it's basically the same as xhrGet. In fact, xhrGet also supports the 'form' argument to its function call, but it's advised not to use it. If you want to see the source of the PHP file 'parse_form.php' then click here
I hope these brief examples have given you a glimpse into the most basic asynchronous XMLHttpRequest calls provided by the Dojo Toolkit. From here you should take a look at dojo.io.iframe.send(), dojox.io.xhrMultiPart() and for eye-candy dojox.widget.Loader.
Dojo Forum