Skip to content

Commit

Permalink
feat(drag-utils): add utility function for cloning array items from o…
Browse files Browse the repository at this point in the history
…ne 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
  • Loading branch information
nayfin authored and mmalerba committed Oct 26, 2018
1 parent f1d1fc5 commit 13395c5
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
43 changes: 42 additions & 1 deletion src/cdk/drag-drop/drag-utils.spec.ts
@@ -1,4 +1,4 @@
import {moveItemInArray, transferArrayItem} from './drag-utils';
import {moveItemInArray, transferArrayItem, copyArrayItem} from './drag-utils';

describe('dragging utilities', () => {
describe('moveItemInArray', () => {
Expand Down Expand Up @@ -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]);
});

});

});
21 changes: 20 additions & 1 deletion src/cdk/drag-drop/drag-utils.ts
Expand Up @@ -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);

Expand All @@ -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));
Expand Down
4 changes: 4 additions & 0 deletions src/demo-app/drag-drop/drag-drop-demo.html
@@ -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"
Expand Down
26 changes: 21 additions & 5 deletions src/demo-app/drag-drop/drag-drop-demo.ts
Expand Up @@ -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,
Expand All @@ -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',
Expand Down Expand Up @@ -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);
}
}
}
}

0 comments on commit 13395c5

Please sign in to comment.