jQuery 3 - Forms
jQuery 3 - Forms
Written by Ian Elliot   
Monday, 26 December 2016
Article Index
jQuery 3 - Forms
Form Selectors
Hand coded

 

GET & POST

Now that we know how to build a form UI within a form element and we know how to trigger a submit event the only question left is how is the form data gathered and how is the data sent to the server?

When the form element receives a submit event it scans though all of the elements it contains i.e. the child elements and it takes the name of each one and the value of each one and makes up a list of name/value pairs. Some fairly obvious processing is performed for example only the name and value of the currently selected radio button is included deselected radio buttons are ignored. 

Once the form element has the set of name value pairs it sends it to the server as part of the get or post request for the next page. If a get is specified then the name value pairs are sent as a query string i.e. as part of the URL and the client can see them in the address bar. If a post is used then the name value pairs are included in the body of the HTTP request to the server and these are not visible to the client. 

Using a get means we can see what is going on without having to implement a handler on the server. 

For example consider the simple form:

<form action="mypage.html" method="get">
 <input type="text" name="username"/><br/>
 <input type="submit" />
</form>

When the user clicks the submit button the form element gathers the name value pairs of its children - in this case only username and what ever the user has typed in - codes it as a query string and sends it as a get request for mypage.html. The URL sent will be something like:

http://domain/mypage.html?username=myvalue

assuming that the user entered myvalue. Of course an JavaScript that you might want to include in mypage can access the query string and process it.

In this case we send the form's data to the server which immediately sends it back to the client for any further processing. This is not the usual way that form data is processed. What usually happens is that the form sends the data to the sever specifying a program that will process the data on the server and then return whatever HTML is appropriate. For example, the URL might specify a PHP page which then uses PHP to access the query string or the query strings parameters and process them. This is of course the only way you can work if you specify a POST as the method and in this case the PHP has to access the POST data. 

jQuery Form Selectors

At this point you might be wondering what jQuery can do to make forms easier to use and it is worth saying that jQuery doesn't do as much as it could. There are some jQuery plugins that add features like data validation but even if you don't want to use one of these jQuery helps implementing special form handling easier. 

The biggest simplification is that jQuery provides an extended set of selectors to find standard form elements. 

  • :button Selects all button elements and elements of type button.
  • :checkbox Selects all elements of type checkbox.
  • :checked Matches all elements that are checked or selected.
  • :disabled Selects all elements that are disabled.
  • :enabled Selects all elements that are enabled.
  • :file Selects all elements of type file.
  • :focus Selects element if it is currently focused.
  • :image Selects all elements of type image.
  • :input Selects all input, textarea, select and button elements.
  • :password Selects all password elements
  • :radio Selects all elements of type radio.
  • :reset Selects all elements of type reset.
  • :selected Selects all elements that are selected.
  • :submit Selects all elements of type submit.

All of these selectors are jQuery extensions and do not take advantage of the optimization possible in modern browsers using standard CSS selectors. If you are worried about efficiency you can usually work out a pure CSS equivalent of most of these selectors. For example instead of :radio you can use an attribute selector as a radio button has the attribute type=radio however if you use [type="radio"] this is equivalent to *[type="radio"] and it will search every element for type=radio. It is much better to use input[type="radio"] because this examines the attributes only of input elements.

Usually you also want to restrict your selection to a given form. There are a number of ways of doing this but the simplest is to make sure that each form has an id and then use something like:

var form=$("#form1>*");
var text=form.filter(":text");

The first select returns all of the direct children of the form with id set to form1. The second returns all of the text input elements within the form. If you save the form query you can use it to do multiple queries on different type of form element. You can get and set the value of the form element using the val function e.g.

text.val();

is the value of the first text element in the result.  

If you want to select an input element based on its name then you have to use an attribute selector. For example:

var text=form.filter("[name='username']");

selects the elements in the form with name equal to username. What you have to keep in mind is that the name attribute isn't unique like an id and you might well get multiple results. For example a set of radio buttons all share the same name because this groups them together so that only one is selected. 

Form Events And Validation

jQuery provides a number of functions that make it simpler to hook into form events. The most important of which is .submit() this can be used to trigger a submit event on a form element or assign an event handler which is called before the form processes the data. 

