Multilevel list menu with JSON and jQuery Mobile

I try to reach following structure

a list of (distinct!) categories

Read More
  • Category 1
  • Category 2
  • Category n

And each Category links to the posts within the Category. And the posts link to the content

  • Post 1 Cat 1 –> Content Post 1 Cat 1
  • Post 2 Cat 2 –> Content Post 2 Cat 1

Question: I don’t know how to create the distinct list of categories which leads to the posts. Any solutions?

This is my JSON example (this is from the json api plugin in wordpress)

{"status": "ok",
"count": 10,
"count_total": 20,
"pages": 2,
"posts": [
    {
        "id": 86,
        "type": "post",
        "slug": "inaktiviert",
        "url": "http://localhost/wordpress/?p=86",
        "status": "publish",
        "title": "Post 1 Cat1",
        "content": "his is content for Post1 Cat 1.",
        "date": "2014-03-04 15:09:51",
        "modified": "2014-03-04 15:09:51",
        "categories": [
            {
                "id": 1,
                "title": "Category 1",
                "description": "",
                "parent": 0,
                "post_count": 4
            }
        ],
    },
    {
        "id": 84,
        "type": "post",
        "slug": "kann-nicht-aktualisiert-werden",
        "url": "http://localhost/wordpress/?p=84",
        "status": "publish",
        "title": "Post 2 Cat1",
        "content": "<p>This is content for Post2 Cat 1.</p>n",
        "date": "2014-03-04 15:09:25",
        "modified": "2014-03-04 15:09:25",
        "categories": [
            {
                "id": 1,
                "title": "Category 1",
                "description": "",
                "parent": 0,
                "post_count": 4
            }
        ],
    },
        {
            "id": 74,
            "type": "post",
            "slug": "dieses-symbol-zeigt-an",
            "url": "http://localhost/wordpress/?p=74",
            "status": "publish",
            "title": "Post 1 Cat2",
            "content": "This is Content for Post1 Cat 2",
            "date": "2014-03-04 15:06:47",
            "modified": "2014-03-04 15:06:47",
            "categories": [
                {
                    "id": 2,
                    "title": "Category 2",
                    "description": "",
                    "parent": 0,
                    "post_count": 3
                }
            ],
        }
    ]}

And this my JS

$(document).on("pagecreate", "#page1", function(){
    var liste = $('#liste');

    var AllListItems = '';
    var AllDynamicPages = '';
    $.each(daten.posts, function(index1, data) {
        var postid = data.id;
        var postTitle = data.title;
        var postContent = data.content;

        for (var i = 0; i< data.categories.length; i++) {

            var catid = data.categories[i].id;     
            var catTitle = data.categories[i].title;            
            AllListItems += '<li><a href="#page' + postid + '">' + postTitle + '</a></li>';    
            AllDynamicPages += '<div data-role="page" data-add-back-btn="true" id="page' + postid + '"><div data-role="header"><h1>' + postTitle + '</h1></div><div data-role="content">' + postContent + '</div></div>'
        }        
    });

    liste.empty().append(AllListItems).listview("refresh");
    $("body").append(AllDynamicPages);
});

DEMO

Related posts

Leave a Reply

1 comment

  1. I would approach it this way: Instead of a list, create a collapsible set where each child collapsible is a category, and each category collapsible contains a list of posts.

    So the top level HTML markup would be a collapsible set:

    <div id="thelist" data-role="collapsibleset" data-theme="a" data-content-theme="a">       
    </div>  
    

    Then the code:

    var liste = $('#thelist');
    var AllDynamicPages = '';
    $.each(daten.posts, function(index1, data) {
        var postid = data.id;
        var postTitle = data.title;
        var postContent = data.content;        
        for (var i = 0; i< data.categories.length; i++) {
            var catid = data.categories[i].id;     
            var catTitle = data.categories[i].title;            
            //see if we already have this category, if not create new collapsible
            var $cat = $("#cat" + catid);
            if ($cat.length == 0){
                $cat = $('<div id="cat' + catid + '" data-role="collapsible"><h3>' + catTitle + '</h3><ul data-role="listview"></ul></div>');   
                liste.append($cat);
            }
    
            //create post link in category collapsible list
            var postlink = '<li><a href="#page' + postid + '">' + postTitle + '</a></li>';
            $cat.find("ul").append(postlink);
    
            AllDynamicPages += '<div data-role="page" data-add-back-btn="true" id="page' + postid + '"><div data-role="header"><h1>' + postTitle + '</h1></div><div data-role="content">' + postContent + '</div></div>'
        }        
    });        
    liste.enhanceWithin();
    $("body").append(AllDynamicPages);
    

    It is the same iteration as you had before, but now for each category, we check if there is already a collapsible for that category. If there is not we create one and add it to the set. Then we create a link for the post and add it the list widget within the category collapsible.

    Finally we call .enhanceWithin() to apply jQM styling.

    The dynamic pages part stays exactly the same.