Possible Editor bug?: DELETE data is different than EDIT data

Possible Editor bug?: DELETE data is different than EDIT data

burncharburnchar Posts: 118Questions: 12Answers: 0
edited September 2015 in Free community support

I've come across a strange problem which seems likely to be an Editor bug because it involves the format of data Editor sends to the server. I loosely suspect some incompatibility with use of idSrc: 0

EDIT sends row names & values as expected.
DELETE sends only row values, and also sends row 0 which is not even in the editor's fields.

This is causing problems because the server expects editor operations to send the same format, as is described in http://editor.datatables.net/manual/server

Examples:

action  edit
data[row_1][ID] 1
data[row_2][NAME]   Administrator
data[row_3][DESCRIPTION]    TableMan Administrators
action  remove
data[row_0][]   row_0
data[row_1][]   1
data[row_2][]   Administrator
data[row_3][]   TableMan Administrators

(This is URL-encoded data as interpreted by Fiddler for easier readability)

Normally, I use send JSON from the web browser (the code for this can be seen commented below).

Also, normally I send more info than just row number within the row ID, though this doesn't appear to have anything to do with the problem. Still, here is some actual data (formatted):

DT Debugger code: esikus

{
    "action": "edit",
    "data": {
        "{\"P\":\"AAAX88AAJAAAAGXAAA\",\"T\":\"10645061192435\",\"C\":{\"ID\":1,\"NAME\":\"Administrator\",\"DESCRIPTION\":\"TableMan Administrators\"}}": {
            "ID": "1",
            "NAME": "Administrator",
            "DESCRIPTION": "TableMan Administrators"
        }
    }
}
{
    "action": "remove",
    "data": {
        "{\"P\":\"AAAX88AAJAAAAGXAAA\",\"T\":\"10681190045017\",\"C\":{\"ID\":1,\"NAME\":\"Administrator\",\"DESCRIPTION\":\"TableMan Administrators\"}}": ["{\"P\":\"AAAX88AAJAAAAGXAAA\",\"T\":\"10681190045017\",\"C\":{\"ID\":1,\"NAME\":\"Administrator\",\"DESCRIPTION\":\"TableMan Administrators\"}}",
        1,
        "Administrator",
        "TableMan Administrators"]
    }
}

The HTML and JS involved can be seen below:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Foo</title>
        <link href="/TableMan/Content/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="/TableMan/Content/bootstrap/bootstrap-theme.min.css" rel="stylesheet" />
        <link href="/TableMan/Content/site.css" rel="stylesheet" />
      </head>
      <body>
      <div class="container body-content">
        <h1>Editing ACCESSGROUP</h1>
        <table id="editor" class="table table-striped table-bordered">
          <thead>
            <tr>
              <th>ID</th>
              <th>NAME</th>
              <th>DESCRIPTION</th>
            </tr>
          </thead>
          <tfoot>
            <tr>
              <th>ID</th>
              <th>NAME</th>
              <th>DESCRIPTION</th>
            </tr>
          </tfoot>
        </table>
      </div>
      <script src="/TableMan/Scripts/jquery-2.1.4.js"></script> 
      <script src="/TableMan/Scripts/bootstrap.min.js"></script> 
      <script src="/TableMan/Scripts/moment.min.js"></script> 
      <script src="/TableMan/Scripts/tm.min.js"></script></body>
        <script type="text/javascript">
            var restUrl = '/TableMan/API/Crud?e=1';

            function restAjaxCall(method, url, data, successCallback, errorCallback) {
                $.ajax({
                    method: method,
                    url: restUrl,
                    data: JSON.stringify(data),
                    dataType: 'json',
                    contentType: "application/json"
                })
                .done(function(json) { successCallback(json); })
                .error(function(xhr, error, thrown) { errorCallback(xhr, error, thrown); });
            };

            var editor;
            $(document).ready(function() {
                var reportTitle = "TableMan ACCESSGROUP saved " + moment().format();
                editor = new $.fn.dataTable.Editor({
                    idSrc: 0,
                    table: "#editor",
                    fields: [{"name":"ID","data":1,"label":"ID"},{"name":"NAME","data":2,"label":"NAME"},{"name":"DESCRIPTION","data":3,"label":"DESCRIPTION"}],
                    ajax: {
                        create: function(method, url, data, success, error) { restAjaxCall('POST',   url, data, success, error) },
                        edit:   function(method, url, data, success, error) { restAjaxCall('PUT',    url, data, success, error) },
                        remove: function(method, url, data, success, error) { restAjaxCall('DELETE', url, data, success, error) }
                    }
                    //ajax: {
                    //  create: { url: restUrl, type: 'POST' },
                    //  edit:   { url: restUrl, type: 'PUT' },
                    //  remove: { url: restUrl, type: 'DELETE' }
                    //}
            });


            function duplicateRow(e, dt, node, config) {
                var values = editor.edit($dataTable.row( { selected:true }).index(), false).val();
                editor.create({title: "Duplicate record", buttons: "Create from existing"}).set(values);
            };

            var $dtOptions = {
                dom: "Bfrtip",
                deferRender: true,
                select: true,
                serverSide: true,
                processing: true,
                "ajax": {
                    url: '/TableMan/API/Crud' + "?e=" + 1
                },
                columns: [{"data":1,"visible":false,"searchable":false},{"data":2,"searchable":false},{"data":3,"searchable":false}],
                buttons: [
                    { extend: "create", editor: editor  },
                    {
                        extend: "selectedSingle",
                        text: "Duplicate",
                        action: duplicateRow
                    },
                    { extend: "edit",   editor: editor  },
                    { extend: "remove", editor: editor   },
                    {
                        extend: "collection",
                        text: "Export",
                        title: reportTitle,
                        buttons: [
                            'copy',
                            'excel',
                            'csv',
                            'pdf',
                            'print'
                        ]
                    }
                ]
            };

            var $dtOverrides = {};
            var $dataTable = $('#editor').DataTable($.extend(true, $dtOptions, $dtOverrides));
        });
        </script>
    </html>

Any idea what is going on?

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,210Questions: 1Answers: 10,415 Site admin
    Answer ✓

    Hi,

    The reason that this is happening is that on delete Editor is sending back the row information - there is no form information on delete since the field values are effectively irrelevant for a delete action.

    The data sent on delete is the same as would be returned from row().data().

    In this particular case it looks like you are populating your table with arrays rather than objects, and there is a primary key included in the data set for the row. If you were to use objects, then the only difference would be the primary key which would also be included.

    It would be possible to drop Editor into editing mode for the rows to be deleted, read their values and then populate the data from the form, but that could result in a lot of complexity ("why are my change events triggering on delete?", etc).

    Interesting one...

    Allan

  • burncharburnchar Posts: 118Questions: 12Answers: 0

    It sounds like this is expected behavior (more ore less), so I'll look into two ideas that come to mind:
    1) Go back to using a different server-side data type for delete requests
    2) Convert request data for create/update to an array

    2 sounds hackish because I'd be creating a custom data format instead of using Editor's. A small reduction in data size and consistent incoming types would be the only benefits.

    1 is probably what I'll do with. My code is already considerably simpler now that Editor's types are so much more consistent, even with this small issue when using arrays.

    As an aside, I think Editor and DataTables benefit greatly from their ability to use arrays for serious applications, but they probably feel like second-class data structures in the documentation. Poor arrays. :)

This discussion has been closed.