Add custom command to Kendo UI dynamic datasource / grid

3.1k views Asked by At

I'm using Kendo UI javascript framework in an ASP.NET MVC application.

I have to load dynamic data, provided by my server, in my Kendo UI Grid, so I don't want to use datasource schema and columns definition, in no case.

An example of my data is :
PersonID, Data1, Data2, Date3 ...

To load dynamic data in Kendo UI Grid I use the following code: (JsFidlle Example)

var grid = $("#grid").kendoGrid({ 
    scrollable: false,
    sortable: true
}).data("kendoGrid"); 

var ds = grid.dataSource;
grid.columns = [];    
ds.data([{one: 1, two: 1, three: 3, four: 4}]);

Starting from this example, I'm curious to know if, with this management, I can put in each row a command / custom command like "Delete". (Example)

Eventually, how can I handle the command's behavior ? (would be nice to see a confirm window after the click over the command)

Thanks for the attention !

2

There are 2 answers

0
Yordan Asenov On BEST ANSWER

I resolved out with this solution : https://jsfiddle.net/Endrik/smLfh67e/1/

It's very similar to Frederic solution but with few changes.

1) I start from a datasource object, cause I will get my data from remote
If you change the type of data loading in the DataSource object, the example should work equally.

var myDataSource = new kendo.data.DataSource({
    data: [{
            one: "1",
            two: "2",
            three: "3",
            four: "4"
        }, {
            one: "5",
            two: "6",
            three: "7",
            four: "8"
        }]
    });

    myDataSource.fetch();

2) In order to have dynamic columns, I have to convert the data present in my datasource object into an array of values. (Like Frederic's startup collection of objects)

var myDataSourceRowsNumber = myDataSource.total();

var rows = [];
var columns = null;
var columnsCount = 0;

for (var i = 0; i < myDataSourceRowsNumber; i++) {
    var entryArray = [];
    var dataItem = myDataSource.at(i);

    columns = [];

    for (var field in dataItem) {
        if (dataItem.hasOwnProperty(field) && 
            field != 'parent' && 
            field != 'uid' && 
            field != '_events') {

            columns.push({
               field: field,
               value: dataItem[field.toString()]
            });
        }
    }

    columnsCount = columns.length;
    for (var j = 0; j < columnsCount; j++) {
        entryArray.push(dataItem[columns[j].field]);
    }

    rows.push(kendo.observable({
        entries: entryArray
    }));
}

var viewModel = kendo.observable({
    gridRows: rows
});

3) At the end, I create a new Kendo UI grid with my definition of columns.

var finalColumns = [];
for (var k = 0; k <= columnsCount; k++) {
    var entryIndex = "entries[" + k + "]";
    if (k != columnsCount) {
        finalColumns.push({
            field: entryIndex,
            title: columns[k].field
        });
    } else {
        finalColumns.push({
            command: [{
                name: "CustomDelete",
                text: "Delete",
                className: "custom-delete-btn ",
                imageClass: "k-icon k-i-close",
                click: ManageDeleteButtonClick
            }],
            title: "Actions"
        });
    }
}

var configuration = {
    editable: true,
    sortable: true,
    scrollable: false,
    columns: finalColumns
};

function ManageDeleteButtonClick(e) {
    e.preventDefault();
    var dataItem = this.dataItem($(e.target).closest("tr"));
    if (confirm('Are you sure you want to delete this record ?')) {
        // AJAX CALL
        var dataSource = $("#grid").data("kendoGrid").dataSource;
        dataSource.remove(dataItem);
    }
}

var myGrid = $("#grid").kendoGrid(configuration).data("kendoGrid");
kendo.bind($('#example'), viewModel);
0
Frederic On

Get your data first, then create an array for the grid columns based on the data and add a column for the buttons.

Create the grid and attach handler to every button.

http://jsfiddle.net/cp67fpw1/2/

Creating the grid:

var columns = [],
    data = [{
        one: 1,
        two: 1,
        three: 3,
        four: 4,
        five: 5
    }],
    grid;

for (var cx in data[0]) {
    if (data[0].hasOwnProperty(cx)) {
        columns.push({
            field: cx
        })
    }
}

columns.push({
    field: '',
    template: '<a class="k-button" command="doit">do it</a><a class="k-button" command="doitagain">do it again</a>'
});

grid = $("#grid").kendoGrid({
    columns: columns,
    dataSource: new kendo.data.DataSource({
        data: data
    }),
    scrollable: false,
    sortable: true
}).data("kendoGrid");

Adding the button handler:

$('#grid').on('click', '[command="doit"]', doit);

function doit(e) {
    var dataItem = grid.dataSource.getByUid($(this).closest('tr').data('uid'));
}