Skip to content

Instantly share code, notes, and snippets.

@brendanoh
Last active March 5, 2017 21:07
Show Gist options
  • Save brendanoh/79921203529ab9a57cb3 to your computer and use it in GitHub Desktop.
Save brendanoh/79921203529ab9a57cb3 to your computer and use it in GitHub Desktop.
This is a GIST to explain a workaround to the lack of case insensitive or partial text search on the server side via the Emberfire add-on.
import Ember from 'ember';
import computed from 'ember-new-computed';
const inject = Ember.inject;
const alias = computed.alias;
const sort = computed.sort;
export default Ember.Controller.extend({
sessionManager: inject.service(),
person: alias('sessionManager.person'),
personSkills: alias('sessionManager.personSkillsByName'),
// This is the field bound to the autocomplete control and used for client side filtering
filterText: "",
// This is the field bound to query and used for server side filtering
filterTextThree: "",
// This will update 'filterTextThree' when 'filterText' changes and is 3 char long
filterTextObserver: function() {
if(this.get('filterText.length') === 3) {
this.set('filterTextThree', this.get('filterText').toUpperCase());
}
}.observes('filterText'),
// This will pull down models based on the 'nameStartsWith' field matching against 'filterTextThree' and updates when 'filterTextThree' changes
skillsByStartsWith: Ember.computed('filterTextThree', function() {
if(this.get('filterTextThree')) {
return this.store.query('skill', {
orderBy: 'nameStartsWith',
equalTo: this.get('filterTextThree')
});
}
}),
// This does the client side filtering of models returned by the 'skillsByStartsWith' property
// This however uses the full string of 'filterText' regardless of how many chars it is
skills: Ember.computed('skillsByStartsWith', 'skillsByStartsWith.[]', 'filterText', function() {
const promise = this.get('skillsByStartsWith');
if(promise && promise.get('length') && this.get('filterText')) {
const filterText = this.get('filterText').toUpperCase();
return promise.filter(function(skill) {
return skill.get('name').toUpperCase().indexOf(filterText) !== -1;
});
}
}),
actions: {
updateSearch(str) {
this.set('filterText', str);
}
},
newSkill: null,
addSkillObserver: function() {
const self = this;
const person = this.get('person');
const newSkill = this.get('newSkill');
if(newSkill) {
this.store.createRecord('person-skill', {
person: person,
skill: newSkill
}).save().then(function() {
self.set('newSkill', null);
self.set('filterText', null);
});
}
}.observes('newSkill')
});
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
nameStartsWith: DS.attr('string')
});
{
"1290": {
"name" : "Business economics (teaching)",
"nameStartsWith" : "BUS"
},
"1291": {
"name" : "Business Efficiency",
"nameStartsWith" : "BUS"
}
}
{{#paper-content class="md-padding"}}
<h2>
Please add any skills you have.
</h2>
<p class="cvr-black">
We use this information to highlight your skills and to better match you with opportunities.
<br><br>
This information is completely optional and no one will see this unless you want them to.
</p>
{{paper-autocomplete floating=true
minLength=3
placeholder="Enter the first 3 letters of the skill..."
source=skills
lookupKey="name"
model=newSkill
cache-miss="updateSearch"}}
{{#paper-list}}
{{#each personSkills as |personSkill|}}
<div class="progress-bars">
{{#link-to 'skills.edit' personSkill tagName='div' class="progress progress-1"}}
<div class="{{if personSkill.months 'progress-bar' 'no-progress-bar'}}" style="width: {{personSkill.ratingNumber}}%">
<span>
<div class="title">{{personSkill.skill.name}}</div>
<div class="percent">{{personSkill.ratingText}}</div>
</span>
</div>
{{/link-to}}
</div>
{{/each}}
{{/paper-list}}
{{/paper-content}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment