Is there any way to edit rows in DataTables?

问题: I have a datatable that fetches records from database with ajax. I want to add the edit tooltip like jquery-datatables-editor extension to datatables but for free. Is there...

问题:

I have a datatable that fetches records from database with ajax. I want to add the edit tooltip like extension to but for free. Is there any plugin to do this? if not, can any one help me to do this manually?

This is my JavaScript code:

$('#table_id').DataTable({
    "serverSide": true,
    "processing": true,
    "ajax": function (data, callback, settings) {
        $.ajax({
            url: '/some url',
            type: 'GET',
            data: data,
            success: function (data) {
                console.log(data)
            }
        });

    },
    "columns": [{
            "title": "edit",
            "data": null,
            "className": "center",
            "defaultContent": '<a href = "" class = "editor_edit"> Edit </a>  /  <a href = "" class = "editor_remove"> Delete </a>'
        }, {
            "title": "name",
            "data": "name"
        }, {
            "title": "id",
            "data": "id"
        },

    ]
});

回答1:

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 in local 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 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>


回答2:

If you mean JQUERY DATATABLE then you can insert input fields (that would still retain the cell data) for every column within your table row as you desire and set the borders of the input field to not display, with css.

EXAMPLE TABLE

 <style>
  .no-input-border {
    border: 'none' !important; background: 'none' !important;
   }
 </style>
 <table id="dynamic_table">
   <thead>
     <tr>
       <th>Name</th>
       <th>State</th>
       <th>Address</th>
       <th>Active</th>
       <th>Action</th> <!-- This column would hold your buttons -->
     </tr>
   </thead>
   <tbody>
   </tbody>
</table>

EXAMPLE DATATABLE INITIALIZATION

 var table = $('#dynamic_table').DataTable({
          "order":[[ 0, 'asc' ]], // order by first column
          "processing": true,
          'paging': true,
          'searching': true,
          'retrieve': true,
          'serverSide': true,
          'ajax': {
              'url': "your-ajax-url",
              'type': 'POST'
          },
          'columns': [ //every **name:** value must be present in your json
              { data: null, name: 'name'},
              { data: null, name: 'state' },
              { data: null, name: 'address' },
              { data: null, name: 'active' },
              { data: null, name: 'id' } // column that holds your buttons
          ],
          "columnDefs": [
             {
                "targets": 0,  // column that inserts an input field
                "data":  'name',
                "orderable": false,
                "createdCell": function (td, cellData, rowData, row, col){
                  return '<input type="text" class="no-input-border" name="name" value="'+cellData+'" />'
                }
             },
             {
                "targets": 1,  // column that inserts an input field
                "data":  'state',
                "orderable": false,
                "createdCell": function (td, cellData, rowData, row, col){
                  return '<input type="text" class="no-input-border" name="state" value="'+cellData+'" />'
                }
             },
             {
                "targets": 2,  // column that inserts an input field
                "data":  'address',
                "orderable": false,
                "createdCell": function (td, cellData, rowData, row, col){
                  return '<input type="text" class="no-input-border" name="state" value="'+cellData+'" />'
                }
             },
             {
                "targets": 3,  // column that inserts an input field
                "data":  'active',
                "orderable": false,
                "createdCell": function (td, cellData, rowData, row, col){
                  return '<input type="text" class="no-input-border" name="active" value="'+cellData+'" />'
                }
             },
             {
                "targets": 4,  // column that holds your buttons
                "data":  'id',
                "orderable": false,
                "createdCell": function (td, cellData, rowData, row, col){
                  return '<button class="edit_row">Edit<button>'
                }
             }
          ],
          'responsive': true,
          'initComplete': function(settings, json) {
            //Run a function when table first initializes
          },
          'drawCallback': function( settings ) {
            //Run a function anytime table reloads when paginating
          }
      });

EXAMPLE DATATABLE ROW EDIT FUNCTION

