Copy Item with Drag and Drop in Angular ListBox

Created: 18 Jan 2019

Drag and Drop allows you to move items during run time from one position to another in the same or between different components. In some cases, during this process instead of moving the item(s), you may need to create a copy item and place it at target location. In this article you will learn how to create item copy during drag and drop from one Angular ListBox component to another.

ListBox component is part of IntegralUI Web
a suite of UI Components for development of web apps

If you have any questions, don't hesitate to contact us at support@lidorsystems.com

In this demo, the ListBox has some items with drag and drop enabled. You can select an item and start dragging it from left to right. While over the right ListBox, to create an item copy, hold the SHIFT key and release the mouse button. In this way, instead of moving the original item, you have copied the item from left ListBox to the right one.

Note To simplify the example, drop items over the ListBox on the left is disabled. So you can only more or copy items from left to the right list.

You can also create copies within the same Angular ListBox component, or move/copy items from right to left, in general the functionality is the same.

How to Copy an Item during Drag and Drop

When item is dragged, you can choose whether you want to move it or create a copy of it at target location within the same or a different component. Holding the SHIFT key changes the drag and drop from move to a copy operation. This is only required on drop, when you are sure of the target drop location.

Note During this process the drop mark will change its icon by showing a plus sign next to the arrow, which means that the copy operation is in place.

Internally, during a copy operation a deep clone of the item object is created. This includes a copy of all custom data fields set by you. The only change is the id field that contains a unique identifier for each item. This allows you to have duplicates (in appearance or content) within the same item lists, while still maintaining each item as unique one.

You can clear the selection from the first list, by calling clearSelection method when item(s) drops.

listDrop(e: any){
    // On COPY, clear the selected items in the left ListBox
    if (e.action == 'copy' && e.sourceCtrl && e.sourceCtrl.clearSelection)
        e.sourceCtrl.clearSelection();
}
                            
<div class="app-block" #application>
    <iui-listbox [appRef]="applicationRef" [items]="items" [allowDrag]="true" [allowDrop]="false" [controlStyle]="listStyle" [selectionMode]="selMode" #listbox>
        <iui-listitem *ngFor="let item of items" [controlStyle]="itemStyle" [allowAnimation]="true">  
            <div class="lbox-dd-copy-item-content">
                <span class="lbox-dd-copy-icons {{item.icon}}"></span>
                <span class="lbox-dd-copy-title">{{item.text}}</span>
                <span class="lbox-dd-copy-year">{{item.year}}</span>
            </div>
        </iui-listitem>
    </iui-listbox>
    <iui-listbox [appRef]="applicationRef" [items]="cloneItems" [controlStyle]="cloneListStyle" (dragDrop)="listDrop($event)" #listboxCopy>
        <iui-listitem *ngFor="let item of cloneItems" [controlStyle]="itemStyle" [allowAnimation]="true">  
            <div class="lbox-dd-copy-item-content">
                <span class="lbox-dd-copy-icons {{item.icon}}"></span>
                <span class="lbox-dd-copy-title">{{item.text}}</span>
                <span class="lbox-dd-copy-year">{{item.year}}</span>
            </div>
        </iui-listitem>
    </iui-listbox>
</div>
                            

Create a Copy Item on Drop event in Angular ListBox

The other way to create a copy item is to handle the dragDrop event and cancel the default drag and drop functionality and then adding your own custom operation. In this way, by intercepting the drag and drop you can create a copy item manually in your code using the cloneItem method. In this case holding the SHIFT key is not required, because the item clone is created in code.

Related: How to Handle Drag and Drop Events in ListBox for Angular

At first, you need to cancel the drag and drop. To do this, set the cancel field of drag drop event data to true. Then you can proceed with creating clones from dropped items. For example:

listDrop(e: any){
    e.cancel = true;

    if (e.sourceCtrl && e.dragItem && Array.isArray(e.dragItem)){
        e.targetCtrl.suspendLayout();

        for (let i = 0; i < e.dragItem.length; i++){
            let clone = e.sourceCtrl.cloneItem(e.dragItem[i]);

            // Depending on drop position, place the clone item accordingly
            switch (e.dropPos){
                case 1: // Above
                    e.targetCtrl.insertItemBefore(clone, e.targetItem);
                    break;

                case 2: // Below
                    e.targetCtrl.insertItemAfter(clone, e.targetItem);
                    break;

                default: // At the end
                    e.targetCtrl.addItem(clone);
                    break;
            }
        }
        
        e.targetCtrl.resumeLayout();
    }
}
                            

Check first whether there is a source control, using the sourceCtrl field from the event data. This gives you access to the cloneItem method from the ListBox component, which you can use to create a deep copy of the item object.

Note In case of custom source control, which may not have a method for cloning, you can use the IntegralUIDataService. This service has a cloneObject method, which creates a deep copy of any object.

Once a copy item is available, add it to the target list at location determined by the drop position. There can be only three locations: above, below the target item or at the end of the list.

Note To improve performance, mostly when copying multiple items, enclose this process within calls to suspendLayout and resumeLayout methods. This prevents layout from updating whenever a new item is added to the list.

Conclusion

IntegralUI ListBox for Angular comes with built-in support for drag and drop operations that allows you to move or copy items. Creating an item copy during drag and drop is easy; you only need to hold the SHIFT key while item is dropped at target location. In other cases, you can also create an item copy manually in your code, using provided built-in methods.

The ListBox component is part of IntegralUI Web.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.