Home
The jQuery Mobile tutorial - Managing lists

Chapter 11

Managing lists

Manipulation of lists displayed by jQuery Mobile will be through the basics of jQuery. jQuery Mobile has also implemented the listview () method to use them. The lists are associated with the listview standard component.

Dynamically create a list

Lists can be created directly in the HTML code as we did in the previous section (see Chapter 3). jQuery Mobile automatically converts the HTML by adding new CSS classes to view the list items more enjoyable.

It is also possible to dynamically create a new list, based on the methods of jQuery.

List without images

In the following example, we create an initial list from the HTML code listed on the page, then a second list is created dynamically by JavaScript code. Finally, the appearance of the two lists are identical, which means how to create them is irrelevant.

Dynamic creation of a list

<!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>

    <ol id=list1 data-role=listview data-inset=true>

      <li data-role=list-divider>Static list</li>

      <li data-icon=delete>

        <a href=#>Element 1.1</a>

      </li>

      <li data-icon=delete>

        <a href=#>Element 1.2</a>

      </li>

      <li data-icon=delete>

        <a href=#>Element 1.3</a>

      </li>

    </ol>

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "<ol id=list2 data-role=listview data-inset=true>";

html +=   "<li data-role=list-divider>Dynamic list</li>";

html +=   "<li data-icon=delete>";

html +=      "<a href=#>Element 2.1</a>";

html +=   "</li>";

html +=   "<li data-icon=delete>";

html +=      "<a href=#>Element 2.2</a>";

html +=   "</li>";

html +=   "<li data-icon=delete>";

html +=      "<a href=#>Element 2.3</a>";

html +=   "</li>";

html += "</ol>";


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


</script>

The first list is created in the traditional way in the HTML (static list), while the second is created dynamically by JavaScript, and inserted into the DOM tree using the append (html) instruction (dynamic list).




List with images

We take the same example as above, but including images in the list items. The static list contains two list items, while the dynamic list will contain only one.

Dynamic creation of a list with images

<!DOCTYPE html> 

<html> 

<head> 

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

  <meta name="apple-mobile-web-app-capable" content="yes" />

  <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>

    <ul id=list1 data-role=listview data-inset=true>

      <li data-role=list-divider>Static list</li>

      <li>

        <img src=images/html.jpg />

        <h1> HTML & CSS</h1>

        <p> Eric Sarrion</p>

      </li>

      <li>

        <img src="images/j2ee.jpg" />

        <h3>J2EE</h3>

        <p> Eric Sarrion</p>

      </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "<ul id=list2 data-role=listview data-inset=true>";

html +=   "<li data-role=list-divider>Dynamic list</li>";

html +=   "<li>";

html +=     "<img src=images/jquery.jpg />";

html +=     "<h3>JQuery & jQuery UI</h3>";

html +=     "<p> Eric Sarrion</p>";

html +=   "</li>";

html += "</ul>";


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


</script>




Turning a HTML element into a jQuery Mobile list

The goal here is to turn a classic <ul> or <ol> HTML list into a list that is displayed according to the conventions of jQuery Mobile. We know that it is enough that the <ul> or <ol> element has the data-role="listview" attribute. We study how to incorporate this attribute to the corresponding <ul> or <ol> element.

For this we assume that the list is stripped of all its classic attributes (data-role, data-icon, etc.).. The HTML code of the list is as follows:

A HTML list with no jQuery Mobile conventions

<!DOCTYPE html> 

<html> 

<head> 

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

  <meta name="apple-mobile-web-app-capable" content="yes" />

  <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>

    <ol id=list1>

      <li>Element 1.1</li>

      <li>Element 1.2</li>

      <li>Element 1.3</li>

    </ol>

  </div>

</div>


</body>

</html>


<script>


</script>

This list is included in a typical jQuery Mobile window, but as the <ol> element does not have the data-role="listview" attribute, the list appears in a rudimentary way.




It would be necessary to indicate in the JavaScript that the list should be displayed according to the jQuery Mobile conventions. For this, we use the listview () method, associated with the listview jQuery Mobile component, to transform the underlying HTML into a jQuery Mobile list.

Add this statement in our JavaScript code:

Call to the listview () method on the list

