Skip to content

Instantly share code, notes, and snippets.

@sandstrom
Last active December 16, 2015 12:49
Show Gist options
  • Save sandstrom/5437244 to your computer and use it in GitHub Desktop.
Save sandstrom/5437244 to your computer and use it in GitHub Desktop.
Faster Em.Select
// A static select where options aren't child-views but plain option tags.
// This implementation is currently much faster than Em.Select on large collections.
(function() {
// shortcuts
var set = Em.set, get = Em.get;
Em.FastSelect = Em.Select.extend({
staticLabels: true,
render: function(buffer) {
var escape = Handlebars.Utils.escapeExpression;
var labelKey = get(this, "optionLabelPath").replace("content.", "");
var valueKey = get(this, "optionValuePath").replace("content.", "");
if (!labelKey)
throw "Must specify a labelKey";
if (!valueKey)
throw "Must specify a valueKey";
if (!get(this, "staticLabels")) {
this._super(buffer);
return;
}
var output = "";
if (get(this, "prompt")) {
output += "<option>" + escape(get(this, "prompt")) + "</option>";
}
output += get(this, "content").map(function(obj) {
var value = escape( get(obj, valueKey) );
var text = escape( get(obj, labelKey) );
return "<option value='" + value + "'>" + text + "</option>";
}).join("");
buffer.push(output);
},
_changeSingle: function () {
var content = get(this, 'content');
if (!content) {
return;
}
var selectedIndex = this.$()[0].selectedIndex;
var prompt = get(this, 'prompt');
if (prompt && selectedIndex === 0) {
set(this, 'selection', null);
return;
}
if (prompt) {
selectedIndex -= 1;
}
var selectedItem = content.objectAt(selectedIndex);
if (selectedItem) {
var valuePath = get(this, 'optionValuePath').replace('content.', '');
selectedItem = get(selectedItem, valuePath);
}
set(this, 'selection', selectedItem);
},
// Find the index of selection in content based on optionValuePath
_indexOf: function (content, selection) {
var optionValuePath = get(this, 'optionValuePath');
var valuePath = optionValuePath.replace('content.', '');
function getValue(item) {
return get(item, valuePath);
}
return Em.EnumerableUtils.indexOf(Em.EnumerableUtils.map(content, getValue), selection);
},
_selectionDidChangeSingle: function () {
var el = this.$()[0];
if (!el) {
return;
}
var content = get(this, 'content');
var selection = get(this, 'selection');
var selectionIndex = this._indexOf(content, selection);
if (get(this, 'prompt')) {
selectionIndex += 1;
}
el.selectedIndex = selectionIndex;
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment