Working with Events in jQuery

Now you get to put together not only your knowledge of events, but your cumulative work with jQuery. One of the most common features of any database-driven web application is a registration form. E-mail, social networks, or anywhere you want to post content, at the very least you’ll need to provide an e-mail and a password. In this sample application, you create a skeleton that could easily serve for a more complex/complete user registration form. The form will ask for a username, e-mail, password, and password confirmation. Although the application doesn’t actually save (yet), a button is provided for validating the inputs. All fields are required, and the passwords must match in order to pass validation. Optionally, the user may add location information; in this case, a simple drop-down select for U.S. state and city information.

Clicking the Add Location button generates a state drop-down and a city drop-down that are dependent — when the state value is changed, so is the list of available cities. Of course, the values available for state and city are by no means comprehensive, or even practical, considering that only the U.S. is considered. But, for the purposes of this example it suffices. Figure 5-6 demonstrates the implemented registration form.

First, begin with the basic markup. This should be old hat by now. After all of the regular boilerplate HTML, the body consists of a div for displaying any error messages, and a form with text inputs and two password inputs. At the bottom are two buttons. Notice that the body contains only HTML elements, and absolutely no JavaScript, as it should be.

<!DOCTYPE html>

<html>

<head>

<title>User Registration and Validation</title>

<script src=”http://code.jquery.com/jquery-1.7.1.js”></script>

<script>

$(function(){

// jQuery code will go here

)};

</script>

</head>

<body>

<div id=”msg”></div>

<form name=”userRegistrationForm”>

<label for=”userName”>User</label><input type=”text” name=”userName” /><br/>

<label for=”email”>Email</label><input type=”text” name=”email” /><br/>

<label for=”password”>Password</label><input type=”text” name=”password” /><br/>

<label for=”chkPassword”>Re-enter Password</label>

<input type=”text” name=”chkPassword” /><br/>

<input type=”button” name=”validate” value=”Validate Inputs” />

</form>

<input type=”button” name=”addLocation” value=”Add Location” />

</body>

</html>

The $(function(){…}); as you’ll recall is equivalent to using .ready(), which executes the enclosed code after all DOM elements are loaded, but before the full document is loaded with all assets. The first action to add is the validation of the fields. The validation will occur upon a click event of the validate button. Using the jQuery attribute selector to get the validate button as wrapped object, you then apply a click event with anonymous function as its handler. Whenever the validate button is clicked the msg div has its content removed using the .html() method to get rid of any old messages. Then all of the input values are extracted using .val().

Using && operators to simplify the conditional tests, when a value of any of the inputs is empty (null), some text is appended to the msg div, and the CSS styling of the font color is changed to red on the fly. The second check confirms that both passwords match using the identity operator (===), and just like the previous validation, upon failure adds a text message to the msg div. Only one of the two messages is ever shown, never both at the same time. Figures 5-7 and 5-8 illustrate each of the messages being shown, individually.

