0

I have a JSON witch looks something like this

{
      "English": "en",
      "Francais": "fr",
      "German": "gm"
  }

Now I need to print this data in HTML structure witch looks like this

<ul id="links">
            <li class="home">
                <a href="#"></a>
            </li>
            <li class="languages">
                <a href="#">EN</a>   ------ > FIRST LANGUAGE FROM JSON
                <ul class="available">  ----> OTHERS
                    <li><a href="#">DE</a></li>
                    <li><a href="#">IT</a></li>
                    <li><a href="#">FR</a></li>
                </ul>
            </li>
        </ul>

In javascript I know how to get data and print all data in the same structure but how to do it in structure shown in example ?

in Javascript I'm getting data with

$.getJSON('js/languages.json', function(data) {
    console.log(data);
  /* $.each(data, function(key, val) {
    console.log(val);
  });*/
});
chipatama
  • 153
  • 3
  • 16
  • Loop through it using the `$.each` function like you were doing before. – Tim Withers Sep 15 '13 at 16:10
  • 2
    Perhaps looking for templating https://github.com/janl/mustache.js/ – mplungjan Sep 15 '13 at 16:11
  • 1
    One problem you'll run into is that there's no defined ordering for properties in an object. Your format will not allow you to reliably find the "first" language unless you write your own JSON parser. – Pointy Sep 15 '13 at 16:12
  • yes but how to seperate first object from the others ? – chipatama Sep 15 '13 at 16:13
  • @Pointy Pray tell which browser/js implementation will NOT give English first if $.each or for..in is used? – mplungjan Sep 15 '13 at 16:14
  • @mplungjan relying on behavior that is explicitly not defined is a bad idea. It may work today; will it work after the next round of V8 or Spidermonkey optimizations? – Pointy Sep 15 '13 at 16:15
  • There's no point relying on undefined behavior when there's a perfectly simple way to create a data structure with well-defined ordering. – Pointy Sep 15 '13 at 16:16
  • ... and furthermore, in this case, you're relying on *two layers* of undefined behavior. You really have no guarantee that the JSON parser will add properties to a resulting object in the order that it sees them in the source code. – Pointy Sep 15 '13 at 16:18
  • One word: Pragmatism. I can fix the broken script when it breaks. Of course you need to do it the best way possible. Sometimes you do not have the luxury to. I daily have to fight with a JSON result from an API I do not have control over. Too bad, I have learned to live with it – mplungjan Sep 15 '13 at 16:21
  • 1
    [Here is a good SO question on the topic.](http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop) – Pointy Sep 15 '13 at 16:21
  • You are correct. If possible re-create the object as `"languages":[{"English":"en"},{}{}]` – mplungjan Sep 15 '13 at 16:23
  • @Pointy interesting that all the failing examples in the interesting post you gave all have numeric keys. I never had a numeric key ever. – mplungjan Sep 15 '13 at 16:34

4 Answers4

2

Use jQuery template to bind the Html. Some Sample

sudhansu63
  • 6,025
  • 4
  • 39
  • 52
0

Something like that:

var getBlock = function(skipLang) {
    var str = '\
        <ul id="links">\
            <li class="home">\
                <a href="#"></a>\
            </li>\
            <li class="languages">\
                <a href="#">' + data[skipLang] + '</a>\
                <ul class="available">\
    ';
    for(var lang in data) {
        if(lang != skipLang) {
            str += '<li><a href="#">' + lang + '</a></li>';
        }
    }
    str += '</ul></li></ul>';
    return str;
}

var html = '';
for(var lang in data) {
   html += getBlock(lang);
}
Krasimir
  • 13,306
  • 3
  • 40
  • 55
0

Although using templating engine is an option for simpler code, for this case you can directly run a for loop and assign HTML within javascript code easily.

HTML part is going to be something like this

<ul id="links">
    <li class="home">
        <a href="#">home</a>
    </li>
    <li class="languages">
        <ul class="available">
        </ul>
    </li>
</ul>

And JS part is like this:

var data = {
      "English": "en",
      "Francais": "fr",
      "German": "gm"
  };

var $liLanguages = $('li.languages');
var $ulAvailable = $('ul.available');

var selectedLanguage = '';

for(var index in data) {
    if(selectedLanguage == '') {
        selectedLanguage = data[index];
        $liLanguages.prepend("<a href='#'>" + data[index].toUpperCase() + "</a>");
    }
    else {
        $ulAvailable.append("<li><a href='#'>" + data[index].toUpperCase() + "</a></li>");
    }
}

Here is the jsfiddle related.

Hope this helps.

CM.
  • 1,007
  • 1
  • 7
  • 19
0

Here is a bit that will get you two new objects, one for the first object property/value and another for the remaining. Still not clear what is done with it once you have it, but let me know if it helps:

// This can be replaced with existing data or updated to var langs = data;
var langs = {"English": "en", "Francais": "fr","German": "gm" };


// jQuery map only works on objects after 1.6, heads up 
var lang_keys = $.map( langs, function( value, key ) {
  return key;
});

// Now that you have an array of the keys, you can use plain-ol shift()    

var primary_lang_key = lang_keys.shift();

// create and populate an object just for your first language:
var primary_lang = {};
primary_lang[primary_lang_key] = langs[primary_lang_key];

// Thanks to shift, we know that populating this object with lang_keys will
// only have remaining items:
var other_langs = {};
$.map( lang_keys, function( lang_key ) {
  other_langs[lang_key]  = langs[lang_key];
});

console.log(other_langs);
Anthony
  • 36,459
  • 25
  • 97
  • 163