1

In Handlebars.js, how can I use @index to subscript into another parallel array in the object I am passing to a template?

For example, say I have an object set up like the following:

var table = {
    cols : [
        { name: "Column 1" },
        { name: "Column 2" },
        { name: "Column 3", highlighted: true }
    ],
    rows : [
        {
            label: "Row 1",
            data: [
                { val: 5 },
                { val: 3 },
                { val: 8 }
            ]
        },
        {
            label: "Row 2",
            data: [
                { val: 8 },
                { val: 4 },
                { val: 0 }
            ]
        }
    ]
};

I need to be able to use the @index from an {{#each rows}}{{#each data}} loop to check if the column is highlighted to apply a style to cells in the column, but Handlebars.js does not appear to allow using @index in a subscript operator.

E.g.

{{@index}} <!-- Index of current rows.data is 2. -->

{{#if ../../cols.[@index].highlighted }}
    <!-- Never Executed -->
{{/if}}

{{#if ../../cols.[2].highlighted }}
    <!-- Executes -->
{{/if}}

Is this not supported? Am I doing something wrong? How can I get this to work easily?

I posted an example on jsfiddle.net.

5
  • FYI {{#if ../../[email protected] }} does not work either, causing the parse error Expecting 'ID', got 'DATA'. Commented Jun 3, 2013 at 20:28
  • Why don't you do the data wrangling in JavaScript instead? Handlebars templates are meant to be very light on the logic after all. Commented Jun 3, 2013 at 20:34
  • So you're suggesting something like adding a highlighted: true to each column cell that should be highlighted? I guess I can do that, but it seemed like unnecessary duplication of data. Commented Jun 3, 2013 at 20:43
  • I'm suggesting that you pre-digest your data for the template. You don't have to store the pre-digested data, just set it up, hand it to the compiled template function, and throw it away. You could also unroll cols to make it easier to access the currently hilighted column in Handlebars. Commented Jun 3, 2013 at 21:04
  • @muistooshort I don't understand what you're saying, but this is leading to the much-frowned-upon discussion. Should I create a different question asking specifically about highlighting a column in a Handlebars template? Commented Jun 3, 2013 at 22:21

1 Answer 1

1

@key and @index behave specially, not as variables. So, even when you can use myvar.[123] you cannot use myvar.[@key] even though @key is 123. (At least, as of Handlebars 1.3.0)

There are two solutions. The first is to write your own handlebars helper, that takes both arrays/objects. The second is to restructure your data, i.e. merge your two parallel arrays.

As an example of the latter approach, if you have these two arrays:

var X={
  cat:"meow",
  sheep:"baaa"
  };
var Y={
  cat:3,
  sheep:5
  };

Then you could do:

var Z={};
for(var ix in X){
  Z[ix]={X:X[ix],Y:Y[ix]};
  }

And then pass Z to your handlebars template:

myTemplate({animals:Z});

which might look like this:

{{#each animals}}
  The {{@key}} goes {{this.X}}; we have {{this.Y}} of them.
{{/each}}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.