blob: d6dabb6ef75bd28b3422cc4036bbcbc6db243caf [file] [log] [blame]
/**
******************************************************************************
* Copyright © 2017-2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
******************************************************************************
*/
import { Component, OnInit, NgModule, OnChanges, ViewEncapsulation, forwardRef, Input, Output, EventEmitter, ElementRef, AfterViewInit, Pipe, PipeTransform } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { ListItem, MyException } from './multiselect.model';
import { DropdownSettings } from './multiselect.interface';
import { ClickOutsideDirective } from './clickOutside';
import { ListFilterPipe } from './list-filter';
export const DROPDOWN_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AngularMultiSelectComponent),
multi: true
};
const noop = () => {
};
@Component({
selector: 'multiselect',
templateUrl: './multiselect.component.html',
host: { '[class]': 'defaultSettings.classes' },
styleUrls: ['./multiselect.component.scss'],
providers: [DROPDOWN_CONTROL_VALUE_ACCESSOR]
})
export class AngularMultiSelectComponent implements OnInit, ControlValueAccessor {
@Input()
data: Array<ListItem>;
@Input()
settings: DropdownSettings;
@Output('onSelect')
onSelect: EventEmitter<ListItem> = new EventEmitter<ListItem>();
@Output('onDeSelect')
onDeSelect: EventEmitter<ListItem> = new EventEmitter<ListItem>();
@Output('onSelectAll')
onSelectAll: EventEmitter<Array<ListItem>> = new EventEmitter<Array<ListItem>>();
@Output('onDeSelectAll')
onDeSelectAll: EventEmitter<Array<ListItem>> = new EventEmitter<Array<ListItem>>();
private onTouchedCallback: () => void = noop;
private onChangeCallback: (_: any) => void = noop;
public selectedItems: Array<ListItem>;
public isActive= false;
public isSelectAll = false;
filter: ListItem = new ListItem();
defaultSettings: DropdownSettings = {
singleSelection: false,
text: 'Select',
enableCheckAll: true,
selectAllText: 'Select All',
unSelectAllText: 'UnSelect All',
enableSearchFilter: false,
maxHeight: 300,
badgeShowLimit: 999999999999,
classes: ''
};
constructor() {
}
ngOnInit() {
this.settings = Object.assign(this.defaultSettings, this.settings);
}
onItemClick(item: ListItem, index) {
const found = this.isSelected(item);
const limit = this.selectedItems.length < this.settings.limitSelection ? true : false;
if (!found) {
if (this.settings.limitSelection) {
if (limit) {
this.addSelected(item);
this.onSelect.emit(item);
}
} else {
this.addSelected(item);
this.onSelect.emit(item);
}
} else {
this.removeSelected(item);
this.onDeSelect.emit(item);
}
if (this.isSelectAll || this.data.length > this.selectedItems.length) {
this.isSelectAll = false;
}
if (this.data.length === this.selectedItems.length) {
this.isSelectAll = true;
}
}
writeValue(value: any) {
if (value !== undefined && value !== null) {
if (this.settings.singleSelection) {
try {
if (value.length > 1) {
this.selectedItems = [value[0]];
throw new MyException(404, { 'msg': 'Single Selection Mode, Selected Items cannot have more than one item.' });
} else {
this.selectedItems = value;
}
} catch (e) {
console.error(e.body.msg);
}
} else {
if (this.settings.limitSelection) {
this.selectedItems = value.splice(0, this.settings.limitSelection);
} else {
this.selectedItems = value;
}
}
} else {
this.selectedItems = [];
}
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
trackByFn(index, item) {
return item.id;
}
isSelected(clickedItem: ListItem) {
let found = false;
this.selectedItems.forEach(item => {
if (clickedItem.id === item.id) {
found = true;
}
});
return found;
}
addSelected(item: ListItem) {
if (this.settings.singleSelection) {
this.selectedItems = [];
this.selectedItems.push(item);
} else {
this.selectedItems.push(item);
}
this.onChangeCallback(this.selectedItems);
}
removeSelected(clickedItem: ListItem) {
this.selectedItems.forEach(item => {
if (clickedItem.id === item.id) {
this.selectedItems.splice(this.selectedItems.indexOf(item), 1);
}
});
this.onChangeCallback(this.selectedItems);
}
toggleDropdown(evt) {
this.isActive = !this.isActive;
evt.preventDefault();
}
closeDropdown() {
this.isActive = false;
}
toggleSelectAll() {
if (!this.isSelectAll) {
this.selectedItems = [];
this.selectedItems = this.data.slice();
this.isSelectAll = true;
this.onChangeCallback(this.selectedItems);
this.onSelectAll.emit(this.selectedItems);
} else {
this.selectedItems = [];
this.isSelectAll = false;
this.onChangeCallback(this.selectedItems);
this.onDeSelectAll.emit(this.selectedItems);
}
}
}