@progress/kendo-angular-listbox
Version:
Kendo UI for Angular ListBox
155 lines (154 loc) • 6.4 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Directive, Input } from '@angular/core';
import { isChanged } from '@progress/kendo-angular-common';
import { Subscription } from 'rxjs';
import { ListBoxComponent } from './listbox.component';
import { isPresent } from './util';
import * as i0 from "@angular/core";
import * as i1 from "./listbox.component";
/**
* A directive which manages the functoinality of the ListBox tools out of the box, and modifies the provided data accordingly.
*/
export class DataBindingDirective {
listbox;
/**
* Specifies the ListBoxComponent instance with which the current ListBox should be connected.
* When two listboxes are linked via this input, one can transfer items between them.
*/
connectedWith;
actionClickSub = new Subscription();
selectedBoxSub = new Subscription();
connectedWithSub = new Subscription();
selectedBox;
constructor(listbox) {
this.listbox = listbox;
this.selectedBox = this.listbox;
this.connectedWithSub.add(this.listbox.getChildListbox.subscribe(() => {
this.listbox.childListbox = this.connectedWith;
}));
this.actionClickSub.add(this.listbox.actionClick.subscribe((actionName) => {
switch (actionName) {
case 'moveUp': {
this.moveVertically('up');
break;
}
case 'moveDown': {
this.moveVertically('down');
break;
}
case 'transferFrom': {
this.transferItem(this.connectedWith, this.listbox);
break;
}
case 'transferTo': {
this.transferItem(this.listbox, this.connectedWith);
break;
}
case 'transferAllTo': {
this.transferAll(this.listbox, this.connectedWith);
break;
}
case 'transferAllFrom': {
this.transferAll(this.connectedWith, this.listbox);
break;
}
case 'remove': {
this.removeItem();
break;
}
default: {
break;
}
}
}));
}
/**
* @hidden
*/
ngOnChanges(changes) {
if (isChanged('connectedWith', changes, false)) {
if (!changes['connectedWith'].firstChange) {
this.selectedBoxSub.unsubscribe();
this.selectedBoxSub = new Subscription();
}
this.selectedBoxSub.add(this.listbox.selectionChange.subscribe(() => {
this.selectedBox = this.listbox;
this.connectedWith.clearSelection();
}));
this.selectedBoxSub.add(this.connectedWith.selectionChange.subscribe(() => {
this.selectedBox = this.connectedWith;
this.listbox.clearSelection();
}));
}
}
/**
* @hidden
*/
ngOnDestroy() {
if (this.actionClickSub) {
this.actionClickSub.unsubscribe();
this.actionClickSub = null;
}
if (this.selectedBoxSub) {
this.selectedBoxSub.unsubscribe();
this.selectedBoxSub = null;
}
}
moveVertically(dir) {
const index = this.selectedBox.selectedIndex;
if (!isPresent(index)) {
return;
}
const topReached = dir === 'up' && index <= 0;
const bottomReached = dir === 'down' && index >= this.selectedBox.data.length - 1;
if (topReached || bottomReached) {
return;
}
const newIndex = dir === 'up' ? index - 1 : index + 1;
const navigation = this.selectedBox.keyboardNavigationService;
navigation.focusedListboxItemIndex = navigation.selectedListboxItemIndex = newIndex;
[this.selectedBox.data[newIndex], this.selectedBox.data[index]] = [this.selectedBox.data[index], this.selectedBox.data[newIndex]];
this.selectedBox.selectionService.select(newIndex);
}
removeItem() {
const index = this.selectedBox.selectedIndex;
if (!isPresent(index)) {
return;
}
this.selectedBox.data.splice(index, 1);
this.selectedBox.selectionService.clearSelection();
}
transferItem(source, target) {
const item = source && source.data[source.selectedIndex];
if (!item || !target || !source) {
return;
}
target.data.push(item);
source.data.splice(source.selectedIndex, 1);
source.clearSelection();
target.selectItem(target.data.length - 1);
this.selectedBox = target;
}
transferAll(source, target) {
if (!target || !source) {
return;
}
target.data.splice(target.data.length, 0, ...source.data.splice(0, source.data.length));
target.selectItem(target.data.length - 1);
this.selectedBox = target;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: i1.ListBoxComponent }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DataBindingDirective, isStandalone: true, selector: "[kendoListBoxDataBinding]", inputs: { connectedWith: "connectedWith" }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, decorators: [{
type: Directive,
args: [{
selector: '[kendoListBoxDataBinding]',
standalone: true
}]
}], ctorParameters: function () { return [{ type: i1.ListBoxComponent }]; }, propDecorators: { connectedWith: [{
type: Input
}] } });