Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ Ember is moving towards a paradigm that encourages the use of actions. With this
<td valign="top"><code>remove-item</code> / <code>remove-value</code></td>
<td valign="top">Sent when the user deselects an item in multiple mode. The removed object is sent as a parameter. `remove-value` is identical, but gets the removed value passed in.</td>
</tr>
<tr>
<td valign="top"><code>reorder-items</code></td>
<td valign="top">Sent when the user reorders a list of items in multiple mode. The reordered list of items is sent as a parameter</td>
</tr>
<tr>
<td valign="top"><code>on-focus</code></td>
<td valign="top">Sent when the control gains focus.</td>
Expand Down
49 changes: 49 additions & 0 deletions addon/components/ember-selectize.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default Ember.Component.extend({
create: allowCreate ? Ember.run.bind(this, '_create') : false,
onItemAdd: Ember.run.bind(this, '_onItemAdd'),
onItemRemove: Ember.run.bind(this, '_onItemRemove'),
onChange: Ember.run.bind(this, '_onChange'),
onType: Ember.run.bind(this, '_onType'),
render: this.get('renderOptions'),
placeholder: this.get('placeholder'),
Expand Down Expand Up @@ -232,6 +233,38 @@ export default Ember.Component.extend({
});
},

/**
* Event callback triggered when an item has changed (eg. reorder with drag_drop plugin)
* Here we need to update our selection property (if single selection) or array (if multiple selection)
* We also send an action
*/
_onChange : function(args) {
var selection = get(this,'selection');
var vp = get(this,'_valuePath');

if(!args || !selection || !isArray(selection) || args.length !== selection.length) {
return;
}

if( selection.every(function(obj, idx) {
if( get(obj, vp) === args[idx] ) { return true; }
}) === true ) { return; }

var reorderedSelection = Ember.A([]);

args.forEach(function(value) {
var obj = selection.find(function(item) {
return (get(item, vp) + '') === value;
}, this);

if (obj) {
reorderedSelection.addObject(obj);
}
});

this._changeSelection(reorderedSelection);
},

/**
* Event callback triggered when an item is added (when something is selected)
* Here we need to update our selection property (if single selection) or array (if multiple selection)
Expand Down Expand Up @@ -319,6 +352,22 @@ export default Ember.Component.extend({
});
},

_changeSelection(selection) {
// TODO This is just to get the tests green, will be cleaned up before merge!
if (!this.get('changeDidTriggerAlready')) {
this.set('changeDidTriggerAlready', true);
this.set('selection', selection);
} else {
this.set('changeDidTriggerAlready', false);
return;
}

// allow the observers and computed properties to run first
Ember.run.schedule('actions', this, function() {
this.sendAction('reorder-items', selection);
});
},

/**
* Ember observer triggered before the selection property is changed
* We need to unbind any array observers if we're in multiple selection
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/components/ember-selectize-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,21 @@ test('updating a selection updates selectize value', function(assert) {
assert.equal(component.get('selection'), content.objectAt(1));
});

test('reorder a selection updates selectize value', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 2', 'item 3']));
component.set('multiple', true);
});
this.render();
Ember.run(function() {
component._selectize.setValue(['item 3', 'item 2']);
});
assert.deepEqual(component.get('value'), ['item 3', 'item 2']);
assert.deepEqual(component.get('selection'), ['item 3', 'item 2']);
});

test('replacing a multiple selection updates selectize selection', function(assert) {
var component = this.subject();
Ember.run(function() {
Expand Down Expand Up @@ -563,6 +578,32 @@ test('it sends remove-value action when an item is deselected in multiple mode',
});
});

test('it sends reorder-items action when an item is reordered in multiple mode', function(assert) {
assert.expect(1);

var component = this.subject();

var targetObject = {
externalAction: function(obj) {
assert.deepEqual(obj, ['item 3', 'item 1', 'item 2'], 'externalAction was called with proper argument');
}
};

Ember.run(function() {
component.set('multiple', true);
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 1', 'item 2', 'item 3']));
component.set('reorder-items', 'externalAction');
component.set('targetObject', targetObject);
});

this.render();

Ember.run(function() {
component._onChange(['item 3', 'item 1', 'item 2']);
});
});

test('if label is falsy, don\'t add item', function(assert) {
var component = this.subject();
Ember.run(function() {
Expand Down