Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data down actions up. #66

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 27 additions & 50 deletions addon/components/ember-selectize.js
Expand Up @@ -28,11 +28,11 @@ export default Ember.Component.extend({
optionValuePath: 'content',
optionLabelPath: 'content',

/**
* selection is one way.
*/
selection: null,
value: computed('selection', {get: function() {
var valuePath = this.get('_valuePath');
return valuePath ? this.get('selection.' + valuePath) : this.get('selection');
}, set: function(key, value){ return value; }}),
_selection: Ember.computed.oneWay('selection'),

/**
* The array of the default plugins to load into selectize
Expand Down Expand Up @@ -154,15 +154,13 @@ export default Ember.Component.extend({
//Save the created selectize instance
this._selectize = this.$()[0].selectize;

//Some changes to content, selection and disabled could have happened before the Component was inserted into the DOM.
//Some changes to content, value and disabled could have happened before the Component was inserted into the DOM.
//We trigger all the observers manually to account for those changes.
this._disabledDidChange();
this._contentDidChange();

var selection = this.get('selection');
var value = this.get('value');
if (!isNone(selection)) { this._selectionDidChange(); }
if (!isNone(value)) { this._valueDidChange(); }

this._loadingDidChange();
},
Expand Down Expand Up @@ -204,45 +202,45 @@ export default Ember.Component.extend({
},
/**
* 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)
* Here we need to update our value property (if single value) or array (if multiple values)
* We also send an action
*/
_onItemAdd: function(value) {
var content = this.get('content');
var selection = this.get('selection');
var currentValue = this.get('_selection');
var multiple = this.get('multiple');
if (content) {
var obj = content.find(function(item) {
return (get(item, this.get('_valuePath')) + '') === value;
}, this);
if (multiple && isArray(selection) && obj) {
if (!selection.findBy(this.get('_valuePath'), get(obj, this.get('_valuePath')))) {
if (multiple && isArray(currentValue) && obj) {
if (!currentValue.findBy(this.get('_valuePath'), get(obj, this.get('_valuePath')))) {
this._addSelection(obj);
}
} else if (obj) {
if (!selection || (get(obj, this.get('_valuePath')) !== get(selection, this.get('_valuePath')))) {
if (!currentValue || (get(obj, this.get('_valuePath')) !== get(currentValue, this.get('_valuePath')))) {
this._updateSelection(obj);
}
}
}
},
/**
* Event callback triggered when an item is removed (when something is deselected)
* Here we need to update our selection property (if single selection, here set to null) or remove item from array (if multiple selection)
* Here we need to update our value property (if single value, here set to null) or remove item from array (if multiple value)
*/
_onItemRemove: function(value) {
//in order to know if this event was triggered by observers or if it came from user interaction
if (this._removing) {
return;
}
var content = this.get('content');
var selection = this.get('selection');
var currentValue = this.get('_selection');
var multiple = this.get('multiple');
if (content) {
var obj = content.find(function(item) {
return get(item, this.get('_valuePath')) + '' === value;
}, this);
if (multiple && isArray(selection) && obj) {
if (multiple && isArray(currentValue) && obj) {
this._removeSelection(obj);
} else if (!multiple) {
this._updateSelection(null);
Expand All @@ -254,23 +252,18 @@ export default Ember.Component.extend({
* Update the selection value and send main action
*/
_updateSelection: function(selection) {
this.set('selection', selection);

// allow the observers and computed properties to run first
Ember.run.schedule('actions', this, function() {
var value = this.get('value');
this.sendAction('select-item', selection, value);
});
this.sendAction('select-item', selection);
},

_addSelection: function(obj) {
this.get('selection').addObject(obj);
this.get('_selection').addObject(obj);

Ember.run.schedule('actions', this, function() {
this.sendAction('add-item', obj);
});
},
_removeSelection: function(obj) {
this.get('selection').removeObject(obj);
this.get('_selection').removeObject(obj);

Ember.run.schedule('actions', this, function() {
this.sendAction('remove-item', obj);
Expand All @@ -282,7 +275,7 @@ export default Ember.Component.extend({
*/
_selectionWillChange: Ember.beforeObserver(function() {
var multiple = this.get('multiple');
var selection = this.get('selection');
var selection = this.get('_selection');
if (selection && isArray(selection) && multiple) {
selection.removeArrayObserver(this, {
willChange: 'selectionArrayWillChange',
Expand All @@ -291,7 +284,7 @@ export default Ember.Component.extend({
var len = selection ? get(selection, 'length') : 0;
this.selectionArrayWillChange(selection, 0, len);
}
}, 'selection'),
}, '_selection'),
/**
* Ember observer triggered when the selection property is changed
* We need to bind an array observer when selection is multiple
Expand All @@ -301,13 +294,13 @@ export default Ember.Component.extend({
return;
}
var multiple = this.get('multiple');
var selection = this.get('selection');
var selection = this.get('_selection');
if (multiple) {
if (selection) {
//Normalize selection to an array
if (!isArray(selection)) {
selection = Ember.A([selection]);
this.set('selection', selection);
this.set('_selection', selection);
return;
}
//bind array observers to listen for selection changes
Expand All @@ -317,44 +310,28 @@ export default Ember.Component.extend({
});
} else {
//selection was changed to nothing
this.set('selection', Ember.A());
this.set('_selection', Ember.A());
return;
}
//Trigger a selection change that will update selectize with the new selection
var len = selection ? get(selection, 'length') : 0;
this.selectionArrayDidChange(selection, 0, null, len);
} else {
if (selection) {
var item = get(selection, this.get('_valuePath'));
//select item in selectize
this._selectize.addItem(get(selection, this.get('_valuePath')));
this._selectize.addItem(item);
} else {
//selection was changed to a falsy value. Clear selectize.
//selection was changed to a falsy selection. Clear selectize.
if (this._selectize) {
this._selectize.clear();
this._selectize.showInput();
}
}
}
}, 'selection'),

/**
* It is possible to control the selected item through its value.
*/
_valueDidChange: Ember.observer('value', function() {
var content = this.get('content');
var value = this.get('value');
var valuePath = this.get('_valuePath');
var selectedValue = (valuePath ? this.get('selection.' + valuePath) : this.get('selection'));
var selection;

if (value !== selectedValue) {
selection = content ? content.find(function(obj) {
return value === (valuePath ? get(obj, valuePath) : obj);
}) : null;
}, '_selection'),


this.set('selection', selection);
}
}),

/*
* Triggered before the selection array changes
Expand Down
5 changes: 4 additions & 1 deletion bower.json
Expand Up @@ -12,5 +12,8 @@
"loader.js": "ember-cli/loader.js#3.2.0",
"qunit": "~1.17.1",
"selectize": "~0.12.0"
},
"resolutions": {
"ember": "1.11.1"
}
}
}
3 changes: 3 additions & 0 deletions index.js
Expand Up @@ -14,5 +14,8 @@ module.exports = {

//import javascript
app.import(app.bowerDirectory + '/selectize/dist/js/standalone/selectize.js');
},
isDevelopingAddon: function() {
return true;
}
};