ngx-sortable
Version:
An angular 4 and above component for sorting list supporting drag and drop sort.
214 lines (207 loc) • 14.4 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, TemplateRef, Component, Input, Output, ContentChild, HostListener, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
var CommandKey;
(function (CommandKey) {
CommandKey["CtrlKey"] = "ctrlKey";
CommandKey["ShiftKey"] = "shiftKey";
CommandKey["Altkey"] = "altKey";
CommandKey["MetaKey"] = "metaKey";
})(CommandKey || (CommandKey = {}));
class NgxSortableComponent {
constructor() {
this.items = [];
this.showHeader = true;
this.removeOnDropOutside = false;
this.dragStart = new EventEmitter();
this.dropped = new EventEmitter();
this.moveDown = new EventEmitter();
this.moveUp = new EventEmitter();
this.remove = new EventEmitter();
this.listStyle = {
height: "250px",
width: "300px",
dropZoneHeight: "50px",
};
this.listSorted = new EventEmitter();
this.commandKey = CommandKey.CtrlKey;
this.draggedIndex = -1;
this.onDragOverIndex = -1;
// console.log('Intializing...');
}
onArrowKeyDown($event) {
/** istanbul ignore else */
if (this.arrowKeySort) {
/** istanbul ignore else */
if ($event.key === "ArrowUp" && $event[this.commandKey]) {
this.onMoveUp($event);
}
/** istanbul ignore else */
if ($event.key === "ArrowDown" && $event[this.commandKey]) {
this.onMoveDown($event);
}
$event.preventDefault();
}
}
onDragEnd() {
if (this.removeOnDropOutside) {
this.onRemoveDrop();
}
else {
this.draggedIndex = -1;
this.onDragOverIndex = -1;
}
}
selectItem(item) {
this.selectedItem = item;
}
onMoveUp($event) {
const index = this.items.indexOf(this.selectedItem);
/** istanbul ignore else */
if (index === 0) {
return;
}
this.swapElements(index, index - 1);
this.moveUp.emit({
event: $event,
itemIndex: index,
newIndex: index - 1,
item: this.selectedItem,
});
this.listSorted.emit(this.items);
}
onMoveDown($event) {
const index = this.items.indexOf(this.selectedItem);
if (index === this.items.length - 1) {
return;
}
this.swapElements(index, index + 1);
this.moveDown.emit({
event: $event,
itemIndex: index,
newIndex: index + 1,
item: this.selectedItem,
});
this.listSorted.emit(this.items);
}
onDrop($event, index) {
// index is of the element on which the item is dropped
/** istanbul ignore else */
if (index === this.draggedIndex) {
this.draggedIndex = -1;
this.onDragOverIndex = -1;
return;
}
const dragIndex = this.draggedIndex;
this.handleDrop(index);
this.dropped.emit({
event: $event,
itemIndex: dragIndex,
newIndex: index,
item: this.selectedItem,
});
}
allowDrop($event, index) {
// index is of the item on which the item is currently hovered
this.onDragOverIndex = index;
$event.preventDefault();
}
onDragStart($event, index) {
this.selectItem(this.items[index]);
this.draggedIndex = index;
this.dragStart.emit({
event: $event,
itemIndex: index,
newIndex: -1,
item: this.selectedItem,
});
}
handleDrop(droppedIndex) {
const item = this.items[this.draggedIndex];
this.items.splice(this.draggedIndex, 1);
this.items.splice(droppedIndex, 0, item);
this.draggedIndex = -1;
this.onDragOverIndex = -1;
this.listSorted.emit(this.items);
}
swapElements(oldIndex, newIndex) {
const temp = this.items[oldIndex];
this.items[oldIndex] = this.items[newIndex];
this.items[newIndex] = temp;
}
onRemoveDrop() {
this.items.splice(this.draggedIndex, 1);
this.remove.emit({
item: this.selectedItem,
itemIndex: this.draggedIndex,
});
this.draggedIndex = -1;
this.onDragOverIndex = -1;
this.listSorted.emit(this.items);
}
}
NgxSortableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
NgxSortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: NgxSortableComponent, selector: "ngx-sortable", inputs: { items: "items", name: "name", showHeader: "showHeader", removeOnDropOutside: "removeOnDropOutside", listStyle: "listStyle", arrowKeySort: "arrowKeySort", commandKey: "commandKey" }, outputs: { dragStart: "dragStart", dropped: "dropped", moveDown: "moveDown", moveUp: "moveUp", remove: "remove", listSorted: "listSorted" }, host: { listeners: { "document:keydown": "onArrowKeyDown($event)", "document:dragend": "onDragEnd()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: "<div class=\"sortable-container\" [style.width]='listStyle.width'>\n <div class=\"sortable-header\" *ngIf=\"showHeader\">\n <label class=\"sortable-name\">{{name}}</label>\n <div class=\"sortable-buttons\">\n <button (click)=\"onMoveUp()\" [disabled]=\"!selectedItem\" title=\"Move Up\">⇧</button>\n <button (click)=\"onMoveDown()\" [disabled]=\"!selectedItem\" title=\"Move Down\">⇩</button>\n </div>\n </div>\n <ul class=\"sortable-list\" [style.height]='listStyle.height'>\n <li draggable=\"true\" (click)=\"selectItem(item)\" *ngFor=\"let item of items; let i = index;\"\n [ngClass]=\"{'active': item == selectedItem}\" (drop)=\"onDrop($event, i)\" (dragover)=\"allowDrop($event,i)\"\n (dragstart)=\"onDragStart($event, i)\">\n <div class=\"drop-zone\" [style.height]=\"listStyle.dropZoneHeight\" *ngIf=\"onDragOverIndex == i && i==0\">\n </div>\n <ng-template [ngTemplateOutlet]=\"itemTemplate\" [ngTemplateOutletContext]=\"{\n item: item,\n index: i\n }\">\n </ng-template>\n <div class=\"drop-zone\" [style.height]=\"listStyle.dropZoneHeight\" *ngIf=\"onDragOverIndex == i && i!=0\">\n </div>\n </li>\n </ul>\n</div>", styles: [".sortable-container{width:100%;border:1px solid #d9d9d9;position:static;border-radius:3px}.sortable-container .sortable-header{width:auto;padding:5px;background:lightgray;border-bottom:1px solid #d9d9d9;height:30px;background-image:linear-gradient(rgb(246,247,249) 0%,rgb(235,237,240) 100%);box-sizing:content-box;color:#000}.sortable-container .sortable-header .sortable-name{vertical-align:middle;font-size:25px}.sortable-container .sortable-header .sortable-buttons{float:right;height:100%;box-sizing:border-box}.sortable-container .sortable-header .sortable-buttons button{height:30px;width:30px;vertical-align:middle;display:inline-block;box-sizing:border-box;margin-left:5px;border:1px solid #2399e5;color:#fff;background:#2399e5;transition:background-color .2s;border-radius:5px;outline:none}.sortable-container .sortable-header .sortable-buttons button:disabled{cursor:not-allowed}.sortable-container .sortable-header .sortable-buttons button:active,.sortable-container .sortable-header .sortable-buttons button:hover{border:1px solid #156090;background:#186ba0;color:#fff}.sortable-container .sortable-header .sortable-buttons button:active:enabled,.sortable-container .sortable-header .sortable-buttons button:hover:enabled{cursor:pointer}.sortable-container .sortable-list{list-style-type:none;margin:0;padding:0;overflow:auto;position:static}.sortable-container .sortable-list .drop-zone{background:rgba(225,219,250,.5);opacity:.5px;border:2px dotted rgb(225,219,250)}.sortable-container .sortable-list .remove{background:rgba(248,210,181,.5);text-align:center}.sortable-container .sortable-list .active{cursor:grab;background:#3f94e9;color:#fff}\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: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableComponent, decorators: [{
type: Component,
args: [{ selector: "ngx-sortable", template: "<div class=\"sortable-container\" [style.width]='listStyle.width'>\n <div class=\"sortable-header\" *ngIf=\"showHeader\">\n <label class=\"sortable-name\">{{name}}</label>\n <div class=\"sortable-buttons\">\n <button (click)=\"onMoveUp()\" [disabled]=\"!selectedItem\" title=\"Move Up\">⇧</button>\n <button (click)=\"onMoveDown()\" [disabled]=\"!selectedItem\" title=\"Move Down\">⇩</button>\n </div>\n </div>\n <ul class=\"sortable-list\" [style.height]='listStyle.height'>\n <li draggable=\"true\" (click)=\"selectItem(item)\" *ngFor=\"let item of items; let i = index;\"\n [ngClass]=\"{'active': item == selectedItem}\" (drop)=\"onDrop($event, i)\" (dragover)=\"allowDrop($event,i)\"\n (dragstart)=\"onDragStart($event, i)\">\n <div class=\"drop-zone\" [style.height]=\"listStyle.dropZoneHeight\" *ngIf=\"onDragOverIndex == i && i==0\">\n </div>\n <ng-template [ngTemplateOutlet]=\"itemTemplate\" [ngTemplateOutletContext]=\"{\n item: item,\n index: i\n }\">\n </ng-template>\n <div class=\"drop-zone\" [style.height]=\"listStyle.dropZoneHeight\" *ngIf=\"onDragOverIndex == i && i!=0\">\n </div>\n </li>\n </ul>\n</div>", styles: [".sortable-container{width:100%;border:1px solid #d9d9d9;position:static;border-radius:3px}.sortable-container .sortable-header{width:auto;padding:5px;background:lightgray;border-bottom:1px solid #d9d9d9;height:30px;background-image:linear-gradient(rgb(246,247,249) 0%,rgb(235,237,240) 100%);box-sizing:content-box;color:#000}.sortable-container .sortable-header .sortable-name{vertical-align:middle;font-size:25px}.sortable-container .sortable-header .sortable-buttons{float:right;height:100%;box-sizing:border-box}.sortable-container .sortable-header .sortable-buttons button{height:30px;width:30px;vertical-align:middle;display:inline-block;box-sizing:border-box;margin-left:5px;border:1px solid #2399e5;color:#fff;background:#2399e5;transition:background-color .2s;border-radius:5px;outline:none}.sortable-container .sortable-header .sortable-buttons button:disabled{cursor:not-allowed}.sortable-container .sortable-header .sortable-buttons button:active,.sortable-container .sortable-header .sortable-buttons button:hover{border:1px solid #156090;background:#186ba0;color:#fff}.sortable-container .sortable-header .sortable-buttons button:active:enabled,.sortable-container .sortable-header .sortable-buttons button:hover:enabled{cursor:pointer}.sortable-container .sortable-list{list-style-type:none;margin:0;padding:0;overflow:auto;position:static}.sortable-container .sortable-list .drop-zone{background:rgba(225,219,250,.5);opacity:.5px;border:2px dotted rgb(225,219,250)}.sortable-container .sortable-list .remove{background:rgba(248,210,181,.5);text-align:center}.sortable-container .sortable-list .active{cursor:grab;background:#3f94e9;color:#fff}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { items: [{
type: Input
}], name: [{
type: Input
}], showHeader: [{
type: Input
}], removeOnDropOutside: [{
type: Input
}], dragStart: [{
type: Output
}], dropped: [{
type: Output
}], moveDown: [{
type: Output
}], moveUp: [{
type: Output
}], remove: [{
type: Output
}], listStyle: [{
type: Input
}], listSorted: [{
type: Output
}], itemTemplate: [{
type: ContentChild,
args: [TemplateRef]
}], arrowKeySort: [{
type: Input
}], commandKey: [{
type: Input
}], onArrowKeyDown: [{
type: HostListener,
args: ["document:keydown", ["$event"]]
}], onDragEnd: [{
type: HostListener,
args: ["document:dragend"]
}] } });
class NgxSortableModule {
}
NgxSortableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgxSortableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableModule, declarations: [NgxSortableComponent], imports: [CommonModule], exports: [NgxSortableComponent] });
NgxSortableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableModule, imports: [CommonModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: NgxSortableModule, decorators: [{
type: NgModule,
args: [{
declarations: [NgxSortableComponent],
imports: [CommonModule],
exports: [NgxSortableComponent],
providers: [],
bootstrap: []
}]
}] });
/*
* Public API Surface of ngx-sortable
*/
/**
* Generated bundle index. Do not edit.
*/
export { CommandKey, NgxSortableComponent, NgxSortableModule };
//# sourceMappingURL=ngx-sortable.mjs.map