<!DOCTYPE html> 

<html> 

<head> 

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

  <meta name="apple-mobile-web-app-capable" content="yes" />

  <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>

    <ol id=list1>

      <li>Element 1.1</li>

      <li>Element 1.2</li>

      <li>Element 1.3</li>

    </ol>

  </div>

</div>


</body>

</html>


<script>


$("#list1").listview ();


</script>




You will see that the result is not as expected! Indeed, we ask to create a jQuery Mobile component (list), while the window containing it is itself being transformed at this time there! So we must wait the window has finished being created to perform this transformation.

Instead, insert the listview () instruction in the treatment of the pagecreate event on the window, the event indicating that the window has finished being created.

Call to the listview () method in the treatment of the pagecreate event

<!DOCTYPE html> 

<html> 

<head> 

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

  <meta name="apple-mobile-web-app-capable" content="yes" />

  <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>

    <ol id=list1>

      <li>Element 1.1</li>

      <li>Element 1.2</li>

      <li>Element 1.3</li>

    </ol>

  </div>

</div>


</body>

</html>


<script>


$("#home").bind ("pagecreate", function ()

{

  $("#list1").listview ();

});


</script>




The list appears as expected now ...

Retrieve a list by Ajax

We display a window where we want to integrate a list recovered by Ajax. The list is inserted as the last element of the window contents.

Retrieve a list by Ajax and insert into the window

<!DOCTYPE html> 

<html> 

<head> 

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

  <meta name="apple-mobile-web-app-capable" content="yes" />

  <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);

    $("#list").listview ();

  }

}); 


</script>

The action.php file contains the server program that returns the list to insert in the window:

action.php file

<?
$html = "";
$html .= "<ol id=list data-inset=true>";
$html .=   "<li data-role=list-divider>List retrieved by Ajax</li>";
$html .=   "<li data-icon=delete>";
$html .=      "<a href=#>Element 1</a>";
$html .=   "</li>";
$html .=   "<li data-icon=delete>";
$html .=      "<a href=#>Element 2</a>";
$html .=   "</li>";
$html .=   "<li data-icon=delete>";
$html .=      "<a href=#>Element 3</a>";
$html .=   "</li>";
$html .= "</ol>";
  
echo utf8_encode ($html);
?>

Note the $("#list").listview () statement in JavaScript code. It transforms the HTML code received from the server in a list displayed according to the conventions of jQuery Mobile. If it is not present, the display of the list no longer takes place under these conventions, but as a simple HTML list.

The display according to the jQuery Mobile conventions is:




Note that you can also use the create event to create the list in the window. Simply replace the line:

Create the list using listview ()

$("#list").listview ();

by the following:

Create the list using the create event

$("#home").trigger ("create");

Note that if you use the create event, the list retrieved from the server must include the data-role="listview" attribute, otherwise jQuery Mobile will not know which HTML elements it should transform into a jQuery Mobile list. The indication of this attribute is unnecessary when using the listview () method, since it is the element that called the method that will be transformed into a jQuery Mobile list (here the #list1 element).

Insert an item in a list

jQuery methods are used to insert an item in a list. For example the append (html) method to insert the elements defined by the HTML code, at the end of the <ul> or <ol> element using the method.

Here we define a <ol> list currently empty. A button Insert at the end of the list allows to insert an element <li> at the end of the <ol> list.

Insert an item at the end of the list

<!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>

    <ol id=list1 data-role=listview>

    </ol>

    <br />

    <a data-role=button id=add>Insert at the end of the list</a>

  </div>

</div>


</body>

</html>


<script>


$("#add").bind ("click", function (event)

{

  $("#list1").append ("<li>Inserted element</li>");

});


</script>

The window is as follows after several successive insertions:




The <li> elements have been inserted, but their appearance is not the list items displayed according to the jQuery Mobile conventions. The reason is that jQuery Mobile does not refresh the list after each insertion. It can be told to do by calling the listview ("refresh") method used on the <ul> or <ol> element.

Add this statement after the insertion of the list item. JavaScript code executed when inserting the <li> element becomes:

Refresh the list after each element insertion

$("#add").bind ("click", function (event)

{

  $("#list1").append ("<li>Inserted element</li>");

  $("#list1").listview ("refresh");

});




Delete an item from a list

Deleting a list item is done using the remove () method of jQuery. For example, adding the ability to remove an item inserted by clicking on it.

Allow the removal of an element inserted

<!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>

    <ol id=list1 data-role=listview>

    </ol>

    <br />

    <a data-role=button id=add>Insert at the end of the list</a>

  </div>

</div>


</body>

</html>


<script>


$("#add").bind ("click", function (event)

{

  $("#list1").append ("<li>Inserted element</li>");

  $("#list1").listview ("refresh");

});


$("li").live ("vclick", function (event)

{

  $(this).remove ();

});


</script>

The live () method adds an event handler for <li> items, including items that are not present in the DOM tree when the method is called.

Note the use of the click event on the link, and the use of the vclick event on <li> element, as recommended by jQuery Mobile.

Manage events on lists

The main event that we can manage on lists is the click event that jQuery Mobile associates with the vclick virtual event.

This event is managed using the bind () method of jQuery used on a list item. For example, display a list for which we display the contents of the list item that is clicked.

Taking into account the click of a list item

<!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>  

    <ul data-role=listview data-inset=true>

      <li> Element 1.1 </li>

      <li> Element 1.2 </li>

      <li> Element 1.3 </li>

      <li> Element 1.4 </li>

      <li> Element 1.5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


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

{

  alert (this.innerHTML);

});


