Hack 18. Dynamically Generate a New Checkbox
|
|
This assignment begins in the window's onload event handler. This event takes place when the browser has finished loading all the elements in the HTML page:
var sportType="";
var request=null;
window.onload=function( ){
var rads = document.getElementsByTagName("input");
if(rads != null) {
for(var i = 0; i < rads.length; i++) {
if(rads[i].type=="radio"){ rads[i].onclick=function( ){
getSports(this)};}
}
}
}
function getSports(obj){
if (obj == null ) { return; }
var url = "";
var val = "";
if(obj.checked) {
val=obj.value;
sportType=val;
url = "http://www.parkerriver.com/s/fav_sports"+
"?sportType="+encodeURIComponent(val)+"&col=y";
httpRequest("GET",url,true);
}
}
//event handler for XMLHttpRequest
function handleResponse( ){
try{
if(request.readyState == 4){
if(request.status == 200){
var resp = request.responseText;
if(resp != null){
//return value is an array
var objt = eval(resp);
createChecks(objt);
}
}
else {
//request.status is 503
//if the application isn't available;
//500 if the application has a bug
alert(
"A problem occurred with communicating between"+
" the XMLHttpRequest object and the server program.");
}
}//end outer if
} catch (err) {
alert("It does not appear that the server "+
"is available for this application. Please"+
" try again very soon. \nError: "+err.message);
}
}
function createChecks(obj){
var _div = document.getElementById("checks");
var el;
//first remove all existing checkboxes
while(_div.hasChildNodes( )){
for(var i = 0; i < _div.childNodes.length; i++){
_div.removeChild(_div.firstChild);
}
}
//obj is an array of new sports names
for(var i=0; i < obj.length;i++) {
el = document.createElement("input");
el.setAttribute("type","checkbox");
el.setAttribute("name",sportType);
el.setAttribute("value",obj[i]);
_div.appendChild(el);
_div.appendChild(document.createTextNode(obj[i]));
_div.appendChild(document.createElement("br"));
}
}
/* httpRequest( ) and related code omitted for the sake of brevity;
see Hack #1 or #2. */
The first stage in generating the checkboxes is to send the request that fetches the values for each widget. When the user clicks a radio button, the code calls getSports( ) . This function formats a URL based on the value it receives from the checkbox, then sends a request to a server component for a list of related sports.
The response comes back from the server in a string formatted as a JavaScript array. A response might look like:
["football","soccer","tennis", etc.]
You get the response from the request object's responseText property and then convert the response to a JavaScript array using the eval( ) global function. Phew, that was a mouthful!
|
Once the code has this
array
of values from the server, it
function createChecks(obj){
var _div = document.getElementById("checks");
var el;
//first remove all existing checkboxes
while(_div.hasChildNodes( )){
for(var i = 0; i < _div.childNodes.length; i++){
_div.removeChild(_div.firstChild);
}
}
//obj is an array of new sports names
for(var i=0; i < obj.length;i++) {
el = document.createElement("input");
el.setAttribute("type","checkbox");
el.setAttribute("name",sportType);
el.setAttribute("value",obj[i]);
_div.appendChild(el);
_div.appendChild(document.createTextNode(obj[i]));
_div.appendChild(document.createElement("br"));
}
The function gets a reference to the
div
element on the HTML page that will enclose the checkboxes. The code then
<input type="checkbox" name= "team_sports" value="baseball" /> baseball<br />
As soon as this function finishes executing, the checkboxes appear on the web page without any visible refresh. Like magic!
Naturally, you want the user to select one or more of these generated checkboxes for some purpose. Maybe to generate another subset of widgets or checkboxes? Or to send the values from the new checkboxes, when the user clicks them, to a server component? You can adapt the code from "Submit Checkbox Values to the Server Without a Round Trip" [Hack #17] to accomplish the latter task, as well as create onclick event handlers for the new checkboxes (as in this hack) to give them some behavior.