151 lines
4.7 KiB
JavaScript
151 lines
4.7 KiB
JavaScript
import BasicComponent from './basic-component';
|
|
import { observer } from '@ember/object';
|
|
import { A } from '@ember/array';
|
|
import $ from 'jquery';
|
|
|
|
export default BasicComponent.extend({
|
|
tagName: 'x-fake-el',
|
|
options: [],
|
|
'value-field': 'value',
|
|
'text-field': 'text',
|
|
'enabled-field': null,
|
|
'hidden-input': true,
|
|
loose: true,
|
|
'fire-init-change': true,
|
|
'values-as-string': true,
|
|
'values-splitter': ',',
|
|
didReceiveAttrs() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
|
|
// select first
|
|
if (!me.get('multiple') &&
|
|
!me.get('nullable')) {
|
|
const options = me.get('options');
|
|
if (options && options.length) {
|
|
const val = me._getVal();
|
|
// no val or val not in options
|
|
if (!val || !options.any(o => me.opEq(o, val))) {
|
|
me._setVal(me.getOpVal(options[0]));
|
|
}
|
|
}
|
|
}
|
|
},
|
|
didInsertElement() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
|
|
$(me.element).children('select.select2').select2({
|
|
multiple: me.get('multiple'),
|
|
disabled: me.get('readonly'),
|
|
allowClear: me.get('nullable'),
|
|
placeholder: me.get('placeholder') ||
|
|
me.get('label') || 'Please select...',
|
|
templateResult: me.get('tplResult'),
|
|
templateSelection: me.get('tplSelection')
|
|
}).on('change', function(e) {
|
|
console.log('selection change: ', e);
|
|
const selected = $(this).select2('data');
|
|
if (me.get('multiple')) {
|
|
me._setVal(selected ? selected.map(o => o.id) : []);
|
|
}
|
|
else {
|
|
const o = selected ? selected[0] : null;
|
|
me._setVal(o ? o.id : null);
|
|
}
|
|
me.notifyChange();
|
|
})
|
|
// init val, trigger change required
|
|
.val(me._getVal()).trigger('change');
|
|
|
|
if (me.get('fire-init-change')) {
|
|
me.notifyChange();
|
|
}
|
|
},
|
|
optionsChanged: observer('options', function() {
|
|
const me = this;
|
|
me.set('optionsUpdated', true);
|
|
}),
|
|
didUpdate() {
|
|
const me = this;
|
|
me._super(...arguments);
|
|
|
|
if (me.get('optionsUpdated')) {
|
|
me.set('optionsUpdated', false);
|
|
const options = me.get('options');
|
|
const jqEl = $(me.element).children('select.select2');
|
|
if (me.get('multiple')) {
|
|
me._setVal([]);
|
|
// clear selection
|
|
jqEl.val(null).trigger('change');
|
|
}
|
|
else {
|
|
const val = me._getVal();
|
|
// reset old val
|
|
if (val && me.findOption(val)) {
|
|
jqEl.val(val).trigger('change');
|
|
}
|
|
else {
|
|
const firstOption = options[0];
|
|
if (firstOption && !me.get('nullable')) {
|
|
me._setVal(me.getOptVal(firstOption));
|
|
jqEl.val(val).trigger('change');
|
|
}
|
|
else {
|
|
me._setVal(null);
|
|
jqEl.val(null).trigger('change');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
findOption(val) {
|
|
const me = this;
|
|
return me.get('options').find(op => me.opEq(op, val));
|
|
},
|
|
notifyChange() {
|
|
const me = this;
|
|
const options = me.get('options');
|
|
const onChange = me.get('on-change');
|
|
onChange && onChange(me._getVal(), options);
|
|
},
|
|
_getVal() {
|
|
const me = this;
|
|
const val = me.getVal();
|
|
if (me.get('multiple')
|
|
&& typeof val === 'string'
|
|
&& me.get('values-as-string')) {
|
|
return A(val ? val.split(me.get('values-splitter')) : []);
|
|
}
|
|
return val;
|
|
},
|
|
_setVal(val) {
|
|
const me = this;
|
|
me.setVal(me.get('multiple')
|
|
&& me.get('values-as-string') ?
|
|
(val.length ? val.join(me.get('values-splitter')) : null) :
|
|
val);
|
|
},
|
|
isPlainVal(val) {
|
|
return typeof val === 'string' ||
|
|
typeof val === 'number' ||
|
|
typeof val === 'boolean' ||
|
|
(
|
|
(!!val && typeof val === 'object') &&
|
|
['[object String]',
|
|
'[object Number]',
|
|
'[object Boolean]'
|
|
].includes(Object.prototype.toString.call(val))
|
|
)
|
|
},
|
|
getOpVal(op) {
|
|
const me = this;
|
|
return me.isPlainVal(op) ? op : op[me.get('value-field')];
|
|
},
|
|
opEq(op, val) {
|
|
const me = this;
|
|
let opv = me.getOpVal(op);
|
|
return me.get('loose') ? opv == val : opv === val;
|
|
}
|
|
});
|