Simplest way to get current item index within jQuery template
Asked Answered
S

8

28

I am passing an array of objects to jQuery template (official jquery-tmpl plugin):

$("#itemTmpl").tmpl(items).appendTo("body");

<script id="itemTmpl" type="text/x-jquery-tmpl">
    <div class="item">Name: ${name}, Index: ${???}</div>
</script>

What is the easiest way to display item index in the template? Preferably without using separated external functions, without changing passed object structure, and without changing template structure (converting to {{each}}). Is there any built-in variable perhaps that stores current array index?

UPDATE I created a ticket proposing to expose array index to template item but it was closed as invalid...

Sipper answered 9/10, 2010 at 1:31 Comment(0)
F
28

Well, it's not a true separate external function, but you can slap a function onto the options object you can pass to tmpl. I've done the following and it works fine:

$("#templateToRender").tmpl(jsonData,
  {
    dataArrayIndex: function (item) {
      return $.inArray(item, jsonData);
    }
  });

In the template, you can access the function from the $item object:

<script id="templateToRender" type="text/x-jquery-tmpl">
  <li>
    Info # ${$item.dataArrayIndex($item.data)}
  </li>
</script>

Alternatively, instead of passing $item.data into the function, the context of the function is the tmplItem object of the template (same as $item.data). So you could write dataArrayIndex as parameterless and access the data via this.data.

Feeler answered 2/11, 2010 at 20:54 Comment(0)
B
3

Here's a cheezy hack:

${ _index === undefined && _index = 0, '' }
<strong>Item ${ index }:</strong> ${ content }
${ _index++, '' }
Behn answered 23/3, 2011 at 5:17 Comment(0)
G
2

Just ran into this issue myself. very frustrating! The index of the template item for example was always available in jTemplates. Shouldnt have been difficult to add that in i would think...

Weird thing is that in Firebug I can see the key property for each $item: item key

But when trying to access it from a function i call from within the template:

<img class="profImage" src="${getProfileImage($item)}" />

In the function if I check the item key property either like 'item.key' or '$(item).key' I get 'undefined' and not the actual value...

Grobe answered 1/3, 2011 at 18:44 Comment(1)
key is set after template rendering completes. you can see "real" item content in the template with: ${console.log(JSON.stringify($item))}Column
S
2

Create a function in javascript to increment a counter. Then create a function in javascript to get the current position of the counter. These functions can be called by using {{ functionName() }}. In the past I have had use the function in an html element, for example, in a hidden input tag. This will enable you to use an index.

Spermic answered 16/10, 2012 at 3:13 Comment(0)
C
1

https://github.com/clarkbox/jquery-tmpl/commit/993e6fa128c5991723316032abe12ff0cbbb9805

Patch you jquery.template and then you can do like this:

<script id=”tabTemplate” type=”text/x-jquery-tmpl”>
    <div id=“tab-${$index + 1}”>
        <!— render tab contents here… —>
    </div>
</script>
Cairistiona answered 12/1, 2012 at 17:42 Comment(0)
I
1

Easy way to do this using jQuery 1.6.4 or newer at least.

First as you'd expect iterate through a collection

{{each myListofStuff}}
Index: ${$this.index}
{{/each}}

Will do the trick!

Inefficiency answered 14/3, 2012 at 21:38 Comment(0)
O
0

There is no easily accessible index. There is a key that is appended to each item.

<div class="item" jQuery1287500528620="1">

This key is accessible through jquery. So you can do something like

$(".item").each(function () {
                var theTemplate = $(this).tmplItem();
                $(this).append("Index: " + theTemplate.key);
            });

But that's not what you wanted. I don't think what you wanted is possible. The ${$item} object is supposed to represent the tmplItem() method, but it doesn't provide a value for ${$item.key}. Using ${$.tmplItem().key} produces 0 for each row.

So the answer to your question is..... No.

Oppilate answered 19/10, 2010 at 15:10 Comment(0)
W
0

simply define one global variable for counting:

var n = 0;
function outputTemplate(){
    return $( "#template_item" ).tmpl(datas,
          {
              getEvenOrOdd: function(){
                  return ++n % 2 == 0 ? 'odd' : 'even';
              }
          } 
    );
}
Willed answered 17/2, 2013 at 23:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.