For example if you want to have a button or some other UI element trigger the form submit you can do something like:

<button id="mySubmit" onclick="doSubmit()">
 Submit
</button>

 and in the button's click event handler you simply call submit on the form element:

function doSubmit(){
 $("#form1").submit();
}

A common mistake is to call submit on the button element. A submit event has to be directed to the form element for it to work. You can use the submit() function to trigger the event from any other element or set of conditions. For example you could auto-submit the form if the user is leaving the page.

The most common use of the submit function is to attach an event handler for the submit event. For example:

$("#form1").submit(handleSubmit);

will result in handleSubmit being called when the submit event is triggered on the form with id form1. You can stop the form being submitted by returning false or using preventDefault() as in 

function handleSubmit(e){
 alert("submit");
 e.preventDefault();
}

There are two reasons for intercepting the submit event. The first is to validate the data entered into the form and asking the user to correct it before resubmitting. The second is to modify the method of sending the data to an Ajax call.

Validating form data can be achieved in many ways. There is a jQuery addon that makes validation easier and HTML5 has validation features built into the input elements. The core of jQuery doesn't provide much to help you implement validation but it is fairly easy and you probably don't need much help. For example, to validate a simple user name input field so that it only accepted if there are no digits you would use something like:

function handleSubmit(e){
 var form=$("#form1>*");
 var text=form.filter("[name='username']").val();
 if( /[0-9]/.test(text)===false) return true;
 return false;
}

This works by first finding the form and then extracting its direct children and then the value of the username input element. Finally the if statement uses a regular expression to test to see if it contains any digits - if it does then we return false. If you want to you can write this in a shorter form:

function handleSubmit(e){
 var form=$("#form1>*");
 var valid= /[0-9]/.test(
    form.filter("[name='username']").val());
 return !valid;
}

This generalizes to the idiom:

var valid= /regex/.test(
    form.filter("[name='name']").val());

where regex is a regular expression that the field corresponding to name has to satisfy to be valid. Of course in a form with multiple fields you would test each field and flag the errors for the user before aborting the submit event. You can also test to make sure that a field has an entry if it is a required field. 

HTML 5 has all of this built into its input types. You can specify a pattern attribute. which is a regex that the field has to make true to be valid. and there is a required attribute which stops the submit unless there is an entry. You can see that it is fairly easy to implement these features and more using simple JavaScript.

Hooking into the submit event is a good way to validate a form when it is complete but users prefer to be informed if something is wrong with a field while they are entering it rather than when the form is complete. You can implement a more immediate feedback using the change() function which can be used to trigger a change event or set a handler for a change event. You can set a change event handler any input elements, textarea and select elements. For select , checkboxes and radio buttons the event occurs as soon as any change is made. For the others the event is deferred until the element loses focus and the user moves on to another element. 

For example to test the username input element as soon as the user has finished with it to make sure it doesn't contain any digits as we did using the submit you would use something like:

$("#form1>*").filter("
    [name='username']").change(handleChange);

and the event handler would be:

function handleChange(){
 if( /[0-9]/.test( $(this).val())){
  alert("a user name cannot contain digits");
 }
}

Note that we can make use of the fact that in an event handler this references the DOM element that the event occurred on. 

In general it is better to validate a field using the change event and get the user to attend any problems as soon as possible. Sometimes this isn't easy but it is still worth the additional effort. For example, there is nothing more annoying that entering a user name and lots of other details only to be told that the user name is already taken following form submission. The problem is how do you validate a user name and check that it is free? The answer is of course to use an Ajax request for the server to validate the entry.

For some elements the change event is only triggered when the element loses focus and the user moves the cursor to some other element. There are a set of events that you can use to control what happens when the focus shifts to all elements. 

.focus() is triggered when an element gains the focus

.blur() is triggered when focus leaves and element

.focusin() is triggered when an element or any element it contains gets the focus

.focusout() is triggered when an element or any element inside of it loses the focus

There is also a more specialized event .select that is triggered when the user selects text within a textarea or an input text element. This is more often used to implement mini-text editors and similar than it is to validate entries. 



Last Updated ( Monday, 26 December 2016 )
 
 

   
Banner
Copyright © 2017 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.