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
Advanced User Interface Controls and Components
Created: 22 Jan 2019
When drag and drop is enabled in ListBox component for Angular, you can move items one by one within the same or to other components. With multi selection enabled you can also drag and drop multiple items at the same. This article explains how to do that.
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
In this demo, you can select multiple items by holding CTRL or SHIFT key and clicking on items in the ListBox. Next, by holding the left mouse button and dragging the mouse cursor starting from a selected item, a drag and drop operation will start in which all selected items are carried. On drop, all dragged items are placed at target location.
Note For demonstration purposes only, you cannot select the top three items.
To create a copy of dragged items, on drop hold the SHIFT key. In this way, instead of original items, copies are created and dropped at target position. This allows you to choose whether you want to move or copy multiple items during drag drop.
At first, you need to enable drag and drop in the angular ListBox by setting the allowDrag property to true. This only allows you to drag items one by one. To enable drag and drop for multiple items, you also need to set the selectionMode property to one of these values:
import { Component, enableProdMode, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
import { IntegralUISelectionMode } from './integralui/components/integralui.core';
enableProdMode();
@Component({
selector: 'iui-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild('application', {read: ViewContainerRef}) applicationRef: ViewContainerRef;
public items: Array;
public selMode: IntegralUISelectionMode = IntegralUISelectionMode.MultiExtended;
}
<div class="app-block" #application>
<iui-listbox [appRef]="applicationRef" [items]="items" [controlStyle]="listStyle" [allowDrag]="true" [selectionMode]="selMode" (dragOver)="listDragOver($event)" #listbox>
<iui-listitem *ngFor="let item of items" [controlStyle]="itemStyle" [allowAnimation]="true">
<div class="lbox-dd-multi-item-content">
<span class="lbox-dd-multi-icons {{item.icon}}"></span>
<span class="lbox-dd-multi-title">{{item.text}}</span>
<span class="lbox-dd-multi-year">{{item.year}}</span>
<iui-rating [controlStyle]="lboxOverviewRatingStyleStars" [value]="getRating(item.rating)" [max]="5"></iui-rating>
</div>
</iui-listitem>
</iui-listbox>
</div>
Related: Selection Options in Angular ListBox
On correlation with custom action set in dragOver event handler (see below), to create a scenario where drag and drop is allowed only form items that are below the first three. The first three items are marked as non selectable.
constructor(){
this.items = [
{ id: 1, icon: "sci-fi", allowDrag: false, canSelect: false, text: "Star Trek", year: "2009", rating: 8.0 },
{ id: 2, icon: "adventure", allowDrag: false, canSelect: false, text: "Cast Away", year: "2000", rating: 7.7, style: { color: 'red' } },
{ id: 3, icon: "action", allowDrag: false, canSelect: false, text: "Gladiator ", year: "2000", rating: 8.5 },
{ id: 4, icon: "drama", text: "Malèna", year: "2000", rating: 7.5 },
{ id: 5, icon: "music", text: "Moulin Rouge", year: "2001", rating: 7.6 },
{ id: 6, icon: "comedy", text: "Snatch", year: "2000", rating: 8.3 },
{ id: 7, icon: "biography", text: "A Beautiful Mind", year: "2001", rating: 8.2 },
{ id: 8, icon: "crime", text: "Black Hawk Down", year: "2001", rating: 7.7 },
{ id: 9, icon: "western", text: "Django Unchained", year: "2012", rating: 8.5 },
{ id: 10, icon: "sci-fi", text: "Man of Steel", year: "2013", rating: 7.2 },
{ id: 11, icon: "horror", text: "The Ring", year: "2002", rating: 7.1 },
{ id: 12, icon: "romance", text: "40 Days and 40 Nights", year: "2002", rating: 5.6 },
{ id: 13, icon: "sci-fi", text: "Minority Report", year: "2002", rating: 7.7 },
{ id: 14, icon: "comedy", text: "Scary Movie 3", year: "2003", rating: 5.5 },
{ id: 15, icon: "music", text: "Walk the Line", year: "2005", rating: 7.9 },
{ id: 16, icon: "romance", text: "How to Lose a Guy in 10 Days", year: "2003", rating: 6.4 },
{ id: 17, icon: "crime", text: "The Dark Knight", year: "2008", rating: 9.0 },
{ id: 18, icon: "horror", text: "American Psycho", year: "2000", rating: 7.6 },
{ id: 19, icon: "drama", text: "The Grand Budapest Hotel", year: "2014", rating: 8.1 },
{ id: 20, icon: "comedy", text: "The Wolf of Wall Street", year: "2013", rating: 8.2 }
];
}
Whenever an item or multiple items are dragged over other items, the dragOver event will fire. You can intercept this event in your code and provide custom conditions. Depending on condition set, you can choose whether to continue or cancel the drag and drop operation.
Related: Drag and Drop Events in ListBox
In case when multiple items are dragged, the dragOver event data holds an array of all selected items. You can check this data in your event handler:
listDragOver(e: any){
if (e.dragItem && Array.isArray(e.dragItem)){
let targetIndex = this.items.indexOf(e.targetItem);
if (targetIndex <= 2)
e.cancel = true;
}
}
<div class="app-block" #application>
<iui-listbox [appRef]="applicationRef" [items]="items" [controlStyle]="listStyle" [allowDrag]="true" [selectionMode]="selMode" (dragOver)="listDragOver($event)" #listbox>
<iui-listitem *ngFor="let item of items" [controlStyle]="itemStyle" [allowAnimation]="true">
<div class="lbox-dd-multi-item-content">
<span class="lbox-dd-multi-icons {{item.icon}}"></span>
<span class="lbox-dd-multi-title">{{item.text}}</span>
<span class="lbox-dd-multi-year">{{item.year}}</span>
<iui-rating [controlStyle]="lboxOverviewRatingStyleStars" [value]="getRating(item.rating)" [max]="5"></iui-rating>
</div>
</iui-listitem>
</iui-listbox>
</div>
As you can see, a check to the e.dragItem field is set to determine whether it is an array or a single object. Depending on this value, you can proceed with the event by adding custom code.
For example, you can check whether the target item is a valid one and whether the drop position is ok. In this code, the drag and drop is allowed only if the target item is below the top three items. In this way, the first three items can act as fixed ones, while you can reorder all the other items. If the target item is one of these top three items, you can cancel the drag and drop by setting the e.cancel data field to true.
Related: Drag and Drop between ListBox and ListView
In this way whenever you drag items over top three items, the mouse cursor will change to NO DROP, stating that you cannot drop items at that location. In addition, top three items are also disabled from dragging, by simple setting their allowDrag field to false.
Drag and Drop feature of Angular ListBox component allows you to reorder items within the component itself during run-time. If multi selection is enabled, you can drag and drop multiple items at once and place them at different position. In this process, you can add event handlers with your own custom conditions that may alter the drag and drop operation.
The ListBox component is part of IntegralUI Web.