LIDOR SYSTEMS

Advanced User Interface Controls and Components

Copy Row in Angular TreeGrid

Created: 08 November 2017

In cases when you select multiple rows you may need to create a copy of these rows and place them at different position within the Tree Grid component. IntegralUI TreeGrid for Angular comes with built-in method that makes this process simple. In this article, you will learn how to create a deep copy of selected row and move it at different position using a context menu.

TreeGrid 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

As demo shows, by right-clicking over selected rows, a context menu will popup. By selecting the COPY menu option, the selected rows are copied. Next, by opening the context menu again over some target row in the second Grid, you can select the PASTE option. This will place the copied row below the target row.

How to Copy a Row in Angular TreeGrid

In order to create a copy row, you need to use the cloneRow method. This method accepts a row as an argument, and returns a deep copy with all data from the original row including child rows. The clone object also has different id and pid values, so that it differs from the original object. This makes sure that the grid data doesn't have duplicates.

@ViewChild('application', {read: ViewContainerRef}) applicationRef: ViewContainerRef;
@ViewChild('treegrid') treegrid: IntegralUITreeGrid;

public gridStyle: any = {
    general: {
        normal: 'treegrid-cyr-normal'
    }
}

public columns: Array;
public rows: Array;

// Cut
private moveRow: any = null;

// Copy/Paste
private clone: any = null;

// Context Menu settings
private menuSettings: any = {
    appRef: null,
    items: [
        { id: 1, text: "Cut" },
        { id: 2, text: "Copy" },
        { id: 3, text: "Paste" }
    ]
}

ngAfterViewInit(){
    this.menuSettings.appRef = this.applicationRef;
}

// ContextMenu events ----------------------------------------------------------------

menuItemClick(e: any){
    if (e.item){
        // Action depends on selected menu option
        switch (e.item.id){
            case 1: // Cut
                // Mark the currently selected row for moving
                this.moveRow = this.treegrid.selectedRow;
                break;

            case 2: // Copy
                // Create a clone of currently selected row
                this.clone = this.treegrid.cloneRow(this.treegrid.selectedRow);
                break;

            case 3:  // Paste
                let pasteRow: any = null;

                // Get the row to be pasted
                // From CUT
                if (this.moveRow){
                    pasteRow = this.moveRow;
                    this.treegrid.removeRow(pasteRow);
                }
                // From COPY
                else if (this.clone)
                    pasteRow = this.clone;

                // Paste the row at position below the selected row
                if (pasteRow){
                    let parent: any = this.treegrid.getRowParent(this.treegrid.selectedRow);
                    let list: Array = parent && parent.rows ? parent.rows : this.rows;

                    if (list){
                        let index: number = list.indexOf(this.treegrid.selectedRow);
                        if (index >= 0)
                            this.treegrid.insertRowAt(pasteRow, index+1, parent);
                    }
                }

                this.treegrid.clearSelection();
                this.treegrid.updateLayout();

                this.moveRow = null;
                this.clone = null;
                break;
        }
   }
}

onMenuOpening(e: any){
    this.menuSettings.items[2].enabled = this.moveRow || this.clone ? true : false;
}                            
<iui-treegrid [appRef]="applicationRef" [controlStyle]="gridStyle" [columns]="columns" [rows]="rows" [expandColumnIndex]="1" [showFooter]="false" #treegrid>
    <ng-template let-column [iuiTemplate]="{ type: 'header' }">
        <span [ngSwitch]="column.id">
            <span *ngSwitchCase="1">
                <span class="treegrid-cyr-cell-checkbox" [ngStyle]="{ 'background-image': getCheckValue(column) }" (mousedown)="columnCheckClicked(column)"></span>
            </span>
            <span *ngSwitchDefault style="display:inline-block">
                <span>{{column.headerText}}</span>
            </span>
        </span>
    </ng-template>
    <ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
        <div [ngSwitch]="cell.cid" [iuiContextMenu]="menuSettings" (menuClick)="menuItemClick($event)" (menuOpening)="onMenuOpening($event)" [ngStyle]="{ display: cell.cid == 2 ? 'inline-block': 'block', width: cell.cid == 2 ? getCellWidth(cell) + 'px' : 'auto' }">
            <span *ngSwitchCase="1">
                <span class="treegrid-cyr-cell-checkbox" [ngStyle]="{ 'background-image': getCheckValue(cell) }" (mousedown)="checkBoxClicked(cell)"></span>
            </span>
            <span *ngSwitchCase="4">
                <img class="treegrid-cyr-cell-rating" src="{{getCellRating(cell)}}" />
            </span>
            <span *ngSwitchDefault style="display:inline-block">
                <span class="treegrid-cyr-cell-label">{{cell.text}}</span>
            </span>
        </div>
    </ng-template>
</iui-treegrid>
                            
.treegrid-cyr-normal
{
    width: 800px;
    height: 400px;
}
.treegrid-cyr-normal .iui-treegrid-expand-box
{
    margin-top: -3px;
}
.treegrid-cyr-cell-label
{
    display: inline-block;
    padding: 1px 0;
}
.treegrid-cyr-cell-checkbox
{
    background: url('') no-repeat 0 0;
    display: inline-block;
    padding: 0;
    margin: 0 7px;
    width: 16px;
    height: 16px;
    vertical-align: middle;
}
.treegrid-cyr-cell-rating
{
    margin: 0 15px;
    vertical-align: middle;
}                            

If you need copies of multiple rows (for example for all selected rows), you can create an array that will temporary hold the references of copied rows. Then, when PASTE option is selected, just add this array to the list.

Conclusion

To create a copy row in IntegralUI TreeGrid component for Angular is simple. You only need to call the cloneRow method, and an exact copy of specified row is created. The copied row has the same data as original row, only a different identifier to avoid creation of duplicates.

The TreeGrid 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.