Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout.js - foreach binding - test if last element

I am using the following template:

<div class="datatypeOptions" data-bind="if: $data.datatypeTemplate().allowOptions">     <h3>Allowed responses</h3>      <p data-bind="if: $data.datatypeTemplate().datatypeOptions().length == 0">There are no responses for this question, yet. <a href="#" data-bind="click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}">Add one</a>     <ul data-bind="foreach: $data.datatypeTemplate().datatypeOptions()">         <li>             <a href="#" data-bind="text: name, click: $root.selectedDatatypeOption, visible: $data !== $root.selectedDatatypeOption()"></a>             <input data-bind="value: name, visibleAndSelect: $data === $root.selectedDatatypeOption(), event: { blur: $root.clearDatatypeOption }, executeOnEnter: { callback: function(){ $root.addDatatypeOption($parent.datatypeTemplate()); } }" />             //I want to show this a tag only if $data is the last element in the array. Problem here ===>  <a href="#" data-bind="if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}"><img src='/static/img/icons/custom-task-wizard/black/plus_12x12.png' title='Add option'></a>         </li>     </ul> </div> 

I get this error in the console:

Uncaught Error: Unable to parse bindings. Message: TypeError: Object [object Object] has no method 'datatypeTemplate'; Bindings value: if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());} 

Is my only option to add a function to my viewmodel that returns true/false if the passed element is last in the array?

like image 307
Jonathan Avatar asked Feb 07 '12 23:02

Jonathan


1 Answers

I've simplified the problem, but this jsFiddle demonstrates a possible solution.

"if" binding:

<div data-bind="if: ($index() === ($parent.data().length - 1))">I'm the last element</div> 

Containerless "if" binding:

<!-- ko if: ($index() === ($parent.data().length - 1)) --> <div>I'm the last element again</div> <!-- /ko --> 

You can use $index within a foreach binding to get the index of the currently bound item. Use that to compare against the original collection of the parent.

See HERE for more information regarding binding contexts.

like image 159
Brett Postin Avatar answered Sep 18 '22 12:09

Brett Postin