Skip to content

Instantly share code, notes, and snippets.

@abuiles
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abuiles/3353197ac9e1881bc5af to your computer and use it in GitHub Desktop.
Save abuiles/3353197ac9e1881bc5af to your computer and use it in GitHub Desktop.
Custom select-component using ember-cli-auto-complete
import AutoComplete from 'ember-cli-auto-complete/components/auto-complete';
import Ember from 'ember';
import lodash from "npm:lodash";
export default AutoComplete.extend({
noMesssagePlaceHolderText: Ember.computed.alias('emptyResult'),
valueProperty: Ember.computed.alias('optionLabelPath'),
placeHolderText: Ember.computed.alias('prompt'),
prompt: '',
selectedValue: '',
inputClass: '',
inputClazz: Ember.computed(function() {
return `typeahead text-input ${this.get('inputClass')}`;
}),
focusOut: function() {
this._super.apply(this, arguments);
if (Ember.isEmpty(this.get('selectedValue'))) {
this.set('selection', null);
}
return true;
},
init: function() {
this._super();
this.setSelectedValue();
},
setSelectedValue: function() {
let optionLabelPath = this.get('optionLabelPath');
let value = this.get('selection');
if (value) {
if (optionLabelPath) {
value = Ember.get(value, optionLabelPath) || '';
}
this.set('selectedValue', value);
}
},
suggestions: Ember.computed('inputVal', 'content.[]', function() {
let inputVal = this.get('inputVal') || '';
let optionLabelPath = this.get('optionLabelPath');
let filter = new RegExp('^'+inputVal.toLowerCase(), 'i');
let results = this.get('content').filter(function(item) {
let value = item;
if (optionLabelPath) {
value = Ember.get(item, optionLabelPath);
}
return filter.test(value);
});
results = results.map(function(item) {
return Ember.ObjectProxy.create({
content: item,
highlight: false
});
});
if (this.get('optionGroupPath')) {
results = this.groupedsuggestions(results);
}
return results;
}),
groupedsuggestions: function(suggestions) {
let grouped = lodash.groupBy(suggestions, (suggestion) => {
return Ember.get(suggestion, this.get('optionGroupPath'));
});
grouped = Ember.keys(grouped).map(function(group) {
return Ember.ObjectProxy.create({
content: group,
name: group,
suggestions: grouped[group]
});
});
return grouped.sortBy('content');
},
optionsToMatch: Ember.computed('content.[]', function() {
let caseInsensitiveOptions = [];
this.get('content').forEach(function(item) {
let value = this.getValue(item);
caseInsensitiveOptions.push(value);
caseInsensitiveOptions.push(value.toLowerCase());
}, this);
return caseInsensitiveOptions;
}),
getValue: function(object) {
let value = object;
if (this.get('optionLabelPath')) {
value = Ember.get(object, this.get('optionLabelPath'));
}
return value;
},
actions: {
selectItem: function(item) {
let optionLabelPath = this.get('optionLabelPath');
this.set('selectedFromList', true);
let value = Ember.get(item, 'content');
let selectedValue = Ember.get(item, 'content');
// Text that will be bound to input
if (this.get('optionLabelPath')) {
selectedValue = Ember.get(item, optionLabelPath);
}
this.set('selectedValue', selectedValue);
// Actual value bound to selection
if (this.get('optionValuePath')) {
value = Ember.get(item, this.get('optionValuePath'));
}
this.set('selection', value);
this.sendAction('selectItem', value);
}
}
});
<div class="typeahead-wrap">
{{input class=inputClazz
value=selectedValue
placeholder=placeHolderText
autocomplete="off"
spellcheck="false"
}}
<span class="tt-dropdown-menu" style={{visibility}}>
<div class="tt-dataset-states">
<span class="tt-suggestions">
{{#if optionGroupPath}}
{{#each suggestions as |group|}}
<div class="dropdown-header">
{{group.name}}
</div>
{{#each group.suggestions as |result|}}
<div class="tt-suggestion {{if result.highlight
"tt-cursor"}}" {{action "selectItem" result bubbles=false}}>
{{select-item-component item=result optionLabelPath=valueProperty}}
</div>
{{/each}}
{{else}}
<div class="message">
<p>{{noMesssagePlaceHolderText}}</p>
</div>
{{/each}}
{{else}}
{{#each suggestions as |result|}}
<div class="tt-suggestion {{if result.highlight
"tt-cursor"}}" {{action "selectItem" result bubbles=false}}>
{{select-item-component item=result optionLabelPath=valueProperty}}
</div>
{{else}}
<div class="message">
<p>{{noMesssagePlaceHolderText}}</p>
</div>
{{/each}}
{{/if}}
</span>
</div>
</span>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment