UNPKG

ng-selector

Version:

Angular2 selector component based on selectize.js

410 lines (403 loc) 13.5 kB
import { CommonModule } from '@angular/common'; import { Attribute, Component, Directive, EventEmitter, Input, NgModule, Output, ViewChild, forwardRef } from '@angular/core'; import { FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; import * as jqueryProxy from 'jquery'; import jqueryProxy__default from 'jquery'; import 'selectize'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ // rollup dirty fix : https://github.com/rollup/rollup/issues/1267 var jQuery = jqueryProxy__default || jqueryProxy; var NgSelectorComponent = (function () { function NgSelectorComponent(placeholder, idField, labelField, allowCreation) { if (placeholder === void 0) { placeholder = ''; } if (idField === void 0) { idField = 'id'; } if (labelField === void 0) { labelField = 'label'; } if (allowCreation === void 0) { allowCreation = true; } this.placeholder = placeholder; this.idField = idField; this.labelField = labelField; this.allowCreation = allowCreation; this.plugins = new Array(); // async input options (function which provide data) this.loadValues = new EventEmitter(); // rendering method to change display of item and options this.renderer = new EventEmitter(); this._disabled = false; this._mutiple = false; this.onChange = function (_) { }; this.onTouched = function () { }; } Object.defineProperty(NgSelectorComponent.prototype, "readonly", { set: /** * @param {?} disabled * @return {?} */ function (disabled) { this._disabled = disabled; this.checkDisabled(); }, enumerable: true, configurable: true }); Object.defineProperty(NgSelectorComponent.prototype, "options", { set: /** * @param {?} values * @return {?} */ function (values) { this.optionsChanged(values); }, enumerable: true, configurable: true }); Object.defineProperty(NgSelectorComponent.prototype, "multiple", { get: /** * @return {?} */ function () { return this._mutiple; }, set: /** * @param {?} value * @return {?} */ function (value) { this._mutiple = value; // this.selectize.maxItems = this.multiple ? null : 1, if (this.selectize) this.selectize.maxItems = this.checkMultipleFalsy(); }, enumerable: true, configurable: true }); /** * @return {?} */ NgSelectorComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { var _this = this; // initialize with default values this.placeholder = this.placeholder || ''; this.idField = this.idField || 'id'; this.labelField = this.labelField || 'label'; this.multiple = this.multiple === undefined ? false : this.multiple; this.allowCreation = this.allowCreation === undefined ? true : this.allowCreation; var /** @type {?} */ render; if (this.renderer.observers.length === 1) { render = { option: this.rendering('option'), item: this.rendering('item'), }; } // prepare selectize compatible method to fetch data var /** @type {?} */ load = null; if (this.loadValues.observers.length === 1) { load = function (query, callback) { // TODO find a way to display it to user // disabled async search if search string is below 3 characters long if (query.length < 3) { return callback([]); } _this.loadValues.emit({ query: query, result: callback }); }; } var /** @type {?} */ plugins = [].concat(this.plugins); // configure Selectize this.selectize = (/** @type {?} */ (jQuery(this.selector.nativeElement))).selectize(/** @type {?} */ ({ valueField: this.idField, labelField: this.labelField, searchField: this.labelField, placeholder: this.placeholder, maxItems: this.checkMultipleFalsy(), create: this.allowCreation, selectOnTab: true, persist: true, load: load, render: render, plugins: plugins, onChange: this.dataChanged.bind(this) }))[0].selectize; // force form-control on jQuery(this.selector.nativeElement).siblings().find('.selectize-input').addClass('form-control'); // force refresh data when Selectize is initialized this.optionsChanged(this.tmpOptions); this.updateData(this.data); this.checkDisabled(); }; /** * @param {?} options * @return {?} */ NgSelectorComponent.prototype.optionsChanged = /** * @param {?} options * @return {?} */ function (options) { var _this = this; if (!options || !Object.keys(options).length) { return this.selectize && this.selectize.clearOptions(); } if (this.selectize) { Object.keys(this.selectize.options).forEach(function (id) { if (!options.find(function (elem) { return elem[_this.idField] === _this.selectize.options[id][_this.idField]; })) { _this.selectize.removeOption(id); } }); // this.tagsComponent.options = options; options.forEach(function (option) { var /** @type {?} */ value = option[_this.idField]; // check if option exist to call the right method ... sorry ... -_- if (_this.selectize.options[value]) { _this.selectize.updateOption(value, option); } else { _this.selectize.addOption(option); } }); this.selectize.refreshOptions(false); } else { this.tmpOptions = options; } }; /** * @param {?} value * @return {?} */ NgSelectorComponent.prototype.dataChanged = /** * @param {?} value * @return {?} */ function (value) { var _this = this; if (!value || !value.length) { return this.onChange(this.multiple ? [] : null); } if (this.multiple) { var /** @type {?} */ selectedValues = value .map(function (id) { return _this.selectize.options[id]; }) .filter(function (item) { return !!item; }) .map(this.cleanOrder); this.onChange(selectedValues); } else { this.onChange(this.cleanOrder(this.selectize.options[value])); } }; /** * @param {?} data * @return {?} */ NgSelectorComponent.prototype.updateData = /** * @param {?} data * @return {?} */ function (data) { var _this = this; // component not initialized yet if (!this.selectize) return; if (!data) { this.selectize.clear(); return; } this.selectize.addOption(data); if (Array.isArray(data)) { this.selectize.setValue(data.map(function (item) { return item[_this.idField]; })); } else if (data && typeof data === 'object') { this.selectize.setValue(data[this.idField]); } }; /** * @return {?} */ NgSelectorComponent.prototype.checkDisabled = /** * @return {?} */ function () { if (!this.selectize) return; if (this._disabled === true) { this.selectize.disable(); } else if (this._disabled === false) { this.selectize.enable(); } }; /** * @param {?} type * @return {?} */ NgSelectorComponent.prototype.rendering = /** * @param {?} type * @return {?} */ function (type) { var _this = this; return function (i) { var /** @type {?} */ html = i[_this.labelField]; _this.renderer.emit({ val: i, html: function (htmlContent) { return html = htmlContent; }, type: type }); return html; }; }; /** * @param {?} value * @return {?} */ NgSelectorComponent.prototype.writeValue = /** * @param {?} value * @return {?} */ function (value) { this.updateData(value); }; /** * @param {?} fn * @return {?} */ NgSelectorComponent.prototype.registerOnChange = /** * @param {?} fn * @return {?} */ function (fn) { this.onChange = fn; }; /** * @param {?} fn * @return {?} */ NgSelectorComponent.prototype.registerOnTouched = /** * @param {?} fn * @return {?} */ function (fn) { this.onTouched = fn; }; /** * @param {?} item * @return {?} */ NgSelectorComponent.prototype.cleanOrder = /** * @param {?} item * @return {?} */ function (item) { delete item.$order; return item; }; /** * @return {?} */ NgSelectorComponent.prototype.checkMultipleFalsy = /** * @return {?} */ function () { return (this.multiple) ? null : 1; }; NgSelectorComponent.decorators = [ { type: Component, args: [{ selector: 'ng-selector', template: "<select #selector></select>", providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(function () { return NgSelectorComponent; }), multi: true }] },] }, ]; /** @nocollapse */ NgSelectorComponent.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Attribute, args: ['placeholder',] },] }, { type: undefined, decorators: [{ type: Attribute, args: ['id-field',] },] }, { type: undefined, decorators: [{ type: Attribute, args: ['label-field',] },] }, { type: undefined, decorators: [{ type: Attribute, args: ['allow-creation',] },] }, ]; }; NgSelectorComponent.propDecorators = { "selector": [{ type: ViewChild, args: ['selector',] },], "readonly": [{ type: Input },], "options": [{ type: Input },], "plugins": [{ type: Input },], "loadValues": [{ type: Output },], "renderer": [{ type: Output },], "multiple": [{ type: Input, args: ['multiple',] },], }; return NgSelectorComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var NgSelectorValidator = (function () { function NgSelectorValidator() { } /** * @param {?} c * @return {?} */ NgSelectorValidator.prototype.validate = /** * @param {?} c * @return {?} */ function (c) { return this.isEmpty(c.value) ? { required: { valid: false } } : null; }; /** * @param {?} value * @return {?} */ NgSelectorValidator.prototype.isEmpty = /** * @param {?} value * @return {?} */ function (value) { if (value === null || value === undefined) { return true; } // empty array if (Array.isArray(value) && value.length > 0) { return false; } // all objects are valids if (!Array.isArray(value) && typeof value === 'object' && Object.keys(value).length > 0) { return false; } return true; }; NgSelectorValidator.decorators = [ { type: Directive, args: [{ selector: 'ng-selector[required][ngModel]', providers: [{ provide: NG_VALIDATORS, useClass: NgSelectorValidator, multi: true }] },] }, ]; /** @nocollapse */ NgSelectorValidator.ctorParameters = function () { return []; }; return NgSelectorValidator; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var NgSelectorModule = (function () { function NgSelectorModule() { } NgSelectorModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule, FormsModule, ], declarations: [ NgSelectorComponent, NgSelectorValidator, ], exports: [ NgSelectorComponent, NgSelectorValidator, ] },] }, ]; /** @nocollapse */ NgSelectorModule.ctorParameters = function () { return []; }; return NgSelectorModule; }()); export { NgSelectorModule, NgSelectorComponent, NgSelectorValidator };