Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datatable inline editing without editor plugin

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 enter image description here

enter image description here

like image 366
Futuregeek Avatar asked Aug 06 '15 13:08

Futuregeek


People also ask

How do I edit a table inline?

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.

What is inline editing?

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.


3 Answers

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:

  • Detect click on row (you've already done this)
  • Get the data from the row (not at all hard)
  • Populate a form with that data (probably within a modal)
  • Update the server with the new values once the form is submitted
  • Update the row once the server has been updated

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.

like image 121
annoyingmouse Avatar answered Oct 11 '22 05:10

annoyingmouse


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:

  1. 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% " />');
                }
            }
    
  2. 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);
                    }
            });
    
  3. 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');
                    }
                });
            }
    
like image 10
shubham Avatar answered Oct 11 '22 05:10

shubham


The editor license bit me in the butt, so I'm here to hopefully save yours.

Here's how I went about it:

  1. 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' },
      ],
    });
    
  2. 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!

like image 1
Erik Maldonado Avatar answered Oct 11 '22 06:10

Erik Maldonado