Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index of an array element in Mustache.js

This is what I'd like to do in Mustache.js but not seeing how with the documentation.

var view = {items:['Mercury','Venus','Earth','Mars']};
var template = "<ul> {{#items}}<li>{{i}} - {{.}}</li>{{/items}} </ul>";
var html = Mustache.to_html(template,view);

Desired output:

<ul>
  <li>0 - Mercury</li>
  <li>1 - Venus</li>
  <li>2 - Earth</li>
  <li>3 - Mars</li>
</ul>
like image 970
Dane Avatar asked Dec 19 '11 20:12

Dane


2 Answers

Looking for a fast clean solution?

Simply add an index function

var data = {
    items: [{
            name: Aliasghar
            , grade: 19
        }, {
            name: Afagh
            , grade: 20
    }]
    , index: function() {
        return ++window['INDEX']||(window['INDEX']=0);
    }
}

and your template could be like this:

{{#items}}
    {{index}} -- {{name}} is {{grade}}
{{/items}}

How it works

We add a index: function(){} to data and we use it as a normal function in template. This function adds a key to the window object which is available globally; then increases it one by one.

To use with multiple lists

Please note that if you are using multiple templates one after another you need to either reset window['INDEX'] or change it's key to something else like window['YEKI_DIGE']. Another way of doing this is by adding a resetIndex function. Here is the way:

var data = {
    items: [{
            name: Aliasghar
            , grade: 19
        }, {
            name: Afagh
            , grade: 20
    }]
    , index: function() {
        return ++window['INDEX']||(window['INDEX']=0);
    }
    , resetIndex: function() {
        window['INDEX']=null;
        return;
    }
}

and your template could be like this:

{{#items}}
    {{index}} -- {{name}} is {{grade}}
{{/items}}
{{resetIndex}}

Inspired by this answer: https://stackoverflow.com/a/10208239/257479 from dave on In Mustache, How to get the index of the current Section

like image 60
Alexar Avatar answered Sep 17 '22 12:09

Alexar


An alternative solution, without fooling around with Mustache.js

Instead of fooling around with mustache you might as well use a <ol></ol> instead of <ul></ul>, that will prefix each item with index+1.

If you'd like you can use css to change the starting number to 0, and it will render exactly as you want. You can even change the dot after the number, to something such as " - ", and problem is solved.

<ol>
  <li>Mercury</li>
  <li>Venus</li>
  <li>Earth</li>
  <li>Mars</li>
</ol>

the above will render as:

1. Mercury
2. Venus
3. Earth
4. Mars

the Mustache.js way to do it

The proper method if you'd like to do it in mustache is to convert your array of strings to an array of objects, where index and string value is present.

// I wrote this from the back of my head, it's untested and not guaranteed
// to work without modifications, though the theory behind it is valid.


var array     = ["123","stackoverflow","abc"];
var obj_array = [];

for (idx in array)
   obj_array.push ({'index': idx, 'str': array[idx]});

var view     = {items: obj_array};
var template = "<ul>{{#items}}<li>{{index}} - {{str}}</li>{{/items}}</ul>";
var html     = Mustache.to_html(template,view);
like image 37
Filip Roséen - refp Avatar answered Sep 19 '22 12:09

Filip Roséen - refp