BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.

Home Page:http://www.jsviews.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to access iterator in range

kiebor opened this issue · comments

I have a data structure like this:

{
someNumber: 5,
someStuff:[ ... ... ]
}

I can create a row of items conditionally based on the value of someNumber by repeating the below snippet 5x (and manually setting i from 1 to 5)

     {{ if someNumber >= i }}
           <span>true</span>
     {{ else }}
           <span>false</span>
      {{ /if }}

Ideally I would like to use range for simplicity. Something like:

{{ range start=1 end=5 }}
     {{ if someNumber >= [iterator] }}
           <span>true</span>
     {{ else }}
           <span>false</span>
      {{ /if }}
{{ /range }}

I can't find the in loop variable to expose the iterator/index of the current iteration. I have tried #index and #data but both resolve as null/undefined in the loop. I also noticed that someNumber is less than 0 when using the construct.

Can you point me at some documentation that explains how to do this (jsviews.com isn't quite clear nor does it explain validating in loop), or offer some advice.

Thanks.

You can access the iterator from within nested blocks using #getIndex(). See also http://jsviews.com/#views@itemview (and the rest of that documentation topic).

In the next update you will be able to do

{{for someStuff start=1 end=5}}
   <span>true</span>
{{/for}}

but it looks as if you need something like:

{{for someStuff}}
  {{if #getIndex() < 6}}
    <span>true</span>
  {else}}
    <span>false</span>
  {{/if}}
{{/for}}

Thanks, Boris. Below works for me to get the iterator in the range/for loop

{{range start=1 end=5}}
  {{if #getIndex() < 4 }}
    <span>true</span>
  {{/if}}
{{/range}}

but what I wanted was to be able to validate the iterator against someNumber. In this loop my data value someNumber equates to null, or is inaccessible.

Ideally I was hoping to achieve something like:

for (i = 1; i < 6; i++) {
  if(someNumber > i){
     //true
  }
}

I'll add some context. I'm using JsRender/JsViews to template a set of product cards:

<p>&nbsp;</p>
{{for Cards}}
  <div class="col-xxs-3">
    <div class="card carbon-panel product-card">
      <header class="badge-container hidden-xs hidden-sm">
        <span class="badge-slot"></span>
        <span class="badge-slot"></span>
        <span class="badge-slot"></span>
        <span class="badge-slot"></span>
        <span class="badge-slot"></span>
        <span class="pull-right">
          <i title="favourite?" class="glyphicon glyphicon-heart-empty favo-badge glyphicon-light"></i>
        </span>
      </header>

      <div class="img-container with-grow">
        <img src="{{>PhotoURL}}" class="img-responsive" />
      </div>

      <div class="product-rating">
        {{range start=1 end=5}}
          {{if ~Average >= #getIndex()}}
            <span class="glyphicon glyphicon-star rated"></span>
          {{else}}
            <span class="glyphicon glyphicon-star unrated"></span>
          {{/if}}
        {{/range}}
      </div>

      <div class="card-main-text">
        <p class="detail-block-text">
          <strong class="text-concat">
            <a class="carbon-text" href="https://github.com/BorisMoore/jsrender/issues/%7B%7B>ProductNameUrl%7D%7D/%7B%7B>GUID%7D%7D" target="_blank" rel="nofollow">{{>ProductName}}</a>
          </strong>          
        </p>
        
        <p class="catalogue-reference">
          <span class="fontsize">
            {{>CatRef}}
          </span>
        </p>
        {{if StockLevel > 0}}
            <span><span class="available-stock">&bull;&nbsp;</span>{{>StockLevel}}</span>
        {{else}}
            <span><span class="nostock-text">&bull;&nbsp;</span>Out Of Stock</span>
        {{/if}}
        <p class="price-block">
            <span>
                <span class="availableprice-text">{{>MRRP.Symbol}}{{>MRRP.Value / Precision}}</span>
            </span>
        </p>
        
      </div>

    <footer class="card-footer">
      {{if StockLevel > 0}}
      <a class="btn btn-basket-add block-tall with-ripple">
        <i class="icon-add_shopping_cart"></i>
      </a>
      {{else}}
      <a class="btn btn-basket-add block-tall is-disabled" disabled>
        <i class="icon-add_shopping_cart"></i>
      </a>
      {{/if}}
    </footer>

      </div>  
    
  </div>
{{/for}}

For the better part, this renders nicely, but there is only 1 place that I stumble:

  • the product-rating block | the value of Average is unknown (despite being in the json)

Not sure why you put ~Average - (with a ~). Is it in the data or is it a helper? You don't show your data or JSON so I have no idea where Average is defined. I suppose it is higher up in the data object graph, in which case you need to read this: Accessing parent data

Maybe:

{{range start=1 end=5 ~Average=Average}}
  {{if ~Average >= #getIndex()}}
    <span class="glyphicon glyphicon-star rated"></span>
  {{else}}
    <span class="glyphicon glyphicon-star unrated"></span>
  {{/if}}
{{/range}}