$( ‘input[name=”validate”]’ ).click(function(){

// clear message div

$(“#msg”).html(“”);

// get values for all input boxes

var userName = $( ‘input[name=”userName”]’ ).val();

var email = $( ’input[name=”email”]’ ).val();

var passl = $( ‘input[name=”passwordu]’ ).val();

var pass2 = $( ‘input[name=uchkPassword”]’ ).val();

// no empty values permitted

var hasValue = userName && email && pass1 && pass2;

if( !hasValue ){

$(“#msg”)

.append(“All Fields are required.”)

.css(“color”,”red”);

return false;

}

// check that passwords match

var passwordMatch = false;

if( passl === pass2 ) {

passwordMatch = true;

}

if( IpasswordMatch ){

$(“#msg”).append(“<p>Passwords don’t match.</p>”).css(“color”, “red”);

return false;

}

});

Now for the tricky part; neither of the drop-downs exists in the DOM until the Add Location button is clicked. Hence, the elements must be generated by jQuery, but this also means that the event handlers must be created using .live() rather than .bind().

$( “input[name=’addLocation’]” ).click(function(){

$( “body” )

.append( “<select name=’stateCombo’>”

+ “<option>Select State</option></select>” );

Here, .append() is used to create the select element inside of the click event handler (listener) for the Add Location button. Clicking this button multiple times will continue to append select elements to the document body. To prevent a user from doing this, you can disable the button after a single click:

$(this).attr(“disabled”/ “disabled”);

For the limited location options, I’ve picked three states: California, Florida, and New York. A string for each is kept in an array, which is iterated over when generating the select list. Simultaneously, a second select list (for the city) is also appended to the document body, without any data.

// add some sample states

var states = [“California”, “Florida”, “New York”];

$.each(states, function(index, value){

$(“[name=’stateCombo’]”)

.append(“<option value=’”+index+”’>” + value + “</option>”);

});

// add another empty select list

$(“body”)

.append(“<select name=’cityCombo’><option>Select City</option></select>”);

});

Notice that some concatenation of strings is required here for the HTML strings. This is a perfect place to use a more readable jQuery string template, which you’ll see in Chapter 11. In the next snippet, the “change” event is bound to the state select element, or combo box, using the .live() method. This way you don’t have to worry about whether the select element actually exists at load time.

Three string arrays with city names for each of the different states are stored in transient variables. Depending on which state is selected (0 for California, 1 for Florida, and 2 for New York) determines which array is saved to the cities array, which in turn is then used to load the city select element. Each time the state changes, the city select element, cityCombo, is emptied, or in other words, all of its children are removed from the DOM altogether.

// use .live() since states select box doesn’t exist yet

$(“[name=’stateCombo’]”).live(“change”, function(event){

// get name of state and fill with some data

var selectedState = $(this).val();

var CA_Cities = [“San Francisco”, “Los Angeles”, “Mountain View”];

var FL_Cities = [“Fort Lauderdale”, “Miami”, “Orlando”];

var NY_Cities = [“New York”, “Buffalo”, “Ithica”];

var cities = [];

if(selectedState == 0){

cities = $.extend([], CA_Cities);

} else if(selectedState == 1){

cities = $.extend([], FL_Cities);

} else if(selectedState == 2){

cities = $.extend([],NY_Cities);

}

// clear cityCombo of any previous values

$(”[name= ‘cityCombo’]”).empty();

$.each(cities/ function(index, value){

$(“[name= ‘cityCombo’]”).append(“<option value= ‘” + index+ ” ‘>”

+value+”</option>”);

});

});

Now, you can put all this together into the complete application, shown in the final code snippet of this chapter. Several improvements come to mind, such as a mask for the e-mail address field, perhaps by use of a third-party plugin, but for demonstrating handlers for dynamically generated elements, as well as some of the more common events, such as mouse clicks and ready, this example works just fine.

<!DOCTYPE html>

<html>

<head>

<title>User Registration and Validation</title>

<script src=”http://code.jquery.com/jquery-1.7.1.js”></script>

<script>

$(function(){

$( ‘input[name= “validate”]’ ).click(function(){

// clear message div

$(“#msg”).html(” “);

// get values for all input boxes

var userName = $( ‘input[name=”userName”]’ ).val();

var email = $( ‘input[name=”email”]’ ).val();

var passl = $( ‘input[name=”password”]’ ).val();

var pass2 = $( ‘input[name=”chkPassword”]’ ).val();

// no empty values permitted

var hasValue = userName && email && passl && pass2;

if( !hasValue ){

$(“#msg”)

.append(“All Fields are required.”)

.css(“color”,”red”);

return false;

}

// check that passwords match

var passwordMatch = false;

if( passl === pass2 ) {

passwordMatch = true;

}

if( !passwordMatch ){

$(“#msg”).append(“<p>Passwords don’t match. </p>”).css(“color”, “red”);

return false;

}

});

$( “input[name=,addLocation,]” ).click(function(){

$( “body” ).append( “<select name=,stateCombo,><option>”

+ “Select State</option></select>” );

// disable add location button so that we don’t get

// more than one drop-down

$(this).attr(“disabled”, “disabled”);

// add some sample states

var states = [“California”, “Florida”, “New York”];

$.each(states, function(index, value){

$(“[name= ‘stateCombo’]”).append(“<option value='”

+ index

+ “’>”

+ value

+ “</option>”);

});

// add another empty select list

$(“body”).append(“<select name= ‘cityCombo’>”

+ “<option>Select City</option></select>”);

});

// use .live() since states select box doesn’t exist yet

$(“[name=’stateCombo’]”).live(“change”, function(event){

// get name of state and fill with some data

var selectedState = $(this).val();

var CA_Cities = [“San Francisco”, “Los Angeles”, “Mountain View”];

var FL_Cities = [“Fort Lauderdale”, “Miami”, “Orlando”];

var NY_Cities = [“New York”, “Buffalo”, “Ithica”];

var cities = [];

if(selectedState == 0){

cities = $.extend([], CA_Cities);

} else if(selectedState == 1){

cities = $.extend([], FL_Cities);

} else if(selectedState == 2){

cities = $.extend([],NY_Cities);

}

// clear cityCombo of any previous values

$(“[name= ‘cityCombo’]”).empty();

$.each(cities, function(index, value){

$(“[name= ‘cityCombo’]”).append(“<option value= ‘ “

+index

+ “‘>”

+value

+”</option>”);

});

});

});

</script>

</head>

<body>

<div id=”msg”></div>

<form name=”userRegistrationForm”>

<label for=”userName”>User</label>

<input type=”text” name=”userName” /><br/>

<label for=”email”>Email</label>

<input type=”text” name=”email” /><br/>

<label for=”password”>Password</label>

<input type=”password” name=”password” /><br/>

<label for=”chkPassword”>Re-enter Password</label>

<input type=”text” name=”chkPassword” /><br/>

<input type=”button” name=”validate” value=”Validate Inputs” />

</form>

<input type=”button” name=”addLocation” value=”Add Location” />

</body>

</html>

Code snippet is from event-handling.txt

Source: Otero Cesar, Rob Larsen (2012), Professional jQuery, John Wiley & Sons, Inc

Leave a Reply

Your email address will not be published. Required fields are marked *