lemo-crm/web/app/components/form-input-select2.js
2018-03-25 18:24:18 +08:00

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;
}
});