Ghost/ghost/admin/app/components/gh-selectize.js

127 lines
3.8 KiB
JavaScript
Raw Normal View History

/* eslint-disable camelcase */
import {A as emberA, isEmberArray} from 'ember-array/utils';
import computed from 'ember-computed';
import {isBlank} from 'ember-utils';
import get from 'ember-metal/get';
import run from 'ember-runloop';
import EmberSelectizeComponent from 'ember-cli-selectize/components/ember-selectize';
export default EmberSelectizeComponent.extend({
selectizeOptions: computed(function () {
let options = this._super(...arguments);
options.onChange = run.bind(this, '_onChange');
return options;
}),
/**
* Event callback that is triggered when user creates a tag
* - modified to pass the caret position to the action
*/
_create(input, callback) {
let caret = this._selectize.caretPos;
// Delete user entered text
this._selectize.setTextboxValue('');
// Send create action
// allow the observers and computed properties to run first
run.schedule('actions', this, function () {
this.sendAction('create-item', input, caret);
});
// We cancel the creation here, so it's up to you to include the created element
// in the content and selection property
callback(null);
},
_addSelection(obj) {
let _valuePath = this.get('_valuePath');
let val = get(obj, _valuePath);
let caret = this._selectize.caretPos;
// caret position is always 1 more than the desired index as this method
// is called after selectize has inserted the item and the caret has moved
// to the right
caret = caret - 1;
this.get('selection').insertAt(caret, obj);
run.schedule('actions', this, function () {
this.sendAction('add-item', obj);
this.sendAction('add-value', val);
});
},
_onChange(args) {
let selection = get(this, 'selection');
let valuePath = get(this, '_valuePath');
let reorderedSelection = emberA([]);
if (!args || !selection || !isEmberArray(selection) || args.length !== get(selection, 'length')) {
return;
}
// exit if we're not dealing with the same objects as the selection
let objectsHaveChanged = selection.any(function (obj) {
return args.indexOf(get(obj, valuePath)) === -1;
});
if (objectsHaveChanged) {
return;
}
// exit if the order is still the same
let orderIsSame = selection.every(function (obj, idx) {
return get(obj, valuePath) === args[idx];
});
if (orderIsSame) {
return;
}
// we have a re-order, update the selection
args.forEach((value) => {
let obj = selection.find(function (item) {
return `${get(item, valuePath)}` === value;
});
if (obj) {
reorderedSelection.addObject(obj);
}
});
this.set('selection', reorderedSelection);
},
_preventOpeningWhenBlank() {
let openOnFocus = this.get('openOnFocus');
if (!openOnFocus) {
run.schedule('afterRender', this, function () {
let selectize = this._selectize;
if (selectize) {
selectize.on('dropdown_open', function () {
if (isBlank(selectize.$control_input.val())) {
selectize.close();
}
});
selectize.on('type', function (filter) {
if (isBlank(filter)) {
selectize.close();
}
});
}
});
}
},
didInsertElement() {
this._super(...arguments);
this._preventOpeningWhenBlank();
}
});