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.each(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; } });