108 lines
3.4 KiB
JavaScript
108 lines
3.4 KiB
JavaScript
import BaseFormInput from './base-form-input';
|
|
import { set, observer } from '@ember/object'
|
|
import { isNone } from '@ember/utils'
|
|
import { uniqBy } from '@ember/object/computed';
|
|
import { isArray } from '@ember/array';
|
|
|
|
export default BaseFormInput.extend({
|
|
classNames: ['form-group'],
|
|
classNameBindings: ['hasError:has-error'],
|
|
uniqueSelected: uniqBy('options', 'selected'),
|
|
'value-field': 'value',
|
|
'text-field': 'text',
|
|
onSelectionChanged: observer('options.@each.selected', function() {
|
|
const me = this;
|
|
const options = me.get('options');
|
|
me.setVal(me.getSelected());
|
|
const onChange = me.get('on-change');
|
|
onChange && onChange(me.getVal(), options);
|
|
}),
|
|
didReceiveAttrs() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
isNone(me.get('options')) && me.set('options', []);
|
|
},
|
|
didInsertElement() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
me.prependEmpty();
|
|
me.initSelect();
|
|
|
|
me.$('select.select2').select2({
|
|
allowClear: me.get('nullable'),
|
|
placeholder: me.get('placeholder') || me.get('label') || 'Please select...'
|
|
}).on('change', function(e) {
|
|
console.log('select2 change: ', e);
|
|
if (e.removed) {
|
|
me.unselect(me.findOption(e.removed.id));
|
|
}
|
|
if (e.added) {
|
|
me.select(me.findOption(e.added.id));
|
|
}
|
|
});
|
|
},
|
|
didUpdate() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
me.prependEmpty();
|
|
me.$('select.select2').select2('val', me.getSelected());
|
|
},
|
|
prependEmpty() {
|
|
const me = this;
|
|
// prepend empty object for nullable
|
|
if (me.get('nullable')) {
|
|
const firstObject = me.get('options.firstObject');
|
|
if (firstObject
|
|
&& firstObject[me.get('value-field')]
|
|
&& firstObject[me.get('text-field')]) {
|
|
me.get('options').unshiftObject({});
|
|
}
|
|
}
|
|
},
|
|
initSelect() {
|
|
const me = this;
|
|
// init select
|
|
if (me.get('multiple')) {
|
|
const vals = me.getVal();
|
|
if (isArray(vals)) {
|
|
vals.forEach(v => me.select(me.findOption(v)));
|
|
}
|
|
else {
|
|
me.setVal(me.getSelected());
|
|
}
|
|
}
|
|
else {
|
|
const val = me.getVal();
|
|
if (!isNone(val)) {
|
|
me.select(me.findOption(val));
|
|
}
|
|
else {
|
|
const selected = me.get('options').find(o => o.selected);
|
|
if (selected) {
|
|
me.setVal(selected[me.get('value-field')]);
|
|
}
|
|
else {
|
|
me.select(me.get('options.firstObject'))
|
|
}
|
|
}
|
|
}
|
|
},
|
|
findOption(val) {
|
|
const me = this;
|
|
// val may empty of nullable option
|
|
return val ? me.get('options').find(op => op[me.get('value-field')] == val)
|
|
: me.get('options.firstObject');
|
|
},
|
|
select(op) {
|
|
op && set(op, 'selected', true);
|
|
},
|
|
unselect(op) {
|
|
op && set(op, 'selected', false);
|
|
},
|
|
getSelected() {
|
|
const me = this;
|
|
const selected = me.get('options').filter(o => o.selected).mapBy(me.get('value-field'));
|
|
return selected.length > 1 ? selected : selected.length == 1 ? selected[0] : null;
|
|
}
|
|
});
|