</script>

Customize lists

Use the previous program with a list of five elements, and display the HTML generated by jQuery Mobile in the Firefox browser associated with Firebug.




Each list item has the ui-li CSS class, while the <ul> encompassing list has the ui-listview CSS class. Define these two classes in our HTML code to produce a new display of the list.

Change the style of list items

<!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-li { 

      color : #0099FF;

      font-size : 20px;

      font-style : italic;

    }

    .ui-listview {

      padding : 10px;

      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>  

    <ul data-role=listview data-inset=true>

      <li> Element 1.1 </li>

      <li> Element 1.2 </li>

      <li> Element 1.3 </li>

      <li> Element 1.4 </li>

      <li> Element 1.5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


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

{

  alert (this.innerHTML);

});


</script>




Each element of the list has grown in height (to accommodate the new size of the font), while the list is surrounded by a black border, due to the definition of the ui-listview CSS class.

Examples of list manipulation

Create lists containing sub-lists

We want to manage the click of a list item to display in a list included in this element. The sub-list appears below the item clicked. The next click on the item hides the list again. This is the principle of accordion menus.

Manage sub-lists in a list

<!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>  

    <ul data-role=listview data-inset=true>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 1 </a></li>

      <li> Element 1.1 </li>

      <li> Element 1.2 </li>

      <li> Element 1.3 </li>

      <li> Element 1.4 </li>

      <li> Element 1.5 </li>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 2 </a></li>

      <li> Element 2.1 </li>

      <li> Element 2.2 </li>

      <li> Element 2.3 </li>

      <li> Element 2.4 </li>

      <li> Element 2.5 </li>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 3 </a></li>

      <li> Element 3.1 </li>

      <li> Element 3.2 </li>

      <li> Element 3.3 </li>

      <li> Element 3.4 </li>

      <li> Element 3.5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li:not(:jqmData(role=list-divider))").hide ();


$("li:jqmData(role=list-divider)").bind ("vclick", function (event)

{

  $(this).nextUntil ("li:jqmData(role=list-divider)").toggle ();

});


</script>

At launch, only the elements corresponding to the titles of the lists are visible, while the elements in the sub-lists are hidden. The titles of the lists correspond to the <li> elements with data-role="list-divider" attribute. This is achieved by the first statement in the script:

Hide list items that are not titles of list

$("li:not(:jqmData(role=list-divider))").hide ();

The bind () statement is used to observe the following click events on the title elements. The treatment is to hide / show alternatively list items that follow (until the next title).

At the beginning of the program all lists are closed:




Click on the first element (List 1):




The sub-list contained in this list, opened and displayed below the item.

Change the icon for a list item

Improve the previous program. When a list is open, we want to change the icon displayed in the title of the list by displaying such a up arrow (instead of a down arrow). When the list is closed again, it will reset the previous icon.

