Since your question (and posted code sample) are mostly concerned with front-end part of editable rows feature I will focus on that primarily as backend logic is pretty much straightforward (update/insert data into storage upon AJAX-request receipt).
In order to implement that feature following logic I may suggest:
- append (by means of
createdRow
option) some anchor (row().index()
or source object id
property, etc) to your source data within some <tr>
attribute (e.g. rowindex
), so you will know later on which entry to modify server-side:
$('table').DataTable({
...
createdRow: (tr, _, rowIndex) => $(tr).attr('rowindex', rowIndex)
})
- append some anchor attribute (e.g.
data-src
) to your editor pop-up (I'll use bootstrap-4 modal for that purpose) <input>
nodes to link those input fields to corresponding source object properties:
<div><label>PropertyX:</label><input data-src="propertyX"></input></div>
- upon clicking edit button, grab corresponding row data, populate editor pop-up
<input>
fields with that data, pass anchor to edited row (rowindex
attribute value) over to pop-up attribute:
//for table id 'example' handle clicking
//edit button having class 'edit'
$('#example').on('click', '.edit', function () {
//get clicked row invoking row() API method
//against DataTables object assigned to dataTable
const rowClicked = dataTable.row($(this).closest('tr'));
//populate edit form with row data by corresponding
//rowClicked property based on 'data-src' attribute
$.each($('#editform input'), function () {
$(this).val(rowClicked.data()[$(this).attr('data-src')]);
});
//set modal attribute rowindex to corresponding row index
$('#editform').attr('rowindex', rowClicked.index());
//open up edit form modal
$('#editform').modal('toggle');
});
- upon completing row data editing, store
<input>
values into object:
const modifiedData = {};
$.each($('#editform input'), function(){
Object.assign(modifiedData, {[$(this).attr('data-src')]:$(this).val()});
});
POST
data (along with corresponding rowindex
) to the server and reload (ajax.reload()
) up-to-date datatable upon success:
$.ajax({
url: '/editrow',
method: 'POST',
data: {id: $('#editform').attr('rowindex'), ...modifiedData},
success: () => {
$('#editform').modal('hide');
dataTable.ajax.reload();
}
});
Complete live demo of that method you might examine in your browser's DevTools by the following link with some bonus in form of row delete button.
Both HTML and jQuery code sample might look as follows (not executable as there's no supporting backend):
$(document).ready(() => {
//data table initialization
const dataTable = $('#example').DataTable({
ajax: {
url: '/getdata',
type: 'GET',
dataSrc: ''
},
dom: 't',
//use <tr> attribute 'rowindex' to anchor to source data row index
createdRow: (tr, _, rowIndex) => $(tr).attr('rowindex', rowIndex),
columns: [
{data: 'name', title: 'Name'},
//append 'Edit'/'Delete' buttons to the rightmost edge of the cell
{data: 'title', title: 'Title', render: (cellData, _, __, meta) => cellData+'<i class="delete fa fa-trash"></i><i class="edit fa fa-pencil"></i></button>'}
],
});
//delete button handler
$('#example').on('click', '.delete', function() {
//extract the index of the row to delete
//from 'rowindex' attribute
const rowIndex = $(this)
.closest('tr')
.attr('rowindex');
//do AJAX-call to the backend
$.ajax({
url: '/deleterow',
method: 'DELETE',
data: {id: rowIndex},
//re-draw datatable with up to date data
success: () => dataTable.ajax.reload()
});
});
//edit button handler (open up edit form modal)
$('#example').on('click', '.edit', function(){
//get clicked row
const rowClicked = dataTable.row($(this).closest('tr'));
//populate edit form with row data by corresponding
//rowClicked property based on 'data-src' attribute
$.each($('#editform input'), function(){
$(this).val(rowClicked.data()[$(this).attr('data-src')]);
});
//set modal attribute rowindex to corresponding row index
$('#editform').attr('rowindex', rowClicked.index());
//open up edit form modal
$('#editform').modal('toggle');
});
//submit edits handler
$('#editform').on('click', '#submitedits', function(){
//grab modified data into object
const modifiedData = {};
$.each($('#editform input'), function(){
Object.assign(modifiedData, {[$(this).attr('data-src')]:$(this).val()});
});
//send modified data to the backend
$.ajax({
url: '/editrow',
method: 'POST',
data: {id: $('#editform').attr('rowindex'), ...modifiedData},
success: () => {
//close the modal
$('#editform').modal('hide');
//re-draw datatable
dataTable.ajax.reload();
}
});
});
});
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://use.fontawesome.com/937a319e2f.js"></script>
<script type="application/javascript" src="/main.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/main.css">
</head>
<body>
<!-- Table -->
<table id="example"></table>
<!-- Modal -->
<div class="modal fade" id="editform" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Row details</h5>
</div>
<div class="modal-body">
<form>
<div class="form-group"><label>Name:</label><input data-src="name" class="form-control"></input></div>
<div class="form-group"><label>Title:</label><input data-src="title" class="form-control"></input></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-outline-dark" id="submitedits">Save changes</button>
</div>
</div>
</div>
</div>
</body>
</html>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…