I was using 'editor' plugin for data table and following was the code:
Data table editor defined as:
editor = new $.fn.dataTable.Editor( {
ajax: '/contact/' + Contact.id,
table: "#contact-datatable",
fields: [ {
name: "id",
}, {
name: "category",
type: "check",
options: [
{ label: 'Science', value: "Science" },
{ label: 'Maths', value: 'Maths' },
{ label: 'Economics', value: 'Economics' },
]
}
................
]
});
.....
$('#contact-datatable').on( 'click', 'tbody td:not(:first-child)', function (e) {
editor.inline( this, { submitOnBlur: true } );
} );
Attaching the page with this: When we click on Category, it shows a dropdown for editing (using editor plugin).
But the problem is datatables' editor plugin is not opensource and my project doesn't allow a payable plugin at all.
Can anyone please help me for inline editing in datatables with out 'editor' plugin?
Following is the code I wrote without editor :
Contact.dataTable = $('#contact-datatable').dataTable( {
"ajax": {
"url" : '/Contact/list/' + Contact.id,
"dataSrc": function(check) {
check.id = Contact.id;
return json.check;
},
},
"responsive": true,
"order": [],
"columns": [
{ "data": "id"},
{ "data": "category" },
{ "data": "course" },
]
} );
Category and Course will be a dropdown - and this has to be edit inline. Below attached a page example.
I need 'Category' as an inline editor dropdown and then there will be a button to save
Inline editing, as shown demonstrated in this section, is designed to allow rapid editing of individual fields in a table. The most common use case is to simply click on the cell you want to edit and then hit return once the edit is complete. This will save the data and the row will be immediately updated.
Inline editing allows users to edit fields directly from a table, without using a form. So instead of jumping between edit forms to update different records, all changes can be made from the same page.
Datatables rock! And SpryMedia let us play with it for free! I'm not 100% sure I've used the Editor Plugin despite buying it but I am pleased that I've contributed to its development in some way. One of the main reasons I've not used the plugin is because I was too skint to afford it for a while so wrote my own versions and that's really not that difficult. The steps are quite simple:
The plugin makes all that easy and allows you to figure out the backend as well. The steps above aren't all that difficult but I've not come across something that does it all for you except for the Editor Plugin. Work through the steps and you'll get there.
I wrote my own code for editing inline and made it such that you can edit complete row and define the columns you want to be editable by user.
here : https://github.com/sinhashubh/datatable-examples
Steps to do this:
Handle click even on the clicked row/cell.
$("#dtexample tbody").on('click', 'tr td', function (e) {
RoweditMode($(this).parent());
});
function RoweditMode(rowid) {
var prevRow;
var rowIndexVlaue = parseInt(rowid.attr("indexv"));
if (editIndexTable == -1) {
saveRowIntoArray(rowid);
rowid.attr("editState", "editState");
editIndexTable = rowid.rowIndex;
setEditStateValue(rowid, rowIndexVlaue + 2);
}
else {
prevRow = $("[editState=editState]");
prevRow.attr("editState", "");
rowid.attr("editState", "editState");
editIndexTable = rowIndexVlaue;
saveArrayIntoRow(prevRow);
saveRowIntoArray(rowid);
setEditStateValue(rowid, rowIndexVlaue + 2);
}
}
function saveArrayIntoRow(cureentCells) {
for (var k in EditRowData) {
$($(cureentCells).children('.' + k)[0]).html(EditRowData[k]);
}
}
function saveRowIntoArray(cureentCells) {
$.each(ColumnData, function (index, element) {
if (element.Editable == true) {
var htmlVal = $($(cureentCells).children('.' + element.Name)[0]).html();
EditRowData[element.Name] = htmlVal;
}
});
}
function setEditStateValue(td1, indexRow) {
for (var k in EditRowData) {
$($(td1).children('.' + k)[0]).html('<input value="' + EditRowData[k] + '" class="userinput" style="width: 99% " />');
}
}
On pressing Enter after inputting anything, bind enter input (You can change it to maybe a save button as you like.
$("#dtexample tbody").on('keyup', 'input.userinput', function (e) {
if (e.keyCode == 13) {
updateRowData(this.parentNode.parentNode);
}
});
Update function to make call to server with parameters.
function updateRowData(currentCells) {
var table = $("#dtexample").DataTable();
var row = table.row(currentCells);
rowid = currentCells.getAttribute('id');
var UpdateRowData = [];
$.each(ColumnData, function (index, element) {
if (element.Editable==true) {
UpdateRowData.push({
'pname': element.Name , 'pvalue': $($($(currentCells).children('.' + element.Name)).children('input')[0]).val()
});
}
});
console.log(UpdateRowData);
UpdateRowData.push({ 'pname': 'rowid', 'pvalue': rowid });
var parameter = "";
for (i = 0; i < UpdateRowData.length; i++) {
if (i == UpdateRowData.length - 1)
parameter = parameter + UpdateRowData[i].pname + "=" + UpdateRowData[i].pvalue;
else
parameter = parameter + UpdateRowData[i].pname + "=" + UpdateRowData[i].pvalue + "&";
}
$.ajax({
type: 'POST',
url: '/WebService.asmx/UpdateTableData',
data: parameter,
success: function (data) {
var table = $('#dtexample').DataTable();
table.draw('page');
}
});
}
The editor license bit me in the butt, so I'm here to hopefully save yours.
Here's how I went about it:
When creating the table, add the class 'editable' to any element you'd like to edit
example = new DataTable('#example', {
columns: [
{ data: 'domain', name: 'domain' },
{ data: 'owner1', name: 'owner1', className: 'editable' },
{ data: 'owner2', name: 'owner2', className: 'editable' },
{ data: 'description', name: 'description', className: 'editable' },
{ data: 'account_state', name: 'account-state' },
],
});
Create mouse events for when you enter/exit a td. I chose to create an input element with mouse hover because I didn't want actual html inputs everywhere
// when the mouse enters a cell, create an editor.
$('#example').on('mouseenter', 'td.editable', function (e) {
e.preventDefault() // I'm a noob, don't know what this means
// I think there is some delay on when the events trigger
// so sometimes the cell still contains the input element and this check
// prevents accidently creating another input element
if (e.target.localName != 'input') {
let row = e.target._DT_CellIndex.row
let col = e.target._DT_CellIndex.column
if (!e.target.children.length) {
e.target.innerHTML = `<input id="${row}-${col}" type="text" class="editor" value="${e.target.innerHTML}">`
}
}
})
// when the mouse exits the editor, write the data into the table and redraw
$('#example').on('mouseleave', 'td.editable', function (e) {
e.preventDefault()
if (e.target.localName != 'input') {
let row = e.target._DT_CellIndex.row
let col = e.target._DT_CellIndex.column
data_table.cell(row, col).data(e.target.firstElementChild.value)
data_table.draw() // up to you
}
else { // forces write when there is an event delay
let [row, col] = e.target.id.split('-')
data_table.cell(Number(row), Number(col)).data(e.target.value)
}
data_table.draw()
})
That's it!
My table is at most about 2000 entries (definitely still usable), but I 'm sure there are performance improvements, and I'd love to know them!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With