Home
The jQuery Mobile tutorial - Managing input fields

Chapter 14

Managing input fields

The input fields can be of two types: a single line or multiline. In the first case, they correspond to <input> elements with the type="text" attribute, while in the latter they are <textarea> elements. jQuery Mobile has also introduced search fields, to enter a value to search for. These three types of input fields are managed by the standard methods of jQuery, but jQuery Mobile also added the textinput () method. The input fields are associated with the textinput standard component.

Dynamically create an input field

Input on one line

To dynamically create an input field of a single line with JavaScript, simply create a <input> element with the type="text" attribute.

Create an input field dynamically

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "Name : <input type=text value='Sarrion' />";

$("#home div:jqmData(role=content)").append (html);


</script>




Input on multiple lines

Now let's create a <textarea> element that will contain the multiline text field.

Create a multiline text field dynamically

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "Description : <textarea> Beautiful sunny studio. Reasonable price.</textarea>";

$("#home div:jqmData(role=content)").append (html);


</script>




Search field

Creating a search field is done using a <input> element with the type="search" attribute.

Dynamic creation of a search field

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "Name : <input type=search value='Sarrion' />";

$("#home div:jqmData(role=content)").append (html);


</script>




Turning a HTML element into a jQuery Mobile input field

Input on one line

When creating an input field on one line, jQuery Mobile adds to the corresponding <input> element some CSS classes that can assign a width and height, and a shaded border. To verify this, we can use the previous program and look into Firebug HTML code generated by jQuery Mobile.




We see that the <input> element has now a new ui-input-text CSS class and other classes managing the rounded edges of the border.

Input on multiple lines

Consider the HTML generated by jQuery Mobile for the previous program that displays the multiline input field.




We find the ui-input-text class again, but this time applied to the <textarea> element.

Search field

Do the same for the previous program that displays the search field:




We see that the HTML transformation performed by jQuery Mobile is more complex. A <div> element with ui-input-search class, including the <input> element, was created containing also an <a> link corresponding to the button associated with the erase icon to the right of the field.

Note also that the <input> element now has the type="true" attribute (instead of type="search"), and the new data-type attribute has been set equal to "search".

Insert input fields by Ajax

We now want to retrieve from the server the HTML corresponding to an input field on a line, a search field and a multiline input field, and then insert the result in the contents of the window.

Insert input fields by Ajax

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


$.ajax (

  url : "action.php", 

  complete : function (xhr, result)

  {

    if (result != "success") return;

    var response = xhr.responseText;

    $("#home div:jqmData(role=content)").append (response);

    $(":text").textinput ();

    $("textarea").textinput ();

    $("[type=search]").textinput ();

  }

});   


</script>

Note the call to the textinput () method on elements associated with input fields. It is necessary to transform the appearance of input fields that would otherwise be displayed without jQuery Mobile aspect.

action.php file

<?
$html = "";
$html .= "Name : <input type=text value=Sarrion /> <br />";
$html .= "Description : <textarea>Nice studio for renovation </textarea> <br />";
$html .= "Search : <input type=search value=Name />";

echo utf8_encode ($html);
?>




Assign and retrieve the value in an input field

The value in the input field (on a single line or multiline) can be affected by the val (value) method and recovered by the val () method. Both methods are part of the jQuery methods.

Suppose we have an HTML code that contains a text input field (the name of a person), a <textarea> element to enter a description, and finally a search field (for the name of a person). These three fields are initialized with default values, but we want to change this value programmatically by JavaScript.

Here is the HTML code that could be written. We will then see why some parts do not work.

Initialize input fields by JavaScript

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

    Name : <input type=text value="Your name" id=text /> <br />

    Description : <textarea> Description </textarea> <br />

    Search : <input type=search value="Your name" id=search />

  </div>

</div>


</body>

</html>


<script>


alert ($("#text").val ("Eric").val ());

alert ($("textarea").val ("Nice studio for renovation").val ());

