DataTable - copy row

I have a DataTable on a public form. When the user clicks, 'Add new record' I would like to copy the value from a column in the previous row and insert it into the same column for the new row. The column involved is a Dropdown type.

I also would like to make this behavior optional based on the value of a Single Choice field (e.g., choice options are "copy previous value" or "do NOT copy previous value).

Dear @donald.kantik ,
If I understand correctly, you want something like this:

This can be achieved with the following JavaScript code:

fd.rendered(function() {
    var dt = fd.control('DataTable1');
    var isNew = false;
    dt.widget.wrapper.find('.k-grid-add').on('click', e => {
        isNew = true;
    });
    dt.widget.bind('edit', function(e) {
        if (isNew && fd.field('Copy').value == 'Copy row') {
            isNew = false;
            e.model.set('Dropdown', fd.control('DataTable1').value[1].Dropdown);
        }
    });
});

You just need to replace DataTable1 with the name of your DataTable, Copy with the name of your dropdown field and Copy row with the value which is used for copying. Finally, replace Dropdown used twice in one line with the name of the column to copy.

Now, if you want something even more advanced, it's also possible to add a button to each row, which will allow copying this specific row, essentially creating an exact duplicate.

Nikita,

Yes, that is basically what I wanted except I am copying the values for both Column1 and Column2. Your solution works but only if I make Column1 NOT required - otherwise I get an error.

Thanks,
Don

Dear @donald.kantik,
Okay, I see, will try to rectify it! What about something like this? - Form Preview

This will add a duplicate button to each row instead. Try the following code to make this work:

fd.rendered(function() {
    var dt = fd.control('DataTable1');
    var columns = dt.widget.options.columns;
    var customRowDataItem = null;
    var isCustomAdd = false;
    columns.push({
        command: {
            text: "Copy row",
            iconClass:"k-icon k-i-copy",
            click: function(e) {
                e.preventDefault();
                customRowDataItem = this.dataItem($(e.currentTarget).closest("tr"));
                isCustomAdd = true;
                this.addRow();
            }
        }
    });
    dt.widget.setOptions({
        columns: columns
    });
    dt.widget.bind('edit', function(e) {
        if (isCustomAdd && e.model.isNew()) {
            isCustomAdd = false;
            for (var i = 0; i < columns.length; i++) {
                var field = columns[i].field;
                if (field) {
                    e.model.set(field, customRowDataItem[field]);
                }
            }
            e.sender.closeCell(e.container);
        }
    });
});

Hello,

Can I hide the text of the button "Copy row"? Only the icon is fine for me :wink:

Thanky you,

Daniël

Dear @danieljr,
It does need some text, at least an empty space, but you can add a custom CSS class:

fd.rendered(function() {
    var dt = fd.control('DataTable1');
    var columns = dt.widget.options.columns;
    var customRowDataItem = null;
    var isCustomAdd = false;
    columns.push({
        command: {
            text: ' ',
            iconClass:"k-icon k-i-copy no-margin",
            click: function(e) {
                e.preventDefault();
                customRowDataItem = this.dataItem($(e.currentTarget).closest("tr"));
                isCustomAdd = true;
                this.addRow();
            }
        }
    });
    dt.widget.setOptions({
        columns: columns
    });
    dt.widget.bind('edit', function(e) {
        if (isCustomAdd && e.model.isNew()) {
            isCustomAdd = false;
            for (var i = 0; i < columns.length; i++) {
                var field = columns[i].field;
                if (field) {
                    e.model.set(field, customRowDataItem[field]);
                }
            }
            e.sender.closeCell(e.container);
        }
    });
});

And use it with CSS code in Theme settings > Custom CSS to center the icon:

.no-margin{
    margin: 0!important;
}

Works fine! thanks :+1:

I found a problem (same text is confusing for the datatable)

My solution: also added "name"

//Manueal sort - specify what the column will be like
columns.push({
    command: {
        name: "moveUp",
        text: " ",
        iconClass:"k-icon k-i-sort-asc-sm no-margin", 
        click: function(e) {
            e.preventDefault();
            var selectedItem = $(e.currentTarget).closest("tr");
            var selectedUid = selectedItem.attr("data-uid");
            var itemIndex = selectedItem.index();
            var dataItem = grid.dataItem(selectedItem);

            var newIndex = itemIndex - 1;
            var content = $(".k-grid-content");
            var offset = selectedItem.offset().top;

            if (newIndex <= 0) {
              newIndex = 0;
            }

            grid.dataSource.remove(dataItem);
            grid.dataSource.insert(newIndex, dataItem);

            grid.select("[data-uid=" + selectedUid +"]");
        }
    }
});
columns.push({
    command: {
        name: "moveDown",
        text: " ",
        iconClass:"k-icon k-i-sort-desc-sm no-margin",
        click: function(e) {
            e.preventDefault();
            var selectedItem = $(e.currentTarget).closest("tr");
            var selectedUid = selectedItem.attr("data-uid");
            var itemIndex = selectedItem.index();
            var dataItem = grid.dataItem(selectedItem);

            var newIndex = itemIndex + 1;
            var content = $(".k-grid-content");

            var offset = selectedItem.offset().top;

            if (newIndex < grid.dataSource.view().length) {
              grid.dataSource.remove(dataItem);
              grid.dataSource.insert(newIndex, dataItem);

              grid.select("[data-uid=" + selectedUid +"]");
            }
        }
    }
});
dt.widget.setOptions({
    columns: columns
});
1 Like