UNPKG

15.9 kBJavaScriptView Raw
1import { EventEmitter, Component, ChangeDetectionStrategy, ViewEncapsulation, ElementRef, ChangeDetectorRef, Input, Output, ViewChild, ContentChildren, NgModule } from '@angular/core';
2import { CommonModule } from '@angular/common';
3import { ButtonModule } from 'primeng/button';
4import { PrimeTemplate, SharedModule } from 'primeng/api';
5import { DomHandler } from 'primeng/dom';
6import { ObjectUtils, FilterUtils } from 'primeng/utils';
7import { RippleModule } from 'primeng/ripple';
8
9class OrderList {
10 constructor(el, cd) {
11 this.el = el;
12 this.cd = cd;
13 this.metaKeySelection = true;
14 this.controlsPosition = 'left';
15 this.filterMatchMode = "contains";
16 this.selectionChange = new EventEmitter();
17 this.trackBy = (index, item) => item;
18 this.onReorder = new EventEmitter();
19 this.onSelectionChange = new EventEmitter();
20 this.onFilterEvent = new EventEmitter();
21 }
22 get selection() {
23 return this._selection;
24 }
25 set selection(val) {
26 this._selection = val;
27 }
28 ngAfterContentInit() {
29 this.templates.forEach((item) => {
30 switch (item.getType()) {
31 case 'item':
32 this.itemTemplate = item.template;
33 break;
34 default:
35 this.itemTemplate = item.template;
36 break;
37 }
38 });
39 }
40 ngAfterViewChecked() {
41 if (this.movedUp || this.movedDown) {
42 let listItems = DomHandler.find(this.listViewChild.nativeElement, 'li.p-highlight');
43 let listItem;
44 if (listItems.length > 0) {
45 if (this.movedUp)
46 listItem = listItems[0];
47 else
48 listItem = listItems[listItems.length - 1];
49 DomHandler.scrollInView(this.listViewChild.nativeElement, listItem);
50 }
51 this.movedUp = false;
52 this.movedDown = false;
53 }
54 }
55 get value() {
56 return this._value;
57 }
58 set value(val) {
59 this._value = val;
60 if (this.filterValue) {
61 this.filter();
62 }
63 }
64 onItemClick(event, item, index) {
65 this.itemTouched = false;
66 let selectedIndex = ObjectUtils.findIndexInList(item, this.selection);
67 let selected = (selectedIndex != -1);
68 let metaSelection = this.itemTouched ? false : this.metaKeySelection;
69 if (metaSelection) {
70 let metaKey = (event.metaKey || event.ctrlKey || event.shiftKey);
71 if (selected && metaKey) {
72 this._selection = this._selection.filter((val, index) => index !== selectedIndex);
73 }
74 else {
75 this._selection = (metaKey) ? this._selection ? [...this._selection] : [] : [];
76 ObjectUtils.insertIntoOrderedArray(item, index, this._selection, this.value);
77 }
78 }
79 else {
80 if (selected) {
81 this._selection = this._selection.filter((val, index) => index !== selectedIndex);
82 }
83 else {
84 this._selection = this._selection ? [...this._selection] : [];
85 ObjectUtils.insertIntoOrderedArray(item, index, this._selection, this.value);
86 }
87 }
88 //binding
89 this.selectionChange.emit(this._selection);
90 //event
91 this.onSelectionChange.emit({ originalEvent: event, value: this._selection });
92 }
93 onFilterKeyup(event) {
94 this.filterValue = event.target.value.trim().toLocaleLowerCase(this.filterLocale);
95 this.filter();
96 this.onFilterEvent.emit({
97 originalEvent: event,
98 value: this.visibleOptions
99 });
100 }
101 filter() {
102 let searchFields = this.filterBy.split(',');
103 this.visibleOptions = FilterUtils.filter(this.value, searchFields, this.filterValue, this.filterMatchMode, this.filterLocale);
104 }
105 isItemVisible(item) {
106 if (this.filterValue && this.filterValue.trim().length) {
107 for (let i = 0; i < this.visibleOptions.length; i++) {
108 if (item == this.visibleOptions[i]) {
109 return true;
110 }
111 }
112 }
113 else {
114 return true;
115 }
116 }
117 onItemTouchEnd(event) {
118 this.itemTouched = true;
119 }
120 isSelected(item) {
121 return ObjectUtils.findIndexInList(item, this.selection) != -1;
122 }
123 moveUp(event) {
124 if (this.selection) {
125 for (let i = 0; i < this.selection.length; i++) {
126 let selectedItem = this.selection[i];
127 let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, this.value);
128 if (selectedItemIndex != 0) {
129 let movedItem = this.value[selectedItemIndex];
130 let temp = this.value[selectedItemIndex - 1];
131 this.value[selectedItemIndex - 1] = movedItem;
132 this.value[selectedItemIndex] = temp;
133 }
134 else {
135 break;
136 }
137 }
138 this.movedUp = true;
139 this.onReorder.emit(event);
140 }
141 }
142 moveTop(event) {
143 if (this.selection) {
144 for (let i = this.selection.length - 1; i >= 0; i--) {
145 let selectedItem = this.selection[i];
146 let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, this.value);
147 if (selectedItemIndex != 0) {
148 let movedItem = this.value.splice(selectedItemIndex, 1)[0];
149 this.value.unshift(movedItem);
150 }
151 else {
152 break;
153 }
154 }
155 this.onReorder.emit(event);
156 this.listViewChild.nativeElement.scrollTop = 0;
157 }
158 }
159 moveDown(event) {
160 if (this.selection) {
161 for (let i = this.selection.length - 1; i >= 0; i--) {
162 let selectedItem = this.selection[i];
163 let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, this.value);
164 if (selectedItemIndex != (this.value.length - 1)) {
165 let movedItem = this.value[selectedItemIndex];
166 let temp = this.value[selectedItemIndex + 1];
167 this.value[selectedItemIndex + 1] = movedItem;
168 this.value[selectedItemIndex] = temp;
169 }
170 else {
171 break;
172 }
173 }
174 this.movedDown = true;
175 this.onReorder.emit(event);
176 }
177 }
178 moveBottom(event) {
179 if (this.selection) {
180 for (let i = 0; i < this.selection.length; i++) {
181 let selectedItem = this.selection[i];
182 let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, this.value);
183 if (selectedItemIndex != (this.value.length - 1)) {
184 let movedItem = this.value.splice(selectedItemIndex, 1)[0];
185 this.value.push(movedItem);
186 }
187 else {
188 break;
189 }
190 }
191 this.onReorder.emit(event);
192 this.listViewChild.nativeElement.scrollTop = this.listViewChild.nativeElement.scrollHeight;
193 }
194 }
195 onDragStart(event, index) {
196 event.dataTransfer.setData('text', 'b'); // For firefox
197 event.target.blur();
198 this.dragging = true;
199 this.draggedItemIndex = index;
200 }
201 onDragOver(event, index) {
202 if (this.dragging && this.draggedItemIndex !== index && this.draggedItemIndex + 1 !== index) {
203 this.dragOverItemIndex = index;
204 event.preventDefault();
205 }
206 }
207 onDragLeave(event) {
208 this.dragOverItemIndex = null;
209 }
210 onDrop(event, index) {
211 let dropIndex = (this.draggedItemIndex > index) ? index : (index === 0) ? 0 : index - 1;
212 ObjectUtils.reorderArray(this.value, this.draggedItemIndex, dropIndex);
213 this.dragOverItemIndex = null;
214 this.onReorder.emit(event);
215 event.preventDefault();
216 }
217 onDragEnd(event) {
218 this.dragging = false;
219 }
220 onListMouseMove(event) {
221 if (this.dragging) {
222 let offsetY = this.listViewChild.nativeElement.getBoundingClientRect().top + document.body.scrollTop;
223 let bottomDiff = (offsetY + this.listViewChild.nativeElement.clientHeight) - event.pageY;
224 let topDiff = (event.pageY - offsetY);
225 if (bottomDiff < 25 && bottomDiff > 0)
226 this.listViewChild.nativeElement.scrollTop += 15;
227 else if (topDiff < 25 && topDiff > 0)
228 this.listViewChild.nativeElement.scrollTop -= 15;
229 }
230 }
231 onItemKeydown(event, item, index) {
232 let listItem = event.currentTarget;
233 switch (event.which) {
234 //down
235 case 40:
236 var nextItem = this.findNextItem(listItem);
237 if (nextItem) {
238 nextItem.focus();
239 }
240 event.preventDefault();
241 break;
242 //up
243 case 38:
244 var prevItem = this.findPrevItem(listItem);
245 if (prevItem) {
246 prevItem.focus();
247 }
248 event.preventDefault();
249 break;
250 //enter
251 case 13:
252 this.onItemClick(event, item, index);
253 event.preventDefault();
254 break;
255 }
256 }
257 findNextItem(item) {
258 let nextItem = item.nextElementSibling;
259 if (nextItem)
260 return !DomHandler.hasClass(nextItem, 'p-orderlist-item') || DomHandler.isHidden(nextItem) ? this.findNextItem(nextItem) : nextItem;
261 else
262 return null;
263 }
264 findPrevItem(item) {
265 let prevItem = item.previousElementSibling;
266 if (prevItem)
267 return !DomHandler.hasClass(prevItem, 'p-orderlist-item') || DomHandler.isHidden(prevItem) ? this.findPrevItem(prevItem) : prevItem;
268 else
269 return null;
270 }
271}
272OrderList.decorators = [
273 { type: Component, args: [{
274 selector: 'p-orderList',
275 template: `
276 <div [ngClass]="{'p-orderlist p-component': true, 'p-orderlist-controls-left': controlsPosition === 'left',
277 'p-orderlist-controls-right': controlsPosition === 'right'}" [ngStyle]="style" [class]="styleClass">
278 <div class="p-orderlist-controls">
279 <button type="button" pButton pRipple icon="pi pi-angle-up" (click)="moveUp($event)"></button>
280 <button type="button" pButton pRipple icon="pi pi-angle-double-up" (click)="moveTop($event)"></button>
281 <button type="button" pButton pRipple icon="pi pi-angle-down" (click)="moveDown($event)"></button>
282 <button type="button" pButton pRipple icon="pi pi-angle-double-down" (click)="moveBottom($event)"></button>
283 </div>
284 <div class="p-orderlist-list-container">
285 <div class="p-orderlist-header" *ngIf="header">
286 <div class="p-orderlist-title">{{header}}</div>
287 </div>
288 <div class="p-orderlist-filter-container" *ngIf="filterBy">
289 <div class="p-orderlist-filter">
290 <input type="text" role="textbox" (keyup)="onFilterKeyup($event)" class="p-orderlist-filter-input p-inputtext p-component" [attr.placeholder]="filterPlaceholder" [attr.aria-label]="ariaFilterLabel">
291 <span class="p-orderlist-filter-icon pi pi-search"></span>
292 </div>
293 </div>
294 <ul #listelement class="p-orderlist-list" [ngStyle]="listStyle" (dragover)="onListMouseMove($event)">
295 <ng-template ngFor [ngForTrackBy]="trackBy" let-item [ngForOf]="value" let-i="index" let-l="last">
296 <li class="p-orderlist-droppoint" *ngIf="dragdrop && isItemVisible(item)" (dragover)="onDragOver($event, i)" (drop)="onDrop($event, i)" (dragleave)="onDragLeave($event)"
297 [ngClass]="{'p-orderlist-droppoint-highlight': (i === dragOverItemIndex)}"></li>
298 <li class="p-orderlist-item" tabindex="0" [ngClass]="{'p-highlight':isSelected(item)}" pRipple
299 (click)="onItemClick($event,item,i)" (touchend)="onItemTouchEnd($event)" (keydown)="onItemKeydown($event,item,i)"
300 [style.display]="isItemVisible(item) ? 'block' : 'none'" role="option" [attr.aria-selected]="isSelected(item)"
301 [attr.draggable]="dragdrop" (dragstart)="onDragStart($event, i)" (dragend)="onDragEnd($event)">
302 <ng-container *ngTemplateOutlet="itemTemplate; context: {$implicit: item, index: i}"></ng-container>
303 </li>
304 <li class="p-orderlist-droppoint" *ngIf="dragdrop && l" (dragover)="onDragOver($event, i + 1)" (drop)="onDrop($event, i + 1)" (dragleave)="onDragLeave($event)"
305 [ngClass]="{'p-orderlist-droppoint-highlight': (i + 1 === dragOverItemIndex)}"></li>
306 </ng-template>
307 </ul>
308 </div>
309 </div>
310 `,
311 changeDetection: ChangeDetectionStrategy.OnPush,
312 encapsulation: ViewEncapsulation.None,
313 styles: [".p-orderlist,.p-orderlist-controls{display:-ms-flexbox;display:flex}.p-orderlist-controls{-ms-flex-direction:column;-ms-flex-pack:center;flex-direction:column;justify-content:center}.p-orderlist-list-container{-ms-flex:1 1 auto;flex:1 1 auto}.p-orderlist-list{list-style-type:none;margin:0;max-height:24rem;min-height:12rem;overflow:auto;padding:0}.p-orderlist-item{cursor:pointer;overflow:hidden;position:relative}.p-orderlist.p-state-disabled .p-button,.p-orderlist.p-state-disabled .p-orderlist-item{cursor:default}.p-orderlist.p-state-disabled .p-orderlist-list{overflow:hidden}.p-orderlist-filter{position:relative}.p-orderlist-filter-icon{margin-top:-.5rem;position:absolute;top:50%}.p-orderlist-filter-input{width:100%}.p-orderlist-controls-right .p-orderlist-controls{-ms-flex-order:2;order:2}.p-orderlist-controls-right .p-orderlist-list-container{-ms-flex-order:1;order:1}.p-orderlist-droppoint{height:6px}"]
314 },] }
315];
316OrderList.ctorParameters = () => [
317 { type: ElementRef },
318 { type: ChangeDetectorRef }
319];
320OrderList.propDecorators = {
321 header: [{ type: Input }],
322 style: [{ type: Input }],
323 styleClass: [{ type: Input }],
324 listStyle: [{ type: Input }],
325 responsive: [{ type: Input }],
326 filterBy: [{ type: Input }],
327 filterPlaceholder: [{ type: Input }],
328 filterLocale: [{ type: Input }],
329 metaKeySelection: [{ type: Input }],
330 dragdrop: [{ type: Input }],
331 controlsPosition: [{ type: Input }],
332 ariaFilterLabel: [{ type: Input }],
333 filterMatchMode: [{ type: Input }],
334 selectionChange: [{ type: Output }],
335 trackBy: [{ type: Input }],
336 onReorder: [{ type: Output }],
337 onSelectionChange: [{ type: Output }],
338 onFilterEvent: [{ type: Output }],
339 listViewChild: [{ type: ViewChild, args: ['listelement',] }],
340 templates: [{ type: ContentChildren, args: [PrimeTemplate,] }],
341 selection: [{ type: Input }],
342 value: [{ type: Input }]
343};
344class OrderListModule {
345}
346OrderListModule.decorators = [
347 { type: NgModule, args: [{
348 imports: [CommonModule, ButtonModule, SharedModule, RippleModule],
349 exports: [OrderList, SharedModule],
350 declarations: [OrderList]
351 },] }
352];
353
354/**
355 * Generated bundle index. Do not edit.
356 */
357
358export { OrderList, OrderListModule };
359//# sourceMappingURL=primeng-orderlist.js.map