alert ($("#search").val ("Sarrion").val ());

  

</script>

When running the program, we have three alert windows containing respectively the value Eric, Nice studio for renovation, Sarrion. These values are part of the input fields of the window, except for the search field which remains unchanged.




We see that the value Sarrion did not replace the default Your name entered in the search field. This means that the approach to the search fields is different from other input fields.

One line and multiple lines inputs

We have already seen that the use of val () (to recover the value of an input field) and val (value) (to assign a new value in an input field) methods worked perfectly.

Assign and then read the value of a <input> element with type="text" attribute

alert ($(":text").val ("Eric").val ());

                           // Displays: Eric

Selector ":text" is the selector "type = text".

Assign and then read the value of a <textarea> element

alert ($("textarea").val ("Nice studio for renovation").val ());

                           // Displays: Nice studio for renovation

Search field

For a search field, the technique is more complicated. Indeed, the original HTML code is modified by jQuery Mobile, so it is not enough to write:

Assign and then read the value of an <input> element with type="search" attribute (as it does not work!)

alert ($("#search").val ("Sarrion").val ());

                           // Displays: Sarrion

The alert displays the modified text (Sarrion), but the display window does not contain this value! (the input field is not changed). The reason is simple: val ("Sarrion") instruction is executed before the search field has been fully created. We must therefore wait for the search field to finish to be created to modify its contents.

To understand the actions to be undertaken the easiest way is to look at how jQuery Mobile modified the code of our HTML input fields:




We see that the input field of a single line and multiline input field is slightly modified by adding CSS classes that allow the styling. The biggest change occurs in the search field now included in a <div> element with ui-input-search CSS class. In fact the initial <input> element is completely recreated and inserted into this new <div> element.

Modify the contents of the search field after its creation

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

    Name : <input type=text value="Your name" id=text /> <br />

    Description : <textarea> Description </textarea> <br />

    Search : <input type=search value="Your name" id=search />

  </div>

</div>


</body>

</html>


<script>


alert ($("#text").val ("Eric").val ());

alert ($("textarea").val ("Nice studio for renovation").val ());


$("#search").live ("textinputcreate", function (event)

{

  alert ($("#search").val ("Sarrion").val ());

});


</script>

Note that the <input> element associated with the search field (with search identifier) must be observed by means of the live () method and not bind (). Indeed, the <input> element that will receive the textinputcreate event does not yet exist when the event is set, since this element will be created by jQuery Mobile. The live () jQuery method is used to position an event for future elements in the DOM tree, while the bind () method only deals with existing items at this time there.

One can check that the search field is now updated with the correct value.




Manage events on input fields

The input fields receive standard events, and can be observed using the bind () method of jQuery. Note that jQuery Mobile retains the same event names that are either on a touch screen or on a classical computer.

Events on the input fields

Name

Signification

click

vclick

A click was made in the field.

focus

The field has just won the focus.

blur

The field has lost focus.

change

The field content has changed (detected when the field loses focus).

keyup

A keyboard key was pressed.

keydown

A keyboard key was released.

mousedown

vmousedown

The left mouse button was pressed (or the finger touched the field).

mouseup

vmouseup

The left mouse button was released (or the finger was removed from the screen).

Taking into account of a click in an input field

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "Name : <input type=text value='Sarrion' />";

$("#home div:jqmData(role=content)").append (html);


$("input").bind ("vclick", function (event)

{

  alert ("click");

});


</script>

Taking into account of a click in a search field

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "Search : <input type=search value='Your name' id=search />";

$("#home div:jqmData(role=content)").append (html);


$("#search").live ("textinputcreate", function (event)

{

  $("#search").bind ("vclick", function (event)

  {

    alert ("click");

  });

});


</script>

We here have to wait until the search field has been created, otherwise the <input> element used in the bind ("vclick" ...) does not exist at the time of the execution of the bind (). We have the same problem if the HTML of the search field is inserted directly into the HTML (instead of being inserted by JavaScript as before). For example:

Search field inserted directly into the HTML

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>  

    Search : <input type=search value="Your name" id=search />

  </div>

</div>


</body>

</html>


<script>


$("#search").live ("textinputcreate", function (event)

{

  $("#search").bind ("vclick", function (event)

  {

    alert ("click");

  });

});


</script>

As explained above, taking into account the click event (or vclick) in the treatment of the textinputcreate event is essential, otherwise the click is not taken into account.

Customize input fields

Change the appearance of an input field that does not have focus

Using Firebug we can verify that the input fields have the ui-input-text CSS class. This class is assigned to <input> or <textarea> elements. In addition, if the <input> element is a search field, the surrounding <div> created by jQuery Mobile has a ui-input-search CSS class.

Use these CSS classes to give a new aspect to the input fields:

Styling input fields

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

  

  <style type=text/css>

    .ui-input-text, .ui-input-search {

      color : white; 

      background-color : black;

    }

  </style>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

    Name : <input type=text value=Sarrion /> <br />

    Description : <textarea> Nice studio for renovation </textarea> <br />

    Search : <input type=search value="Your name" />

  </div>

</div>


</body>

</html>


<script>


</script>




Change the appearance of an input field that has focus

When the input field has focus, jQuery Mobile assigned the ui-focus CSS class. This class is affected:

Use this class to style as before, only the fields that have focus (the fields not having the focus will not be styled by us).

Styling fields that have focus

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

  

  <style type=text/css>

    .ui-focus {

      color : white; 

      background-color : black;

    }

    .ui-input-search.ui-focus > .ui-input-text {

      color : white; 

    }

  </style>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

    Name : <input type=text value=Sarrion /> <br />

    Description : <textarea> Nice studio for renovation </textarea> <br />

    Search : <input type=search value="Your name" />

  </div>

</div>


</body>

</html>


<script>


</script>

Examples of manipulation of input fields

Communicate the value of an input field on the server by Ajax

We wish to enter a name and forward it to the server that sends it to us in its response. We display that response in the window, allowing to verify that the communication with the server is effective in both directions.

Transmit by Ajax the name entered

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

    Name : <input type=text /> <br />

  </div>

</div>


</body>

</html>


<script>


$("input").bind ("change", function (event)

{

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

  

  $.ajax (

  

    url : "action.php", 

    data : { name : name },

    complete : function (xhr, result)

    {

      if (result != "success") return;

      var response = xhr.responseText;

      $("#home div:jqmData(role=content)").append (response);

    }

  });   

});


</script>

We use the change event to pass the name to the server. This name will be transmitted only if it has changed in the input field. The server response is inserted into the window using append (response).

action.php file

<?
$name = $_REQUEST["name"];
echo utf8_encode ("<p> The name entered is $name </p>");
?>

This is the window that appears when several names were introduced into this:




Display the server's response in a new window

Rather than inserting the response received in the same window, we now want to insert in a new window and display it.

Display a new window containing the server response

<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content 1 </p>

    Name : <input type=text /> <br />

  </div>

</div>


<div data-role=page id=win2 data-add-back-btn=true>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content 2 </p>

  </div>

</div>


</body>

</html>


<script>


$("input").bind ("change", function (event)

{

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

  

  $.ajax (

  

    url : "action.php", 

    data : { name : name },

    complete : function (xhr, result)

    {

      if (result != "success") return;

      var response = xhr.responseText;

      $("#win2 div:jqmData(role=content)").append (response);

      $.mobile.changePage ($("#win2"));

    }

  });   

});


</script>

action.php file

<?
$name = $_REQUEST["name"];
echo utf8_encode ("<p> The name entered is $name </p>");
?>

As soon as the field entered is seen as modified (change event), the Ajax call is made and the second window appears.




Copyright Eric Sarrion (ericsarrion@gmail.com)