To achieve this, we must look in more detail, how is designed the HTML code created by jQuery Mobile to display a list item containing the icon.




We see that the icon is represented by a <span> element with the ui-icon class, and also the ui-icon-arrow-d class representing the drawing of the icon. Just change the last class to ui-icon-arrow-u to display an icon representing a up arrow.

Note that changing the data-icon attribute has no effect on the display of the icon in the list item. This attribute is only used when creating the list item, and its subsequent modification does not work.

Change the icon displayed in a list item when clicking it

<!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>  

    <ul data-role=listview data-inset=true>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 1 </a></li>

      <li> Element 1.1 </li>

      <li> Element 1.2 </li>

      <li> Element 1.3 </li>

      <li> Element 1.4 </li>

      <li> Element 1.5 </li>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 2 </a></li>

      <li> Element 2.1 </li>

      <li> Element 2.2 </li>

      <li> Element 2.3 </li>

      <li> Element 2.4 </li>

      <li> Element 2.5 </li>

      <li data-role=list-divider data-icon=arrow-d>

        <a href=#> List 3 </a></li>

      <li> Element 3.1 </li>

      <li> Element 3.2 </li>

      <li> Element 3.3 </li>

      <li> Element 3.4 </li>

      <li> Element 3.5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li:not(:jqmData(role=list-divider))").hide ();


$("li:jqmData(role=list-divider)").bind ("vclick", function (event)

{

  $(this).nextUntil ("li:jqmData(role=list-divider)").toggle ();

  var $span = $(this).find ("span.ui-icon");

  if ($span.hasClass ("ui-icon-arrow-d")) 

  {

    $span.removeClass ("ui-icon-arrow-d");

    $span.addClass ("ui-icon-arrow-u");

  }

  else 

  {

    $span.removeClass ("ui-icon-arrow-u");

    $span.addClass ("ui-icon-arrow-d");

  }

});


</script>

For example, when List 3 is open:




Managing the click on the icon of an item in a static list

Now we want to handle the click on the icon in a static list item, ie a list created directly in HTML. For example, we insert five items in a list, each element has its own delete icon to delete the item when the icon is clicked.

We need to manage the click on the icon of each <li> item. As seen above, this icon is represented by a <span> element with ui-icon CSS class. We write for example:

Manage click on the delete icon of list items

<!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>  

    <ul data-role=listview data-inset=true>

      <li data-icon=delete> <a href=#>Element 1 </a></li>

      <li data-icon=delete> <a href=#>Element 2 </a></li>

      <li data-icon=delete> <a href=#>Element 3 </a></li>

      <li data-icon=delete> <a href=#>Element 4 </a></li>

      <li data-icon=delete> <a href=#>Element 5 </a></li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li .ui-icon").bind ("click", function (event)

{

  $(this).closest ("li").remove ();

});


</script>




However, clicking on delete icon is not taken into account. The reason is very simple: the "li. ui-icon" selector did not match any HTML element as the HTML of the list has not been transformed into a jQuery Mobile code. This means that we must wait until the list has finalized its creation to make the call to bind () method.

So we write:

Wait until the list was created to manage the click on the delete icon

<!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>  

    <ul data-role=listview data-inset=true>

      <li data-icon=delete> <a href=#>Element 1 </a></li>

      <li data-icon=delete> <a href=#>Element 2 </a></li>

      <li data-icon=delete> <a href=#>Element 3 </a></li>

      <li data-icon=delete> <a href=#>Element 4 </a></li>

      <li data-icon=delete> <a href=#>Element 5 </a></li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("ul").bind ("listviewcreate", function (event)

{

  $("li .ui-icon").bind ("click", function (event)

  {

    $(this).closest ("li").remove ();

  }).css ("z-index", 10);

});


</script>

Manage the click on the icon of an item in a dynamically created list (solution 1)

We now assume that the list is not already present in the HTML but is created dynamically by JavaScript.

We could then consider a second solution (with respect to the solution of the previous example). Rather than waiting for the creation of the list (listviewcreate event), use the jQuery Mobile listview () method to transform the original HTML code to display according to the jQuery Mobile conventions.

The program becomes:

Direct use of the listview () method

<!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 += "<ul data-inset=true>";

