dot dot - 4 months ago 54
jQuery Question

jquery dataTables - how to add an edit and delete option

I have the following code: http://jsfiddle.net/5ooyertu/1/

Right now, the table is being populated properly via the server side, and my paging works. But I'd like to add the ability to delete and or edit a row. I would like to add a column called "Actions" that has two - one to an edit method... and the other to a delete method.

Prior to using dataTables, I had some JavaScript logic that would iterate through an array of records from an Ajax, call and populate a regular table with the data, and the appropriate hyper-links.

for (var i=0; i < data.length; i++) {
if (data[i].grp == 0) {
tr.append("<a href='add.html?id=" + data[i].id + "&pid=" + data[i].pid + "&destination=" + data[i].destination + "&name=" + data[i].name.replace("'", "%27") + "'</a><button class='btn btn-xs btn-primary'>Edit</button>&nbsp;</td>");
tr.append("<button class='btn btn-xs btn-primary' onclick='delete(" + data[i].id + "," + data[i].pid + ");'>Delete</button></td>")

} else {
tr.append("<a href='update_group.html?id=" + data[i].id + "&pid=" + data[i].pid + "&destination=" + data[i].destination + "&name=" + data[i].name.replace("'", "%27") + "'</a><button class='btn btn-xs btn-primary'>Edit</button>&nbsp;</td>");
tr.append("<button class='btn btn-xs btn-primary' onclick='delete(" + data[i].id + "," + data[i].pid + ",true);'>Delete</button></td>")
}
}


As you can see from the above code example, in my hyperlinks, I need to pass a few pieces of data from each row, either as a part of the query string (in the case of edits) or just pass them as parameters to another JavaScript function called "delete" that lives in the same file as this dataTable. And it's conditional... meaning, the hyperlinks will change depending on whether grp is true / false.

I am wondering how I can change the logic that populates the dataTable to now include these two hyper-links?

I found this link: http://datatables.net/forums/discussion/5862/creating-an-action-column-for-icons-view-edit-delete# But the code didn't work for me and I think I read somewhere that the fnRender method is deprecated now.

If you have any suggestions, I'd appreciate it.

EDIT 1

I tried to change my code to look like this:

$(document).ready(function() {
var selected = [];
$('#users').DataTable( {

"serverSide": true,
"ordering": false,
aLengthMenu: [
[10, 25, 50, 100, "-1"],
[10, 25, 50, 100, "All"]
],
"ajax": "/cgi-bin/test",
"rowCallback": function( row, data ) {
if ( $.inArray(data.DT_RowId, selected) !== -1 ) {
$(row).addClass('selected');
}
},
"columns":
[
{ "data": "id" ,"searchable":false},
{ "data": "name","searchable":true},
{ "data": "pid", "searchable":true },
{ "data": "destination", "searchable":true },
{"mRender": function ( data, type, row ) {
return '<a href=add.html?id="'+row[0]+'">Edit</a>';}
}
]
} );

} );


Notice the call reference to render. I also added a new column to my table in my html code. I do get a hyperlink! But unfortunately, the link is incorrect. row[0] returns "undefined". Also, I still don't know how to change the hyperlink i create depending on the value of the field "destination".
So for example, I want to do something like this: (pseudocode)

if row[i].destination = 'Group' then
{"mRender": function ( data, type, row ) {
return '<a href=group.html?id="'+row[0]+'">Edit</a>';}
}
else
{"mRender": function ( data, type, row ) {
return '<a href=add.html?id="'+row[0]+'">Edit</a>';}
}
end


EDIT 2

This code seems to work:

$(document).ready(function() {
var selected = [];
$('#users').DataTable( {

"serverSide": true,
"ordering": false,
aLengthMenu: [
[10, 25, 50, 100, "-1"],
[10, 25, 50, 100, "All"]
],
"ajax": "/cgi-bin/test",
"rowCallback": function( row, data ) {
if ( $.inArray(data.DT_RowId, selected) !== -1 ) {
$(row).addClass('selected');
}
},
"columns":
[
{ "data": "id" ,"searchable":false},
{ "data": "name","searchable":true},
{ "data": "pid", "searchable":true },
{ "data": "destination", "searchable":true },
{"mRender": function ( data, type, row ) {
return '<a href=add.html?id='+row.id+'>Edit</a>';}
}
]
} );


now I just need to figure out how to make it conditional.

Answer

Here you have an example assuming the following:

  • Ajax population
  • Data row is an array containing 4 columns
  • Your data row contains the id on first column
  • You don't display id on table so you hide it

It shouldn't be hard to adapt it to your needs. Check columns usage

var datatablesOptions = {
    "serverSide": true,
    "ajaxSource": '[yourAjaxUrl]',
    "processing": true,
    "columns": [
        { bVisible = false }, // assume this is the id of the row, so don't show it
        null,
        null,
        null,
        /* EDIT */ {
            mRender: function (data, type, row) {
                return '<a class="table-edit" data-id="' + row[0] + '">EDIT</a>'
            }
        }
        /* DELETE */ {
            mRender: function (data, type, row) {
                return '<a class="table-delete" data-id="' + row[0] + '">DELETE</a>'
            }
        },              
     ]
};
$('#table').dataTable(datatablesOptions);

EDIT

In case you need to conditional render something different depending on destination you could do

mRender: function (data, type, row) {
    if (row.destination == "d1") {
        return '<a href="destination1?id=' + row.id + '">EDIT</a>'
    }else (row.destination == "d2"){
        return '<a href="destination2?id=' + row.id + '">EDIT</a>'
    } else {
        // some error telling that destination value is unexpected
    }
}