Skip to content

Instantly share code, notes, and snippets.

@hinok
Created January 18, 2015 14:36
Show Gist options
  • Save hinok/a3d413004df3e1ff4bb0 to your computer and use it in GitHub Desktop.
Save hinok/a3d413004df3e1ff4bb0 to your computer and use it in GitHub Desktop.
Improved {{#each}} for Ember 1.9 / Handlebars 2.0.0
/**
A replacement for #each that provides an index value (and other helpful values) for each iteration.
Unless using `foo in bar` format, the item at each iteration will be accessible via the `item` variable.
Simple Example
--------------
```
{{#eachIndexed bar in foo}}
{{index}} - {{bar}}
{{/#eachIndexed}}
```
Helpful iteration values
------------------------
* index: The current iteration index (zero indexed)
* index_1: The current iteration index (one indexed)
* first: True if this is the first item in the list
* last: True if this is the last item in the list
* even: True if it's an even iteration (0, 2, 4, 6)
* odd: True if it's an odd iteration (1, 3, 5)
*/
Ember.Handlebars.registerHelper('eachIndexed', function eachHelper(path, options) {
var $ = Ember.$;
var keywordName = 'item';
var fn;
if (arguments.length === 4) {
// Process arguments
// #earchIndexed foo in bar
Ember.assert('If you pass more than one argument to the eachIndexed helper, it must be in the form #eachIndexed foo in bar', arguments[1] === 'in');
Ember.assert(arguments[0] +' is a reserved word in #eachIndexed', $.inArray(arguments[0], ['index', 'index+1', 'even', 'odd']));
keywordName = arguments[0];
options = arguments[3];
path = arguments[2];
options.hash.keyword = keywordName;
if (path === '') {
path = 'this';
}
} else if (arguments.length === 1) {
// Process arguments
// #earchIndexed bar
options = path;
path = 'this';
}
// Wrap the callback function in our own that sets the index value
fn = options.fn;
function eachFn() {
var keywords = arguments[1].data.view._keywords;
var view = arguments[1].data.view;
var index = view.contentIndex;
var list = view._parentView.get('content') || [];
var len = list.length;
// Set indexes
keywords.index = index;
keywords.index_1 = index + 1;
keywords.first = (index === 0);
keywords.last = (index + 1 === len);
keywords.even = (index % 2 === 0);
keywords.odd = !keywords.even;
arguments[1].data.keywords = keywords;
return fn.apply(this, arguments);
}
options.fn = eachFn;
// Render
options.hash.dataSourceBinding = path;
if (options.data.insideGroup && !options.hash.groupedRows && !options.hash.itemViewClass) {
new Ember.Handlebars.GroupedEach(this, path, options).render();
} else {
return Ember.Handlebars.helpers.collection.call(this, Ember.Handlebars.EachView, options);
}
});
@hinok
Copy link
Author

hinok commented Jan 18, 2015

@mize
Copy link

mize commented Jan 18, 2015

I think the default ember-cli setup tries to register bound helpers if your helper filename has a dash. http://www.ember-cli.com/#resolving-handlebars-helpers

Try renaming the file without dash and just import it to your app.js directly, like this simple version:

// app/helpers/fooEach.js
import Ember from 'ember';

export default Ember.Handlebars.registerHelper('fooEach', function (options) {
console.log(options);
return 'woot';
});

// app/app.js
import fooEach from './helpers/fooEach';

@kannanmaran
Copy link

getting error in Handlebars V 3.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment