import { Component, EventEmitter, Inject, Input, IterableDiffers, Optional, Output, ViewChild } from '@angular/core';
import { NG_ASYNC_VALIDATORS, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms';
import { ElementBase } from '../../base/element-base';
import { INPUT_FORMS_CONFIG } from '../../input-forms-config.constants';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "../../../ui/directives/click-outside.directive";
import * as i4 from "../../../ui/directives/auto-focus.directive";
import * as i5 from "../../../ui/pipes/search-by.pipe";
let identifier = 0;
export class FilterMultiselectComponent extends ElementBase {
    constructor(validators, asyncValidators, config, iterableDiffers) {
        super(validators, asyncValidators, config);
        this.config = config;
        this.iterableDiffers = iterableDiffers;
        this.placeholder = 'Select...';
        this.searchPlaceholder = 'Search...';
        this.displayTextProperty = 'text';
        this.valueProperty = 'value';
        this.emptyMessage = 'No results found.';
        this.selectAllButtonLabel = 'Select all';
        this.clearSelectionButtonLabel = 'Clear';
        this.dropRight = false;
        this.onChange = new EventEmitter();
        this.identifier = `input-multiselect-${identifier++}`;
        if (config.multiSelect) {
            Object.assign(this, config.multiSelect);
        }
        this._differModel = this.iterableDiffers.find([]).create(null);
        this._differOptions = this.iterableDiffers.find([]).create(null);
    }
    get options() {
        return this._options;
    }
    set options(value) {
        this._options = value;
        this.Init();
    }
    ngOnInit() {
        this.Init();
    }
    ngDoCheck() {
        let changesInModel = this._differModel.diff(this.value);
        let changesInOptions = this._differOptions.diff(this._options);
        if (changesInModel || (changesInOptions && !this.modelInitialized)) {
            this.Init();
        }
    }
    Init() {
        if (!this.value || !this.options || this.value.length == 0 || this.options.length == 0) {
            if ((!this.value || this.value.length == 0) && this.options) {
                this.ToggleAllItemsSelection(false, false);
            }
            return;
        }
        for (let i = 0; i < this.options.length; i++) {
            this.options[i].selected = this.value.filter(x => this.options[i][this.valueProperty] == x[this.valueProperty]).length > 0;
        }
        this.modelInitialized = true;
    }
    ToggleDropDown(event, value) {
        if ((value == false && !this.showOptions) || (value == undefined && this.disabled))
            return;
        if (value == undefined) {
            if (this.showOptions) {
                this.setComboTouched();
            }
            this.showOptions = !this.showOptions;
        }
        else {
            if (!value && this.showOptions) {
                this.setComboTouched();
            }
            this.showOptions = value;
        }
        this.clearSearch();
    }
    ToggleItemSelected(item) {
        if (this.disabled) {
            return;
        }
        item.selected = !item.selected;
        this.updateModel();
        this.onChange.emit();
    }
    ToggleAllItemsSelection(value, emitChanges) {
        if (this.disabled) {
            return;
        }
        if (!this.options || this.options.length == 0)
            return;
        for (let i = 0; i < this.options.length; i++) {
            this.options[i].selected = value;
        }
        this.updateModel();
        this.clearSearch();
        if (emitChanges)
            this.onChange.emit();
    }
    ItemSelectedCheckChanged() {
        if (this.disabled) {
            return;
        }
        this.updateModel();
        this.onChange.emit();
    }
    RemoveItem(item, index, event) {
        if (this.disabled || !this.options || this.options.length == 0) {
            return;
        }
        let itemToRemove = this.options.find(x => x[this.valueProperty] == item[this.valueProperty]);
        if (itemToRemove) {
            this.ToggleItemSelected(itemToRemove);
            this.clearSearch();
        }
        else {
            this.value.splice(index, 1);
        }
        event.stopPropagation();
    }
    OnComboPressed(event) {
        if (event.keyCode == 13) {
            this.ToggleDropDown(null);
            event.preventDefault();
        }
    }
    clearSearch() {
        this.search = '';
    }
    updateModel() {
        if (!this.options || this.options.length == 0) {
            this.value = [];
            return;
        }
        this.value = this.options.filter(x => x.selected);
    }
    setComboTouched() {
        this.comboTouched = true;
    }
}
FilterMultiselectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterMultiselectComponent, deps: [{ token: NG_VALIDATORS, optional: true }, { token: NG_ASYNC_VALIDATORS, optional: true }, { token: INPUT_FORMS_CONFIG }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component });
FilterMultiselectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FilterMultiselectComponent, selector: "filter-multiselect", inputs: { placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", displayTextProperty: "displayTextProperty", valueProperty: "valueProperty", emptyMessage: "emptyMessage", selectAllButtonLabel: "selectAllButtonLabel", clearSelectionButtonLabel: "clearSelectionButtonLabel", dropRight: "dropRight", options: "options" }, outputs: { onChange: "onChange" }, providers: [{
            provide: NG_VALUE_ACCESSOR,
            useExisting: FilterMultiselectComponent,
            multi: true
        }], viewQueries: [{ propertyName: "model", first: true, predicate: NgModel, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div [id]=\"identifier\" class=\"ui-filter-multiselect\">\n    <input type=\"hidden\" [(ngModel)]=\"value\" />\n\n    <div class=\"combobox d-flex align-items-center justify-content-between\" \n        [ngClass]=\"{\n            'open': showOptions, \n            'disabled': disabled,\n            'has-value': value?.length > 0\n        }\"\n        (click)=\"ToggleDropDown($event)\" (keyup)=\"OnComboPressed($event)\" tabindex=\"0\">\n\n        <span class=\"mr-2\" *ngIf=\"value?.length > 0\"><b>{{label}}</b>: </span>\n\n        <span *ngIf=\"!value || value.length == 0\">{{label}}</span>\n\n        <div *ngIf=\"value?.length > 0\" class=\"selected-items d-flex align-items-center\">\n            <span *ngFor=\"let item of value | slice:0:1; let i = index;\">\n                <small class=\"text-muted text-truncate ml-1\">{{item[displayTextProperty]}}</small>\n            </span>\n            <small class=\"text-muted\" *ngIf=\"value.length > 1\">... (+{{value.length - 1}})</small>\n        </div>\n\n        <i class=\"fa\" [ngClass]=\"{'fa-angle-down': !showOptions, 'fa-angle-up': showOptions}\"></i>\n    </div>\n\n    <div class=\"dropdown-options shadow fadeInDown\" *ngIf=\"showOptions\" (clickOutside)=\"ToggleDropDown($event, false)\" \n        [ngClass]=\"{\n            'drop-right': dropRight\n        }\">\n        \n        <div class=\"options-container\" *ngIf=\"options?.length > 0\">\n            <div class=\"toolbar d-flex align-items-center\">\n                <input type=\"text\" class=\"form-control flex-grow-1\" name=\"{{identifier}}-search\" [(ngModel)]=\"search\" placeholder=\"{{searchPlaceholder}}\" auto-focus />\n                <button type=\"button\" class=\"btn btn-light ml-1 flex-shrink-0\" (click)=\"ToggleAllItemsSelection(true, true)\" [disabled]=\"disabled\"><i class=\"fa fa-check-square\"></i> {{selectAllButtonLabel}}</button>\n                <button type=\"button\" class=\"btn btn-light ml-1 flex-shrink-0\" (click)=\"ToggleAllItemsSelection(false, true)\" [disabled]=\"disabled\"><i class=\"fa fa-eraser\"></i> {{clearSelectionButtonLabel}}</button>\n            </div>\n\n            <ul>\n                <li class=\"d-flex\" *ngFor=\"let item of options | searchBy : displayTextProperty : search\" [ngClass]=\"{'selected': item.selected}\">\n                    <div class=\"checkbox mr-3 flex-shrink-0\">\n                        <input type=\"checkbox\" name=\"{{identifier}}-option\" [(ngModel)]=\"item.selected\" (change)=\"ItemSelectedCheckChanged()\" [disabled]=\"disabled\" />\n                    </div>\n                    <span class=\"link\" (click)=\"ToggleItemSelected(item)\">{{item[displayTextProperty]}}</span>\n                </li>\n            </ul>\n\n            <small class=\"empty-results\" *ngIf=\"(options | searchBy : displayTextProperty : search).length == 0\">{{emptyMessage}}</small>\n        </div>\n\n        <small class=\"empty-results\" *ngIf=\"!options || options.length == 0\">{{emptyMessage}}</small>\n    </div>\n</div>", styles: ["@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-5%,0)}to{opacity:1;transform:translateZ(0)}}.fadeInDown{animation-name:fadeInDown;animation-duration:.35s;animation-fill-mode:both}.ui-filter-multiselect{position:relative}.ui-filter-multiselect *{-webkit-user-select:none;user-select:none}.ui-filter-multiselect>.combobox{outline:none;padding:.375rem .475rem;width:-moz-fit-content;width:fit-content}.ui-filter-multiselect>.combobox>span{color:#6c757d;font-size:1rem;line-height:1.5}.ui-filter-multiselect>.combobox>i{color:#495057;font-size:14px;margin-left:10px}.ui-filter-multiselect>.combobox .selected-items{margin-left:-5px;overflow:hidden}.ui-filter-multiselect>.combobox .selected-items .badge{margin-right:3px;line-height:1;color:#888;background-color:#e0e0e0;border-bottom:2px solid #ccc;border-left:2px solid #ccc;padding:5px 7px 4px}.ui-filter-multiselect>.combobox .selected-items .badge>span{display:inline-block;max-width:150px}.ui-filter-multiselect>.combobox .selected-items .badge:hover{cursor:pointer;color:#fff;background-color:#007bff;border-bottom:2px solid #00559a;border-left:2px solid #00559a}.ui-filter-multiselect>.combobox.open{border-radius:.25rem .25rem 0 0}.ui-filter-multiselect>.combobox.disabled{background-color:#e9ecef;border-color:#ced4da}.ui-filter-multiselect>.combobox.has-validations.is-invalid{border-color:#dc3545}.ui-filter-multiselect>.combobox.has-validations.is-invalid.open{box-shadow:0 0 0 .2rem #dc354540}.ui-filter-multiselect>.combobox.has-validations.is-valid{border-color:#28a745}.ui-filter-multiselect>.combobox.has-validations.is-valid.open{box-shadow:0 0 0 .2rem #28a74540}.ui-filter-multiselect .combobox:hover{cursor:pointer}.ui-filter-multiselect>.dropdown-options{background-color:#fff;border:1px solid #ced4da;border-radius:0 0 .25rem .25rem;position:absolute;top:100%;left:0;width:100%;z-index:20;margin-top:-1px;min-width:300px}.ui-filter-multiselect>.dropdown-options>.options-container{display:inherit;position:initial;font-family:inherit;background-color:inherit;box-shadow:none;height:auto;width:auto;color:inherit;font-size:inherit;letter-spacing:inherit;line-height:inherit;padding:inherit;border-radius:inherit}.ui-filter-multiselect>.dropdown-options .toolbar{padding:3px;border-bottom:1px solid #ced4da;background-color:#f8f9fa}.ui-filter-multiselect>.dropdown-options .toolbar input[type=text]{background-color:transparent;border:0;padding:.375rem .55rem;box-shadow:none!important;min-width:0}.ui-filter-multiselect>.dropdown-options ul{max-height:300px;overflow-y:scroll;overflow-x:hidden;margin:0;padding:0}.ui-filter-multiselect>.dropdown-options ul li{list-style:none;border-bottom:1px solid #ced4da}.ui-filter-multiselect>.dropdown-options ul li>.checkbox{background-color:#f0f0f0;border-right:1px solid #ced4da;padding:12px 15px;display:flex;align-items:center}.ui-filter-multiselect>.dropdown-options ul li>.checkbox input[type=checkbox]{width:17px;height:17px}.ui-filter-multiselect>.dropdown-options ul li>span{cursor:pointer;padding:8px 0}.ui-filter-multiselect>.dropdown-options ul li.selected{color:#007bff}.ui-filter-multiselect>.dropdown-options ul li:hover{background-color:#f9f9f9}.ui-filter-multiselect>.dropdown-options ul li:last-child{border-bottom:0}.ui-filter-multiselect>.dropdown-options .empty-results{font-style:italic;padding:12px;display:block;color:#6b6b6b}.ui-filter-multiselect>.dropdown-options.drop-right{left:inherit;right:0}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }, { kind: "directive", type: i4.AutoFocusDirective, selector: "[auto-focus]" }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }, { kind: "pipe", type: i5.SearchByPipe, name: "searchBy" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FilterMultiselectComponent, decorators: [{
            type: Component,
            args: [{ selector: 'filter-multiselect', providers: [{
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: FilterMultiselectComponent,
                            multi: true
                        }], template: "<div [id]=\"identifier\" class=\"ui-filter-multiselect\">\n    <input type=\"hidden\" [(ngModel)]=\"value\" />\n\n    <div class=\"combobox d-flex align-items-center justify-content-between\" \n        [ngClass]=\"{\n            'open': showOptions, \n            'disabled': disabled,\n            'has-value': value?.length > 0\n        }\"\n        (click)=\"ToggleDropDown($event)\" (keyup)=\"OnComboPressed($event)\" tabindex=\"0\">\n\n        <span class=\"mr-2\" *ngIf=\"value?.length > 0\"><b>{{label}}</b>: </span>\n\n        <span *ngIf=\"!value || value.length == 0\">{{label}}</span>\n\n        <div *ngIf=\"value?.length > 0\" class=\"selected-items d-flex align-items-center\">\n            <span *ngFor=\"let item of value | slice:0:1; let i = index;\">\n                <small class=\"text-muted text-truncate ml-1\">{{item[displayTextProperty]}}</small>\n            </span>\n            <small class=\"text-muted\" *ngIf=\"value.length > 1\">... (+{{value.length - 1}})</small>\n        </div>\n\n        <i class=\"fa\" [ngClass]=\"{'fa-angle-down': !showOptions, 'fa-angle-up': showOptions}\"></i>\n    </div>\n\n    <div class=\"dropdown-options shadow fadeInDown\" *ngIf=\"showOptions\" (clickOutside)=\"ToggleDropDown($event, false)\" \n        [ngClass]=\"{\n            'drop-right': dropRight\n        }\">\n        \n        <div class=\"options-container\" *ngIf=\"options?.length > 0\">\n            <div class=\"toolbar d-flex align-items-center\">\n                <input type=\"text\" class=\"form-control flex-grow-1\" name=\"{{identifier}}-search\" [(ngModel)]=\"search\" placeholder=\"{{searchPlaceholder}}\" auto-focus />\n                <button type=\"button\" class=\"btn btn-light ml-1 flex-shrink-0\" (click)=\"ToggleAllItemsSelection(true, true)\" [disabled]=\"disabled\"><i class=\"fa fa-check-square\"></i> {{selectAllButtonLabel}}</button>\n                <button type=\"button\" class=\"btn btn-light ml-1 flex-shrink-0\" (click)=\"ToggleAllItemsSelection(false, true)\" [disabled]=\"disabled\"><i class=\"fa fa-eraser\"></i> {{clearSelectionButtonLabel}}</button>\n            </div>\n\n            <ul>\n                <li class=\"d-flex\" *ngFor=\"let item of options | searchBy : displayTextProperty : search\" [ngClass]=\"{'selected': item.selected}\">\n                    <div class=\"checkbox mr-3 flex-shrink-0\">\n                        <input type=\"checkbox\" name=\"{{identifier}}-option\" [(ngModel)]=\"item.selected\" (change)=\"ItemSelectedCheckChanged()\" [disabled]=\"disabled\" />\n                    </div>\n                    <span class=\"link\" (click)=\"ToggleItemSelected(item)\">{{item[displayTextProperty]}}</span>\n                </li>\n            </ul>\n\n            <small class=\"empty-results\" *ngIf=\"(options | searchBy : displayTextProperty : search).length == 0\">{{emptyMessage}}</small>\n        </div>\n\n        <small class=\"empty-results\" *ngIf=\"!options || options.length == 0\">{{emptyMessage}}</small>\n    </div>\n</div>", styles: ["@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-5%,0)}to{opacity:1;transform:translateZ(0)}}.fadeInDown{animation-name:fadeInDown;animation-duration:.35s;animation-fill-mode:both}.ui-filter-multiselect{position:relative}.ui-filter-multiselect *{-webkit-user-select:none;user-select:none}.ui-filter-multiselect>.combobox{outline:none;padding:.375rem .475rem;width:-moz-fit-content;width:fit-content}.ui-filter-multiselect>.combobox>span{color:#6c757d;font-size:1rem;line-height:1.5}.ui-filter-multiselect>.combobox>i{color:#495057;font-size:14px;margin-left:10px}.ui-filter-multiselect>.combobox .selected-items{margin-left:-5px;overflow:hidden}.ui-filter-multiselect>.combobox .selected-items .badge{margin-right:3px;line-height:1;color:#888;background-color:#e0e0e0;border-bottom:2px solid #ccc;border-left:2px solid #ccc;padding:5px 7px 4px}.ui-filter-multiselect>.combobox .selected-items .badge>span{display:inline-block;max-width:150px}.ui-filter-multiselect>.combobox .selected-items .badge:hover{cursor:pointer;color:#fff;background-color:#007bff;border-bottom:2px solid #00559a;border-left:2px solid #00559a}.ui-filter-multiselect>.combobox.open{border-radius:.25rem .25rem 0 0}.ui-filter-multiselect>.combobox.disabled{background-color:#e9ecef;border-color:#ced4da}.ui-filter-multiselect>.combobox.has-validations.is-invalid{border-color:#dc3545}.ui-filter-multiselect>.combobox.has-validations.is-invalid.open{box-shadow:0 0 0 .2rem #dc354540}.ui-filter-multiselect>.combobox.has-validations.is-valid{border-color:#28a745}.ui-filter-multiselect>.combobox.has-validations.is-valid.open{box-shadow:0 0 0 .2rem #28a74540}.ui-filter-multiselect .combobox:hover{cursor:pointer}.ui-filter-multiselect>.dropdown-options{background-color:#fff;border:1px solid #ced4da;border-radius:0 0 .25rem .25rem;position:absolute;top:100%;left:0;width:100%;z-index:20;margin-top:-1px;min-width:300px}.ui-filter-multiselect>.dropdown-options>.options-container{display:inherit;position:initial;font-family:inherit;background-color:inherit;box-shadow:none;height:auto;width:auto;color:inherit;font-size:inherit;letter-spacing:inherit;line-height:inherit;padding:inherit;border-radius:inherit}.ui-filter-multiselect>.dropdown-options .toolbar{padding:3px;border-bottom:1px solid #ced4da;background-color:#f8f9fa}.ui-filter-multiselect>.dropdown-options .toolbar input[type=text]{background-color:transparent;border:0;padding:.375rem .55rem;box-shadow:none!important;min-width:0}.ui-filter-multiselect>.dropdown-options ul{max-height:300px;overflow-y:scroll;overflow-x:hidden;margin:0;padding:0}.ui-filter-multiselect>.dropdown-options ul li{list-style:none;border-bottom:1px solid #ced4da}.ui-filter-multiselect>.dropdown-options ul li>.checkbox{background-color:#f0f0f0;border-right:1px solid #ced4da;padding:12px 15px;display:flex;align-items:center}.ui-filter-multiselect>.dropdown-options ul li>.checkbox input[type=checkbox]{width:17px;height:17px}.ui-filter-multiselect>.dropdown-options ul li>span{cursor:pointer;padding:8px 0}.ui-filter-multiselect>.dropdown-options ul li.selected{color:#007bff}.ui-filter-multiselect>.dropdown-options ul li:hover{background-color:#f9f9f9}.ui-filter-multiselect>.dropdown-options ul li:last-child{border-bottom:0}.ui-filter-multiselect>.dropdown-options .empty-results{font-style:italic;padding:12px;display:block;color:#6b6b6b}.ui-filter-multiselect>.dropdown-options.drop-right{left:inherit;right:0}\n"] }]
        }], ctorParameters: function () { return [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NG_VALIDATORS]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NG_ASYNC_VALIDATORS]
                }] }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [INPUT_FORMS_CONFIG]
                }] }, { type: i0.IterableDiffers }]; }, propDecorators: { placeholder: [{
                type: Input
            }], searchPlaceholder: [{
                type: Input
            }], displayTextProperty: [{
                type: Input
            }], valueProperty: [{
                type: Input
            }], emptyMessage: [{
                type: Input
            }], selectAllButtonLabel: [{
                type: Input
            }], clearSelectionButtonLabel: [{
                type: Input
            }], dropRight: [{
                type: Input
            }], onChange: [{
                type: Output
            }], model: [{
                type: ViewChild,
                args: [NgModel, { static: true }]
            }], options: [{
                type: Input,
                args: ['options']
            }] } });
//# sourceMappingURL=data:application/json;base64, 