$('#dynamic_table tbody').on('click', '.edit_row', function () {
  var row = table.row( $(this).parents('tr') ); // row that was clicked
  var d = row.data(); // data of the row button that was clicked .eg. console.log(d.name)
  var index = row.index();
  var json = { // json to be sent
        id: d.id,
        name: table.cell(index,0).nodes().to$().find('input').val(),
        state: table.cell(index,1).nodes().to$().find('input').val(),
        address: table.cell(index,2).nodes().to$().find('input').val(),
        active: table.cell(index,3).nodes().to$().find('input').val()
   }
  /*Your Ajax Function Here*/
});

RELOAD DATATABLE FUNCTION

table.ajax.reload( function ( json ) {
  //Run function after table reloads
});  

回答3:

You can create a custom button in datatable. You can go to this documentation to know how it works. Now in the action you can call some function inside it when the user click it the button will call the function in javascript and do what you want inside it.

Here's example code.

$('#table_id').DataTable({
"serverSide": true,
"processing": true,
"ajax": function (data, callback, settings) {
    $.ajax({
        url: '/some url',
        type: 'GET',
        data: data,
        success: function (data) {
            console.log(data)
        }
    });

    },
   buttons: [
    { text: 'Add', name: 'btnAdd', action: function ( e, dt, node, config ) {
                $.fn.addfunction();
            }},
    { extend: 'selected', text: 'Edit', name: 'btnEdit', action: function ( e, dt, node, config ) {
                $.fn.editfunction();
            }},
    { extend: 'selected',  text: 'Delete', name: 'btnDelete', action: function ( e, dt, node, config ) {
                $.fn.deletefunction();
            }},
   ],
   "columns": [{
        "title": "edit",
        "data": null,
        "className": "center",
        "defaultContent": '<a href = "" class = "editor_edit"> Edit </a>  /  <a href = "" class = "editor_remove"> Delete </a>'
     }, {
        "title": "name",
        "data": "name"
     }, {
        "title": "id",
        "data": "id"
     },

    ]
});

$.fn.addfunction = function(){
//Your code here
}

$.fn.editfunction = function(){
//Your code here
}

$.fn.deletefunction = function(){
//Your code here
}

I added the idea of this document from datatables that create custom button and create and call function in jquery

There's also other way by using and giving id for the button. here's the example:

$('#table_id').DataTable({
    "serverSide": true,
    "processing": true,
    "ajax": function (data, callback, settings) {
        $.ajax({
            url: '/some url',
            type: 'GET',
            data: data,
            success: function (data) {
                console.log(data)
            }
        });

        },
       buttons: [
        { text: 'Add', name: 'btnAdd', 
        attr:{
         id: 'btnAdd'
        }},
        { extend: 'selected',  text: 'Edit', name: 'btnEdit', 
        attr:{
         id: 'btnEdit'
        }},
        { extend: 'selected',  text: 'Delete', name: 'btnDelete', 
        attr:{
         id: 'btnDelete'
        }},
       ],
       "columns": [{
            "title": "edit",
            "data": null,
            "className": "center",
            "defaultContent": '<a href = "" class = "editor_edit"> Edit </a>  /  <a href = "" class = "editor_remove"> Delete </a>'
        }, {
            "title": "name",
            "data": "name"
        }, {
            "title": "id",
            "data": "id"
        },

       ]
    });

    $(document).on('click', '#btnAdd', function(e)
        {
          e.preventDefault();
          e.stopPropagation();
          //your code here
        });

    $(document).on('click', '#btnEdit', function(e)
        {
          e.preventDefault();
          e.stopPropagation();
          //your code here
        });

    $(document).on('click', '#btnDelete', function(e)
            {
              e.preventDefault();
              e.stopPropagation();
              //your code here
            });

Sorry for many Edit Hope it helps!

  • 发表于 2019-07-05 08:38
  • 阅读 ( 3131 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除