Skip to content

Commit

Permalink
Merge pull request #779 from cibernox/is-equal
Browse files Browse the repository at this point in the history
[FEATURE] If options implement the `isEqual` method, EPS will use it
  • Loading branch information
cibernox authored Jan 12, 2017
2 parents 092eb63 + 47609e2 commit 6d163c1
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 129 deletions.
11 changes: 10 additions & 1 deletion addon/components/power-select-multiple.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import Ember from 'ember';
import Component from 'ember-component';
import computed from 'ember-computed';
import layout from '../templates/components/power-select-multiple';
import fallbackIfUndefined from '../utils/computed-fallback-if-undefined';

const { isEqual } = Ember;

export default Component.extend({
layout,
// Config
Expand Down Expand Up @@ -81,7 +84,13 @@ export default Component.extend({

buildSelection(option, select) {
let newSelection = (select.selected || []).slice(0);
let idx = newSelection.indexOf(option);
let idx = -1;
for (let i = 0; i < newSelection.length; i++) {
if (isEqual(newSelection[i], option)) {
idx = i;
break;
}
}
if (idx > -1) {
newSelection.splice(idx, 1);
} else {
Expand Down
5 changes: 4 additions & 1 deletion addon/components/power-select.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Ember from 'ember';
import Component from 'ember-component';
import layout from '../templates/components/power-select';
import fallbackIfUndefined from '../utils/computed-fallback-if-undefined';
Expand All @@ -19,6 +20,8 @@ import {
} from '../utils/group-utils';
import { task, timeout } from 'ember-concurrency';

const { isEqual } = Ember;

// Copied from Ember. It shouldn't be necessary in Ember 2.5+
const assign = Object.assign || function EmberAssign(original, ...args) {
for (let i = 0; i < args.length; i++) {
Expand Down Expand Up @@ -248,7 +251,7 @@ export default Component.extend({

select(selected /* , e */) {
let publicAPI = this.get('publicAPI');
if (publicAPI.selected !== selected) {
if (!isEqual(publicAPI.selected, selected)) {
this.get('onchange')(selected, publicAPI);
}
},
Expand Down
17 changes: 16 additions & 1 deletion addon/helpers/ember-power-select-is-selected.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
import Ember from 'ember';
import { helper } from 'ember-helper';
import { isEmberArray } from 'ember-array/utils';

const { isEqual } = Ember;

// TODO: Make it private or scoped to the component
export function emberPowerSelectIsSelected([option, selected]/* , hash*/) {
return isEmberArray(selected) ? selected.indexOf(option) > -1 : option === selected;
if (selected === undefined || selected === null) {
return false;
}
if (isEmberArray(selected)) {
for (let i = 0; i < selected.length; i++) {
if (isEqual(selected[i], option)) {
return true;
}
}
return false;
} else {
return isEqual(option, selected);
}
}

export default helper(emberPowerSelectIsSelected);
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"ember-disable-prototype-extensions": "^1.1.0",
"ember-export-application-global": "^1.0.5",
"ember-fastboot-test-helpers": "0.1.1",
"ember-href-to": "1.7.0",
"ember-href-to": "1.11.0",
"ember-load-initializers": "^0.6.0",
"ember-pagefront": "0.10.10",
"ember-resolver": "^2.0.3",
Expand All @@ -79,7 +79,7 @@
"ember-cli-htmlbars": "^1.1.1",
"ember-concurrency": "^0.7.15",
"ember-text-measurer": "^0.3.3",
"ember-truth-helpers": "^1.2.0"
"ember-truth-helpers": "^1.3.0"
},
"ember-addon": {
"configPath": "tests/dummy/config",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
countries
} from '../constants';

const { RSVP } = Ember;
const { RSVP, Object: eObject, get } = Ember;

moduleForComponent('power-select', 'Integration | Component | Ember Power Select (General behavior)', {
integration: true
Expand Down Expand Up @@ -1115,3 +1115,39 @@ test('the item that is highlighted by default can be customized passing a functi
assert.equal($('.ember-power-select-dropdown').length, 1, 'Dropdown is rendered');
assert.equal($('.ember-power-select-option[aria-current=true]').text().trim(), 'five', 'the given element is highlighted instead of the first, as usual');
});

test('If the options of a single select implement `isEqual`, that option is used to determine whether or not two items are the same', function(assert) {
let User = eObject.extend({
isEqual(other) {
return get(this, 'name') === get(other, 'name');
}
});

this.search = (term) => {
return names.filter((n) => n.indexOf(term) > -1).map((name) => User.create({ name }));
};

let onChangeInvocationsCount = 0;
this.onChance = (selected) => {
onChangeInvocationsCount++;
this.set('selected', selected);
};

this.render(hbs`
{{#power-select
selected=selected
onchange=onChance
search=search as |user|}}
{{user.name}}
{{/power-select}}
`);

clickTrigger();
typeInSearch('M');
nativeMouseUp('.ember-power-select-option:eq(1)');
clickTrigger();
typeInSearch('i');
assert.equal($('.ember-power-select-option:eq(0)').attr('aria-selected'), 'true', 'The item in the list is marked as selected');
nativeMouseUp('.ember-power-select-option:eq(0)'); // select the same user again
assert.equal(onChangeInvocationsCount, 1);
});
32 changes: 30 additions & 2 deletions tests/integration/components/power-select/multiple-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import $ from 'jquery';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { typeInSearch, triggerKeydown, clickTrigger, nativeMouseDown, nativeMouseUp } from '../../../helpers/ember-power-select';
import { numbers, countries } from '../constants';
import { numbers, names, countries } from '../constants';

const { RSVP } = Ember;
const { RSVP, Object: eObject, get } = Ember;

moduleForComponent('ember-power-select', 'Integration | Component | Ember Power Select (Multiple)', {
integration: true
Expand Down Expand Up @@ -781,4 +781,32 @@ test('Multiple selects honor the `defaultHighlighted` option', function(assert)

clickTrigger();
assert.equal($('.ember-power-select-option[aria-current=true]').text().trim(), 'four', 'the given defaultHighlighted element is highlighted instead of the first, as usual');
});

test('If the options of a multiple select implement `isEqual`, that option is used to determine whether or not two items are the same', function(assert) {
let User = eObject.extend({
isEqual(other) {
return get(this, 'name') === get(other, 'name');
}
});

this.search = (term) => {
return names.filter((n) => n.indexOf(term) > -1).map((name) => User.create({ name }));
};

this.render(hbs`
{{#power-select-multiple
selected=selected
onchange=(action (mut selected))
search=search as |user|}}
{{user.name}}
{{/power-select-multiple}}
`);

typeInSearch('M');
nativeMouseUp('.ember-power-select-option:eq(1)');
typeInSearch('Mi');
assert.equal($('.ember-power-select-option:eq(0)').attr('aria-selected'), 'true', 'The item in the list is marked as selected');
nativeMouseUp('.ember-power-select-option:eq(0)'); // select the same user again should remove it
assert.equal(this.$('.ember-power-select-multiple-option').length, 0);
});
Loading

0 comments on commit 6d163c1

Please sign in to comment.