UNPKG

@ngqp/core

Version:

Synchronizing form controls with the URL for Angular

87 lines 11 kB
import { Directive, ElementRef, forwardRef, HostListener, Renderer2 } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; /** @ignore */ const NGQP_MULTI_SELECT_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MultiSelectControlValueAccessorDirective), multi: true }; /** @ignore */ export class MultiSelectControlValueAccessorDirective { constructor(renderer, elementRef) { this.renderer = renderer; this.elementRef = elementRef; this.selectedIds = []; this.options = new Map(); this.optionMap = new Map(); this.idCounter = 0; this.fnChange = (_) => { }; this.fnTouched = () => { }; } onChange() { this.selectedIds = Array.from(this.options.entries()) .filter(([id, option]) => option.selected) .map(([id]) => id); const values = this.selectedIds.map(id => this.optionMap.get(id)); this.fnChange(values); } onTouched() { this.fnTouched(); } writeValue(values) { values = values === null ? [] : values; if (!Array.isArray(values)) { throw new Error(`Provided a non-array value to select[multiple]: ${values}`); } this.selectedIds = values .map(value => this.getOptionId(value)) .filter((id) => id !== null); this.options.forEach((option, id) => option.selected = this.selectedIds.includes(id)); } registerOnChange(fn) { this.fnChange = fn; } registerOnTouched(fn) { this.fnTouched = fn; } setDisabledState(isDisabled) { this.renderer.setProperty(this.elementRef.nativeElement, 'disabled', isDisabled); } registerOption(option) { const newId = (this.idCounter++).toString(); this.options.set(newId, option); return newId; } deregisterOption(id) { this.optionMap.delete(id); } updateOptionValue(id, value) { this.optionMap.set(id, value); if (this.selectedIds.includes(id)) { this.onChange(); } } getOptionId(value) { for (const id of Array.from(this.optionMap.keys())) { if (this.optionMap.get(id) === value) { return id; } } return null; } } MultiSelectControlValueAccessorDirective.decorators = [ { type: Directive, args: [{ selector: 'select[multiple][queryParamName],select[multiple][queryParam]', providers: [NGQP_MULTI_SELECT_VALUE_ACCESSOR], },] } ]; MultiSelectControlValueAccessorDirective.ctorParameters = () => [ { type: Renderer2 }, { type: ElementRef } ]; MultiSelectControlValueAccessorDirective.propDecorators = { onChange: [{ type: HostListener, args: ['change',] }], onTouched: [{ type: HostListener, args: ['blur',] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc2VsZWN0LWNvbnRyb2wtdmFsdWUtYWNjZXNzb3IuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uLy4uL3Byb2plY3RzL25ncXAvY29yZS9zcmMvIiwic291cmNlcyI6WyJsaWIvYWNjZXNzb3JzL211bHRpLXNlbGVjdC1jb250cm9sLXZhbHVlLWFjY2Vzc29yLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFZLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRyxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHekUsY0FBYztBQUNkLE1BQU0sZ0NBQWdDLEdBQWE7SUFDL0MsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHdDQUF3QyxDQUFDO0lBQ3ZFLEtBQUssRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGLGNBQWM7QUFLZCxNQUFNLE9BQU8sd0NBQXdDO0lBd0JqRCxZQUFvQixRQUFtQixFQUFVLFVBQXlDO1FBQXRFLGFBQVEsR0FBUixRQUFRLENBQVc7UUFBVSxlQUFVLEdBQVYsVUFBVSxDQUErQjtRQXRCbEYsZ0JBQVcsR0FBYSxFQUFFLENBQUM7UUFDM0IsWUFBTyxHQUFHLElBQUksR0FBRyxFQUF5QyxDQUFDO1FBQzNELGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBYSxDQUFDO1FBRWpDLGNBQVMsR0FBRyxDQUFDLENBQUM7UUFDZCxhQUFRLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRSxHQUFFLENBQUMsQ0FBQztRQUMxQixjQUFTLEdBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO0lBaUI3QixDQUFDO0lBZE0sUUFBUTtRQUNYLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FB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Q0FBQyxLQUFLLEtBQUssRUFBRTtnQkFDbEMsT0FBTyxFQUFFLENBQUM7YUFDYjtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQzs7O1lBaEZKLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsK0RBQStEO2dCQUN6RSxTQUFTLEVBQUUsQ0FBQyxnQ0FBZ0MsQ0FBQzthQUNoRDs7O1lBZm1FLFNBQVM7WUFBekQsVUFBVTs7O3VCQTBCekIsWUFBWSxTQUFDLFFBQVE7d0JBU3JCLFlBQVksU0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBmb3J3YXJkUmVmLCBIb3N0TGlzdGVuZXIsIFByb3ZpZGVyLCBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE11bHRpU2VsZWN0T3B0aW9uRGlyZWN0aXZlIH0gZnJvbSAnLi9tdWx0aS1zZWxlY3Qtb3B0aW9uLmRpcmVjdGl2ZSc7XG5cbi8qKiBAaWdub3JlICovXG5jb25zdCBOR1FQX01VTFRJX1NFTEVDVF9WQUxVRV9BQ0NFU1NPUjogUHJvdmlkZXIgPSB7XG4gICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTXVsdGlTZWxlY3RDb250cm9sVmFsdWVBY2Nlc3NvckRpcmVjdGl2ZSksXG4gICAgbXVsdGk6IHRydWVcbn07XG5cbi8qKiBAaWdub3JlICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ3NlbGVjdFttdWx0aXBsZV1bcXVlcnlQYXJhbU5hbWVdLHNlbGVjdFttdWx0aXBsZV1bcXVlcnlQYXJhbV0nLFxuICAgIHByb3ZpZGVyczogW05HUVBfTVVMVElfU0VMRUNUX1ZBTFVFX0FDQ0VTU09SXSxcbn0pXG5leHBvcnQgY2xhc3MgTXVsdGlTZWxlY3RDb250cm9sVmFsdWVBY2Nlc3NvckRpcmVjdGl2ZTxUPiBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcblxuICAgIHByaXZhdGUgc2VsZWN0ZWRJZHM6IHN0cmluZ1tdID0gW107XG4gICAgcHJpdmF0ZSBvcHRpb25zID0gbmV3IE1hcDxzdHJpbmcsIE11bHRpU2VsZWN0T3B0aW9uRGlyZWN0aXZlPFQ+PigpO1xuICAgIHByaXZhdGUgb3B0aW9uTWFwID0gbmV3IE1hcDxzdHJpbmcsIFQ+KCk7XG5cbiAgICBwcml2YXRlIGlkQ291bnRlciA9IDA7XG4gICAgcHJpdmF0ZSBmbkNoYW5nZSA9IChfOiBUW10pID0+IHt9O1xuICAgIHByaXZhdGUgZm5Ub3VjaGVkID0gKCkgPT4ge307XG5cbiAgICBASG9zdExpc3RlbmVyKCdjaGFuZ2UnKVxuICAgIHB1YmxpYyBvbkNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZElkcyA9IEFycmF5LmZyb20odGhpcy5vcHRpb25zLmVudHJpZXMoKSlcbiAgICAgICAgICAgIC5maWx0ZXIoKFtpZCwgb3B0aW9uXSkgPT4gb3B0aW9uLnNlbGVjdGVkKVxuICAgICAgICAgICAgLm1hcCgoW2lkXSkgPT4gaWQpO1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLnNlbGVjdGVkSWRzLm1hcChpZCA9PiB0aGlzLm9wdGlvbk1hcC5nZXQoaWQpISk7XG4gICAgICAgIHRoaXMuZm5DaGFuZ2UodmFsdWVzKTtcbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdibHVyJylcbiAgICBwdWJsaWMgb25Ub3VjaGVkKCkge1xuICAgICAgICB0aGlzLmZuVG91Y2hlZCgpO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxTZWxlY3RFbGVtZW50Pikge1xuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlczogVFtdKSB7XG4gICAgICAgIHZhbHVlcyA9IHZhbHVlcyA9PT0gbnVsbCA/IDxUW10+W10gOiB2YWx1ZXM7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb3ZpZGVkIGEgbm9uLWFycmF5IHZhbHVlIHRvIHNlbGVjdFttdWx0aXBsZV06ICR7dmFsdWVzfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZElkcyA9IHZhbHVlc1xuICAgICAgICAgICAgLm1hcCh2YWx1ZSA9PiB0aGlzLmdldE9wdGlvbklkKHZhbHVlKSlcbiAgICAgICAgICAgIC5maWx0ZXIoKGlkOiBzdHJpbmcgfCBudWxsKTogaWQgaXMgc3RyaW5nID0+IGlkICE9PSBudWxsKTtcbiAgICAgICAgdGhpcy5vcHRpb25zLmZvckVhY2goKG9wdGlvbiwgaWQpID0+IG9wdGlvbi5zZWxlY3RlZCA9IHRoaXMuc2VsZWN0ZWRJZHMuaW5jbHVkZXMoaWQpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG4gICAgICAgIHRoaXMuZm5DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuICAgICAgICB0aGlzLmZuVG91Y2hlZCA9IGZuO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2Rpc2FibGVkJywgaXNEaXNhYmxlZCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZ2lzdGVyT3B0aW9uKG9wdGlvbjogTXVsdGlTZWxlY3RPcHRpb25EaXJlY3RpdmU8VD4pOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBuZXdJZCA9ICh0aGlzLmlkQ291bnRlcisrKS50b1N0cmluZygpO1xuICAgICAgICB0aGlzLm9wdGlvbnMuc2V0KG5ld0lkLCBvcHRpb24pO1xuICAgICAgICByZXR1cm4gbmV3SWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGRlcmVnaXN0ZXJPcHRpb24oaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLm9wdGlvbk1hcC5kZWxldGUoaWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVPcHRpb25WYWx1ZShpZDogc3RyaW5nLCB2YWx1ZTogVCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9wdGlvbk1hcC5zZXQoaWQsIHZhbHVlKTtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJZHMuaW5jbHVkZXMoaWQpKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE9wdGlvbklkKHZhbHVlOiBUKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgQXJyYXkuZnJvbSh0aGlzLm9wdGlvbk1hcC5rZXlzKCkpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25NYXAuZ2V0KGlkKSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbn0iXX0=