feat(drag-utils): add utility function for cloning array items from one array to another (#13743)

* feat(drag-utils): add utility function for cloning array items from one array to another

creates a utility helper for cloning an array item into the array of the drop container
compliments moveItemInArray and transferArrayItem

partially closes #13100

* feat(drag-utils): add utility function for cloning array items from one array to another

resolves issues surfaced from code review

* feat(drag-utils): add utility function for cloning array items from one array to another

cuts extra space between parens

* removes link in comments, and clarifies function definition as recommended in review

* resolves nits
This commit is contained in:
Nathan
2018-10-25 10:21:19 -05:00
committed by mmalerba
parent 4fbbb9d52d
commit d2d8a1f675
4 changed files with 87 additions and 7 deletions
+42 -1
View File
@@ -1,4 +1,4 @@
import {moveItemInArray, transferArrayItem} from './drag-utils';
import {moveItemInArray, transferArrayItem, copyArrayItem} from './drag-utils';
describe('dragging utilities', () => {
describe('moveItemInArray', () => {
@@ -66,4 +66,45 @@ describe('dragging utilities', () => {
});
});
describe('copyArrayItem', () => {
it('should be able to copy an item from one array to another', () => {
const a = [0, 1, 2];
const b = [3, 4, 5];
copyArrayItem(a, b, 1, 2);
expect(a).toEqual([0, 1, 2 ]);
expect(b).toEqual([3, 4, 1, 5]);
});
it('should handle an index greater than the target array length', () => {
const a = [0, 1, 2];
const b = [3, 4, 5];
copyArrayItem(a, b, 0, 7);
expect(a).toEqual([0, 1, 2]);
expect(b).toEqual([3, 4, 5, 0]);
});
it('should handle an index less than zero', () => {
const a = [0, 1, 2];
const b = [3, 4, 5];
copyArrayItem(a, b, 2, -1);
expect(a).toEqual([0, 1, 2]);
expect(b).toEqual([2, 3, 4, 5]);
});
it('should not do anything if the source array is empty', () => {
const a: number[] = [];
const b = [3, 4, 5];
copyArrayItem(a, b, 0, 0);
expect(a).toEqual([]);
expect(b).toEqual([3, 4, 5]);
});
});
});
+20 -1
View File
@@ -42,7 +42,6 @@ export function transferArrayItem<T = any>(currentArray: T[],
targetArray: T[],
currentIndex: number,
targetIndex: number): void {
const from = clamp(currentIndex, currentArray.length - 1);
const to = clamp(targetIndex, targetArray.length);
@@ -51,6 +50,26 @@ export function transferArrayItem<T = any>(currentArray: T[],
}
}
/**
* Copies an item from one array to another, leaving it in its
* original position in current array.
* @param currentArray Array from which to copy the item.
* @param targetArray Array into which is copy the item.
* @param currentIndex Index of the item in its current array.
* @param targetIndex Index at which to insert the item.
*
*/
export function copyArrayItem<T = any>(currentArray: T[],
targetArray: T[],
currentIndex: number,
targetIndex: number): void {
const to = clamp(targetIndex, targetArray.length);
if (currentArray.length) {
targetArray.splice(to, 0, currentArray[currentIndex]);
}
}
/** Clamps a number between zero and a maximum. */
function clamp(value: number, max: number): number {
return Math.max(0, Math.min(max, value));
@@ -1,6 +1,10 @@
<div>
<div class="demo-list">
<h2>To do</h2>
<mat-slide-toggle color="primary" [(ngModel)]="cloneMode">
Clone Mode
</mat-slide-toggle>
<div
cdkDropList
#one="cdkDropList"
+21 -5
View File
@@ -9,7 +9,12 @@
import {Component, ViewEncapsulation} from '@angular/core';
import {MatIconRegistry} from '@angular/material/icon';
import {DomSanitizer} from '@angular/platform-browser';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
import {
CdkDragDrop,
moveItemInArray,
transferArrayItem,
copyArrayItem
} from '@angular/cdk/drag-drop';
@Component({
moduleId: module.id,
@@ -19,6 +24,8 @@ import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag
encapsulation: ViewEncapsulation.None,
})
export class DragAndDropDemo {
cloneMode = false;
axisLock: 'x' | 'y';
todo = [
'Go out for Lunch',
@@ -56,10 +63,19 @@ export class DragAndDropDemo {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
if (this.cloneMode) {
copyArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
}
}
}