import {NgModule,Component,ElementRef,AfterViewChecked,AfterContentInit,Input,Output,ContentChildren,QueryList,TemplateRef,EventEmitter,ViewChild} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ButtonModule} from '../button/button';
import {SharedModule,PrimeTemplate} from '../common/shared';
import {DomHandler} from '../dom/domhandler';
import {ObjectUtils} from '../utils/objectutils';
@Component({
selector: 'p-orderList',
template: `
`,
providers: [DomHandler,ObjectUtils]
})
export class OrderList implements AfterViewChecked,AfterContentInit {
@Input() header: string;
@Input() style: any;
@Input() styleClass: string;
@Input() listStyle: any;
@Input() responsive: boolean;
@Input() filterBy: string;
@Input() filterPlaceholder: string;
@Input() metaKeySelection: boolean = true;
@Input() dragdrop: boolean;
@Input() dragdropScope: string;
@Input() trackBy: Function = (index: number, item: any) => item;
@Output() onReorder: EventEmitter = new EventEmitter();
@Output() onSelectionChange: EventEmitter = new EventEmitter();
@Output() onFilterEvent: EventEmitter = new EventEmitter();
@ViewChild('listelement') listViewChild: ElementRef;
@ContentChildren(PrimeTemplate) templates: QueryList;
public itemTemplate: TemplateRef;
selectedItems: any[];
movedUp: boolean;
movedDown: boolean;
listContainer: any;
itemTouched: boolean;
draggedItemIndex: number;
dragOverItemIndex: number;
dragging: boolean;
public filterValue: string;
public visibleOptions: any[];
public _value: any[];
constructor(public el: ElementRef, public domHandler: DomHandler, public objectUtils: ObjectUtils) {}
ngAfterViewInit() {
this.listContainer = this.domHandler.findSingle(this.el.nativeElement, 'ul.ui-orderlist-list');
}
ngAfterContentInit() {
this.templates.forEach((item) => {
switch(item.getType()) {
case 'item':
this.itemTemplate = item.template;
break;
default:
this.itemTemplate = item.template;
break;
}
});
}
ngAfterViewChecked() {
if(this.movedUp||this.movedDown) {
let listItems = this.domHandler.find(this.listContainer, 'li.ui-state-highlight');
let listItem;
if(listItems.length > 0) {
if(this.movedUp)
listItem = listItems[0];
else
listItem = listItems[listItems.length - 1];
this.domHandler.scrollInView(this.listContainer, listItem);
}
this.movedUp = false;
this.movedDown = false;
}
}
get value(): any[] {
return this._value;
}
@Input() set value(val:any[]) {
this._value = val;
if(this.filterValue) {
this.filter();
}
}
onItemClick(event, item, index) {
let selectedIndex = this.objectUtils.findIndexInList(item, this.selectedItems);
let selected = (selectedIndex != -1);
let metaSelection = this.itemTouched ? false : this.metaKeySelection;
if(metaSelection) {
let metaKey = (event.metaKey||event.ctrlKey);
if(selected && metaKey) {
this.selectedItems.splice(selectedIndex, 1);
}
else {
this.selectedItems = (metaKey) ? this.selectedItems||[] : [];
this.selectItem(item, index);
}
}
else {
if(selected) {
this.selectedItems.splice(selectedIndex, 1);
}
else {
this.selectedItems = this.selectedItems||[];
this.selectItem(item, index);
}
}
this.onSelectionChange.emit({originalEvent:event, value:this.selectedItems});
this.itemTouched = false;
}
selectItem(item, index) {
this.selectedItems = this.selectedItems||[];
this.objectUtils.insertIntoOrderedArray(item, index, this.selectedItems, this.value);
}
onFilterKeyup(event) {
this.filterValue = event.target.value.trim().toLowerCase();
this.filter();
this.onFilterEvent.emit({
originalEvent: event,
value: this.visibleOptions
});
}
filter() {
let searchFields: string[] = this.filterBy.split(',');
this.visibleOptions = this.objectUtils.filter(this.value, searchFields, this.filterValue);
}
isItemVisible(item: any): boolean {
if(this.filterValue && this.filterValue.trim().length) {
for(let i = 0; i < this.visibleOptions.length; i++) {
if(item == this.visibleOptions[i]) {
return true;
}
}
}
else {
return true;
}
}
onItemTouchEnd(event) {
this.itemTouched = true;
}
isSelected(item: any) {
return this.objectUtils.findIndexInList(item, this.selectedItems) != -1;
}
moveUp(event,listElement) {
if(this.selectedItems) {
for(let i = 0; i < this.selectedItems.length; i++) {
let selectedItem = this.selectedItems[i];
let selectedItemIndex: number = this.objectUtils.findIndexInList(selectedItem, this.value);
if(selectedItemIndex != 0) {
let movedItem = this.value[selectedItemIndex];
let temp = this.value[selectedItemIndex-1];
this.value[selectedItemIndex-1] = movedItem;
this.value[selectedItemIndex] = temp;
}
else {
break;
}
}
this.movedUp = true;
this.onReorder.emit(event);
}
}
moveTop(event,listElement) {
if(this.selectedItems) {
for(let i = 0; i < this.selectedItems.length; i++) {
let selectedItem = this.selectedItems[i];
let selectedItemIndex: number = this.objectUtils.findIndexInList(selectedItem, this.value);
if(selectedItemIndex != 0) {
let movedItem = this.value.splice(selectedItemIndex,1)[0];
this.value.unshift(movedItem);
listElement.scrollTop = 0;
}
else {
break;
}
}
this.onReorder.emit(event);
listElement.scrollTop = 0;
}
}
moveDown(event,listElement) {
if(this.selectedItems) {
for(let i = this.selectedItems.length - 1; i >= 0; i--) {
let selectedItem = this.selectedItems[i];
let selectedItemIndex: number = this.objectUtils.findIndexInList(selectedItem, this.value);
if(selectedItemIndex != (this.value.length - 1)) {
let movedItem = this.value[selectedItemIndex];
let temp = this.value[selectedItemIndex+1];
this.value[selectedItemIndex+1] = movedItem;
this.value[selectedItemIndex] = temp;
}
else {
break;
}
}
this.movedDown = true;
this.onReorder.emit(event);
}
}
moveBottom(event,listElement) {
if(this.selectedItems) {
for(let i = this.selectedItems.length - 1; i >= 0; i--) {
let selectedItem = this.selectedItems[i];
let selectedItemIndex: number = this.objectUtils.findIndexInList(selectedItem, this.value);
if(selectedItemIndex != (this.value.length - 1)) {
let movedItem = this.value.splice(selectedItemIndex,1)[0];
this.value.push(movedItem);
}
else {
break;
}
}
this.onReorder.emit(event);
listElement.scrollTop = listElement.scrollHeight;
}
}
onDragStart(event: DragEvent, index: number) {
this.dragging = true;
this.draggedItemIndex = index;
if(this.dragdropScope) {
event.dataTransfer.setData("text", this.dragdropScope);
}
}
onDragOver(event: DragEvent, index: number) {
if(this.draggedItemIndex !== index && this.draggedItemIndex + 1 !== index) {
this.dragOverItemIndex = index;
event.preventDefault();
}
}
onDragLeave(event: DragEvent) {
this.dragOverItemIndex = null;
}
onDrop(event: DragEvent, index: number) {
let dropIndex = (this.draggedItemIndex > index) ? index : (index === 0) ? 0 : index - 1;
this.objectUtils.reorderArray(this.value, this.draggedItemIndex, dropIndex);
this.dragOverItemIndex = null;
this.onReorder.emit(event);
event.preventDefault();
}
onDragEnd(event: DragEvent) {
this.dragging = false;
}
onListMouseMove(event: MouseEvent) {
if(this.dragging) {
let offsetY = this.listViewChild.nativeElement.getBoundingClientRect().top + document.body.scrollTop;
let bottomDiff = (offsetY + this.listViewChild.nativeElement.clientHeight) - event.pageY;
let topDiff = (event.pageY - offsetY);
if(bottomDiff < 25 && bottomDiff > 0)
this.listViewChild.nativeElement.scrollTop += 15;
else if(topDiff < 25 && topDiff > 0)
this.listViewChild.nativeElement.scrollTop -= 15;
}
}
}
@NgModule({
imports: [CommonModule,ButtonModule,SharedModule],
exports: [OrderList,SharedModule],
declarations: [OrderList]
})
export class OrderListModule { }