lemo-crm/web/app/components/input-select.js

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