Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically adding collapsible set and nested list in jQuery mobile

I am adding a listview inside a collapsible dynamically. And inside that list I am trying to add a nested list. When I am clicking the <li> node, pageinit event is getting fired instead of click event. The click event is getting fired when we click the same li second time.

jsFiddle - http://jsfiddle.net/5zJC5/

HTML:

<body>
<div data-role="page">
    <div data-role="collapsible-set" data-theme="b" data-content-theme="d" id="mainColl"></div>         
</div>
</body>

jQuery:

$(document).ready(function () {
      var ul=$("#mainColl");
      var collapsible= $('<div data-role="collapsible">');
      collapsible.append('<h2>Collapsible</h2>');

      var list = $('<ul data-role="listview" data-divider-theme="b">');
      list.append('<li data-role="list-divider">List</li>');

      for(var j =0;j<4;j++) {
        list.append("<li>Item</li>");
      }
      collapsible.append(list);
      ul.append(collapsible);
      ul.trigger('create');
});

$("#mainColl").on("click","li",function() {
      var list = $("<ul>");
      for(var i=0;i<4;i++) {
        list.append("<li>test</li>");
      }
      $(this).append(list);
      //$(this).trigger('create');
      $(this).parent().listview('refresh');
});
like image 608
dejavu Avatar asked May 31 '13 21:05

dejavu


1 Answers

You have to use list.append("<li><a href=\"#\">Item</a></li>"); instead of list.append("<li>Item</li>");.

Updated jSFiddle here.

In addition, note that is is not recommended to use the document ready handler in combination with jQuery Mobile. I would suggest to add an id on the jQM page and use an event handler of the 'pagebeforeshow' event.

$(document).on('pagebeforeshow', '#page-id', function(){...mycode...});

You can find a jsFiddle which includes the suggested fix here

At last I would like to suggest you to avoid creating dynamic parts like that. You will realize that after some time your code will become messy and hard to read.

My proposal is to use Undescore.js as a template engine and make your code reusable and clean.

EDITED to add handler on nested list items:

<!DOCTYPE html>
<html>

    <head>
        <title>jQuery Mobile Nested List</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
        <script>
            $(document).on('pagebeforeshow', '#home-page', function () 
             {
                var collapsibleSet=$("#mainColl");
                var collapsible= $('<div data-role="collapsible"></div>');
                collapsible.append('<h2>Collapsible</h2>');

                var list = $('<ul data-role="listview" data-divider-theme="b"></ul>');
                list.append('<li data-role="list-divider">List</li>');

                for(var j =0;j<4;j++)
                {
                    list.append("<li><a href=\"#\">Item</a></li>");
                }
                collapsible.append(list);
                collapsibleSet.append(collapsible);
                collapsibleSet.trigger('create');
             });


            $(document).on("click","#mainColl li",function()
            {
                var list = $("<ul id=\"second-list\"></ul>");
                for(var i=0; i<4; i++)
                {
                    var listItem = $("<li id=\"list-" + i + "\"><a href=\"#\">Test</a></li>").on('click', function(){alert(this.id)})
                    list.append(listItem);
                }
                $(this).append(list);
                $(this).parent().listview('refresh');
            });
        </script>
    </head>

    <body>
        <div data-role="page" id="home-page">
               <div data-role="content">
                   <div data-role="collapsible-set" data-theme="b" data-content-theme="d" id="mainColl">
                   </div>
               </div>
        </div>
     </body>

</html>

I hope this helps.

like image 133
Apostolos Emmanouilidis Avatar answered Oct 08 '22 11:10

Apostolos Emmanouilidis