Copy and paste records in Angular Gantt component
18 Oct 20257 minutes to read
The copy and paste functionality in the Angular Gantt component enables efficient task duplication, allowing you to replicate tasks or entire task hierarchies using the addRecord method and a custom context menu configured via contextMenuItems. For example, right-clicking a parent task to copy and paste it with its child tasks at a specified position streamlines project management workflows. Inject EditService and enable editSettings.allowAdding to support adding copied records. Define valid taskFields mappings (e.g., id, name, startDate) to ensure task data is correctly replicated, including hierarchical structures with child tasks. Use the contextMenuClick event to handle custom copy-paste actions, specifying the paste position (e.g., child, above, below) via addRecord parameters. This feature integrates with dependencies, critical path, and virtual scrolling, ensuring duplicated tasks align with the project structure for seamless schedule management.
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule, ContextMenuService, EditService, SelectionService,  GanttComponent, ContextMenuClickEventArgs, ContextMenuOpenEventArgs} from '@syncfusion/ej2-angular-gantt'
import { ContextMenuItemModel } from '@syncfusion/ej2-angular-grids';
import { editingData } from './data';
@Component({
    imports: [GanttModule],
    providers: [SelectionService, ContextMenuService, EditService],
    standalone: true,
    selector: 'app-root',
    template:
        `<ejs-gantt id="ganttCustomContextmenu" height="430px" [dataSource]="editingData" [taskFields]="taskSettings" [enableContextMenu]="true" [contextMenuItems]="contextMenuItems" [editSettings]="editSettings" (contextMenuClick)="contextMenuClick($event)" (contextMenuOpen)="contextMenuOpen($event)"></ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
    @ViewChild('customcontextmenu', { static: true }) public ganttInstance?: GanttComponent;
    public copiedRecord?: any;
    public editingData?: object[];
    public taskSettings?: object;
    public editSettings?: object;
    public contextMenuItems?: (string | ContextMenuItemModel)[];
    public ngOnInit(): void {
        this.editingData = editingData;
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            dependency: 'Predecessor',
            parentID: 'ParentID',
        };
        this.editSettings = {
            allowAdding: true,
            allowEditing: true,
            allowDeleting: true
        };
        this.contextMenuItems = [{ text: 'Copy', target: '.e-content', id: 'copy' } as ContextMenuItemModel,
        { text: 'Paste', target: '.e-content', id: 'paste' } as ContextMenuItemModel,
        ];
    }
    public contextMenuClick(args: ContextMenuClickEventArgs) {
        if (args.item.id === 'copy') {
            this.copiedRecord = args.rowData;
            this.copiedRecord.taskData.TaskID = this.ganttInstance.currentViewData.length + 1;
        }
        if (args.item.id === 'paste') {
            this.ganttInstance.addRecord(this.copiedRecord.taskData, 'Below', args.rowData!.index);
            if (this.copiedRecord.hasChildRecords) {
                addChildRecords(this.copiedRecord, args.rowData!.index! + 1);
            }
            this.copiedRecord = undefined;
        }
    }
    
    public contextMenuOpen(args: ContextMenuOpenEventArgs) {
        if (args.type !== 'Header') {
            if (this.copiedRecord) {
                args.hideItems!.push('Copy');
            } else {
                args.hideItems!.push('Paste');
            }
        }
    }
}
function addChildRecords(this: any, record: any, index: any): void {
    for (var i = 0; i < record.childRecords.length; i++) {
        var childRecord = record.childRecords[i];
        childRecord.taskData.TaskID = this.ganttInstance.currentViewData.length + 1;
        this.ganttInstance.addRecord(childRecord.taskData, 'Child', index);
        if (childRecord.hasChildRecords) {
            addChildRecords(childRecord, index + (i + 1));
        }
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));