html += "<li data-icon=delete> <a href=#>Element 1 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 2 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 3 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 4 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 5 </a></li>";

html += "</ul>";

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


$("#home").bind ("pagecreate", function ()

{

  $("ul").listview ();

  

  $("li .ui-icon").bind ("click", function (event)

  {

    $(this).closest ("li").remove ();

  });

});


</script>

The listview () method call converts the dynamically created list into a jQuery Mobile list. However this method can be called only if the window is already created, hence the use of the pagecreate event on the window.

Manage the click on the icon of an item in a dynamically created list (solution 2)

Let us take the same example as before. We indicate the data-role="listview" attribute in the HTML of the list, which prevents us from calling the listview () method to create the component.

However, observation of the click event on the icon in the list item can only be done when the list is created, hence the use of the listviewcreate event on the list.

Using the listviewcreate event

<!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 += "<ul data-role=listview data-inset=true>";

html += "<li data-icon=delete> <a href=#>Element 1 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 2 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 3 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 4 </a></li>";

html += "<li data-icon=delete> <a href=#>Element 5 </a></li>";

html += "</ul>";

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


$("ul").bind ("listviewcreate", function ()

{

  $("li .ui-icon").bind ("click", function (event)

  {

    $(this).closest ("li").remove ();

  });

});


</script>

If you do not use the listviewcreate event, the list is created but clicking on the icon is not taken into account.

Allow deletion of a list item by clicking and holding

Rather than displaying a delete icon in each list item, you could also use the long click on the item. The corresponding event is taphold (we studied in the previous chapter).

Delete an item from the list after a long click on the item

<!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>  

    <ul data-role=listview data-inset=true>

      <li> Element 1 </li>

      <li> Element 2 </li>

      <li> Element 3 </li>

      <li> Element 4 </li>

      <li> Element 5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li").bind ("taphold", function (event)

{

  $(this).remove ();

});


</script>

Allow deletion of a list item with a swipe

We now want to delete the items in the list by performing a swipe to the right movement on these. It is therefore sliding your finger on the element from left to right, and the element disappears.

The event is managed by swiperight. Here is the program:

Manage swiperight events on the elements to remove

<!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>  

    <ul data-role=listview data-inset=true>

      <li> Element 1 </li>

      <li> Element 2 </li>

      <li> Element 3 </li>

      <li> Element 4 </li>

      <li> Element 5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li").bind ("swiperight", function (event)

{

  $(this).remove ();

});


</script>

Keep the rounded edges appearance to the list

In the previous examples, you may have noticed that deleting a list item at the top or bottom of the list broke the rounded side edges of the list. These edges are rounded with the data-inset attribute set to "true" on the <ul>.

When you delete an item, we need to indicate to jQuery Mobile to round again first and last item in the list, if one of them would have been deleted and replaced by another element . To do this, jQuery Mobile uses the ui-corner-top CSS class associated with the first list item, as well as the ui-corner-bottom CSS class associated with the last list item.

Using the previous example and add the CSS classes in the first and last element of the list when deleting element:

Keep the rounded edges appearance to the list

<!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>  

    <ul data-role=listview data-inset=true>

      <li> Element 1 </li>

      <li> Element 2 </li>

      <li> Element 3 </li>

      <li> Element 4 </li>

      <li> Element 5 </li>

    </ul>

  </div>

</div>


</body>

</html>


<script>


$("li").bind ("swiperight", function (event)

{

  $(this).remove ();

  $("ul").find ("li:first").addClass ("ui-corner-top");

  $("ul").find ("li:last").addClass ("ui-corner-bottom");

});


</script>

Here is the list display by having removed the first and last element of this:




The rounded edges are now preserved.

Another solution is possible, even easier. Let jQuery Mobile self-manage CSS classes for displaying rounded edges, using the listview ("refresh") method. For this, we replace the two lines:

Management of rounded edges on the lists (with CSS classes)

$("ul").find ("li:first").addClass ("ui-corner-top");

$("ul").find ("li:last").addClass ("ui-corner-bottom");

For this:

Management of rounded edges on the lists (with the listview ("refresh") method)

$("ul").listview ("refresh");


Copyright Eric Sarrion (ericsarrion@gmail.com)