Search code examples
javascriptjsonhtmljquery-mobiledynamic-arrays

Sort JSON objects and append to html using javascript/JQM


First time using JSON and total beginner at javascript / JQM

I am trying to read a JSON file, sort it by country name ie title and display in a listview. I am not sure if I am overcomplicating things by trying to use a two dimensional array to sort. Any help, greatly appreciated.

js

<script type="text/javascript">
    function ajax_get_json(){
    var hr = new XMLHttpRequest();

    hr.open("GET", "european_countries.json", true);
    hr.setRequestHeader("Content-type", "application/json", true);
    hr.onreadystatechange = function() {
        if(hr.readyState == 4 && hr.status == 200) {
            var data = JSON.parse (hr.responseText);
            var results = document.getElementById("results");
            var country, flag, population, avg_growth, date;
            for (var obj in data){
                var countries = [[]];
                var i = 0;
                title = data[obj].title;
                flag = data[obj].flag;
                population = data[obj].population;
                avg_growth = data[obj].avg_annual_growth;
                date = data[obj].date;
                countries[i][0] = title;
                countries[i][1] = flag;
                countries[i][2] = population;
                countries[i][3] = avg_growth;
                countries[i][4] = date;
                i++;
            }
            countries.sort();
            var listHTML = "";
            for (i=0; i < countries.length; i++) {
              for (var details in countries[i]) {
                listHTML += '<li><a href="#' + countries[i][0] + '</a></li>';
              }
            }
            $("#countryList").empty().append(listHTML).listview("refresh");
        }
    }
    hr.send(null);
    // display message while data loading
    // could include animated gif or image here
    results.innerHTML = "requesting...";
    }
</script>

html

<body>
    <div id="results"></div>

    <div data-role="page" id="home">
      <div data-role="header">
        <h2>European Countries</h2>
      </div>
      <div role="main">
        <div id="test"></div>
        <ul id="countryList" data-role="listview" data-autodividers="true" data-filter="true" data-inset="true">
          <li></li>
        </ul>
      </div>
      <div data-role="footer">
      </div>
    </div><!-- page -->

    <script type="text/javascript">
        ajax_get_json();
    </script>
</body>

json

{
"c1":{
"title":"Russia",
"flag":"flags/flags/Russia.png", 
"population":"144,031,000",
"avg_annual_growth":"250,000",
"date":"January 1, 2015"
},
"c2":{
"title":"Germany",
"flag":"flags/Germany.png", 
"population":"81,172,000",
"avg_annual_growth":"271,000",
"date":"December 31, 2013"
},
"c3":{
"title":"Turkey",
"flag":"flags/flags/Turkey.png", 
"population":"78,214,000",
"avg_annual_growth":"1,035,000",
"date":"December 31, 2014"
},  ...etc

Solution

  • You can convert your JSON object to a single array of country objects

    [
      {
        title:"Russia",
        flag:"flags/flags/Russia.png", 
        population:"144,031,000",
        avg_annual_growth:"250,000",
        date:"January 1, 2015"
      },...
    ]
    

    Create a sort comparison function that compares the title field of objects in the array (Found HERE):

    function compare(a,b) {
      if (a.title < b.title)
         return -1;
      if (a.title > b.title)
        return 1;
      return 0;
    }
    

    So your code would end up something like this:

    var countries = [];
    for (var obj in data){        
        countries.push({
            title: data[obj].title,  
            flag: data[obj].flag,
            population: data[obj].population,
            avg_annual_growth: data[obj].avg_annual_growth,
            date: data[obj].date
        });
    }
    countries.sort(compare);
    
    var listHTML = "";
    for (var i=0; i < countries.length; i++) {
        listHTML += '<li><a href="#' + countries[i].title + '">'  + countries[i].title  + '</a></li>';
    }
    
    $("#countryList").empty().append(listHTML).listview("refresh");
    

    Working DEMO