postEdit javascript event not firing

postEdit javascript event not firing

paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

This my first attempt at an editor.
My code:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script type="text/javascript" language="javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.11.4/js/dataTables.jqueryui.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/2.2.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/2.2.2/js/buttons.jqueryui.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.3.4/js/dataTables.select.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/datetime/1.1.1/js/dataTables.dateTime.min.js"></script>
<script type="text/javascript" language="javascript" src="js/dataTables.editor.min.js"></script>
<script type="text/javascript" language="javascript" src="js/editor.jqueryui.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/editor.jqueryui.min.css" />
<script>
var editor;
$(document).ready(function() {
  editor = new $.fn.dataTable.Editor( {
      ajax: "http://virtual-techno.co.uk/heating/timetable.php",
      table: "#timetable",
            idSrc:  'id',
      fields: [ {
              label: "Start period:",
              name: "pstart"
          }, {
              label: "End period:",
              name: "pend"
          }, {
              label: "Target:",
              name: "target"
                    }
                ]
            });
    
        // Activate an inline edit on click of a table cell
        $('#timetable').on('click','tbody td:not(:first-child)', function (e) {
            editor.inline( this );
        });
                
    var table=$('#timetable').DataTable( {
        ajax: {
            url: "http://virtual-techno.co.uk/heating/timetable.php",
                    type: "get",
                  dataSrc: 'timetable'
                },
                columns: [
                    {data: 'pstart'},
                    {data: 'pend'},
                    {data: 'target'}
                ],
        select: true
            });
        
        // Display the buttons
        new $.fn.dataTable.Buttons( table, [
            { extend: "create", editor: editor },
            { extend: "edit",   editor: editor },
            { extend: "remove", editor: editor }
        ] );
 
        table.buttons().container()
            .prependTo( $('div.fg-toolbar:eq(0)', table.table().container() ) );

            editor.on('postEdit', function (e, json, data, id) {
                    console.table(data);
            }); 
} );

</script>
</head>
<body>
<h1>Timetable</h1>
<table id="timetable">
    <thead>
        <tr>
            <th>Start</th>
            <th>End</th>
            <th>Target</th>
        </tr>
    </thead>
</table>
</body>
</html>

Error messages shown: none
Description of problem:
This creates an editor and shows me the incoming data.
I click a cell and the Edit button. A box appears and I change the data then click "Update".
The screen goes back to showing the original data and the postEdit event does not fire.

I looked for a complete simple example but did not find one.
Suggestions please.

Answers

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951
    edited January 2022

    Sonds like your server script isn't returning the updated data as descried in the Editor client/server docs. Start by using the browser's network inspector to see what is returned by the server script when editing. Also check for errors in the browser's console. Let us know what you find.

    Kevin

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    Thanks @kthorngren for the quick reply.

    But I'm still confused.
    I haven't yet written the server side code for an update.
    This is because I don't know how to configure the update.

    The link you gave gives an idea of what the data will look like. I was hoping just to display that in the browser console to confirm the format.
    Then I need to actually send it.

    In my code I mention the server address twice. I'm wondering if the second reference needs to be a put rather than an ajax get?

    Regards Paul

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Hi Paul,

    I haven't yet written the server side code for an update.

    That's the problem. You've Editor initialisation has:

    ajax: "http://virtual-techno.co.uk/heating/timetable.php",

    Which is telling it to submit the form data there and it expects some JSON back. I'm guessing it is returning valid JSON (since otherwise it would give an error), but exactly what that is - perhaps the same as the original DataTable load?

    Are you planning on using our PHP libraries for Editor? If so, it will handle the create / edit / delete actions for you.

    In my code I mention the server address twice. I'm wondering if the second reference needs to be a put rather than an ajax get?

    Editor will send a POST by default. DataTables sends a GET by default. If you are using our PHP libraries for Editor, that will work just fine.

    If you aren't - you need to look for the POST data when the form is submitted to check what action is being performed based on the action property. The page Kevin linked to gives full details for the client / server communication protocol.

    Allan

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    Thx Allan,

    OK. Made progress.

    Now I say:

          editor = new $.fn.dataTable.Editor( {
          ajax: "http://virtual-techno.co.uk:9090/p",
          type: "post",
          idSrc:  'id',
          fields: [ {
              label: "Start period:",
              name: "pstart"
              }, {
              label: "End period:",
              name: "pend"
              }, {
              label: "Target:",
              name: "target"
        }]
         });
    

    In the express app at 9090 I have

    app.post("/p", (req, res) => {
      console.log(req.data);
    });
    

    No when I edit req produces a lot of output but there's nothing in req.data

    Evidently still misunderstanding something.

    Regards, Paul

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    whoops. I should have written

    console.log(req.body);
    

    this gives a response but I'm not clear on how to parse it.

    'data[': { 'object Object': { pstart: '1', pend: '2', target: '3' } },
      action: 'edit'
    

    I also note that it does not contain a row id

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    I added a content-type header to the post request but it still produces this unparsable response. Any further suggestions please?

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    req.body.data will contain the data object that Editor sends to the server. You'll need also req.body.action to know what action is being performed.

    Then loop over the req.body.data object (since it is an object that contains the row ids) - Object.entries() is useful for that with a for ... in loop.

    Is there something you need to do that the Editor NodeJS libraries won't handle for you? It would save you writing all the database interaction code!

    Allan

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    Hi,
    My plan was (after initial testing) to integrate it into an existing express application.

    The data looks ok on presubmit

    {"[object Object]":{"pstart":"1","pend":"2","target":"3"}}
    

    (Except that the index field for a single-row update is missing,)

    The issue seems to be that the req.body.data object when received at the server is not an object that can be parsed. It looks like it got stringified or something.

    Neither req.body.data nor req.body.action are available in app.post (they did not get parsed out).

    That was why I was looking at the headers.

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    I have at last seen that I was not referencing my table in Editor
    Now we have this on presubmit:

    {"data":{"1":{"pstart":"0","pend":"4","target":"19"}},"action":"edit"}
    

    but there is still no request.body in the express post

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    That suggests to me that the body parameters aren't being parsed in your node server. How are you parsing them? You'll need something like:

    app.use( bodyParser.urlencoded({ extended: true }) );
    

    That is for Express - other frameworks will have something similar.

    Allan

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    If I manually post that to my express application it is accepted without a problem.
    However, if I let Editor post it I get this from express (I added some error handling) :

    SyntaxError: Unexpected token d in JSON at position 0
    

    Just to recap on the call:

      editor = new $.fn.dataTable.Editor( {
          ajax: {
            url: "http://virtual-techno.co.uk:9090/p",
        type: "post",
        dataType: "json",
        contentType: 'application/json'
          },
          table: "#timetable",
          dSrc:  'id',
          fields: [ {
                  label: "Start period:",
                  name: "pstart"
              }, {
                  label: "End period:",
                  name: "pend"
              }, {
                  label: "Target:",
                  name: "target"
         } ]
      });       
    

    I'm not sure what else I can check to see how between correct json on presubmit and fault json received this is failing.

    Regards, Paul

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    OK. I think I found part of the problem.
    This "works" when express is expecting url encoding:

      dataType: "json",
      contentType: 'application/x-www-form-urlencoded'
    

    This does not work when express is expecting json encoding

      dataType: "json",
      contentType: 'application/json'
    

    To my mind this is illogical.

    Anyway, in the first case the request body does not translate properly from

    {"data":{"5":{"pstart":"22","pend":"24","target":"19"}},"action":"edit"}
    

    on presubmit to

      data: [ { pstart: '22', pend: '24', target: '19' } ],
      action: 'edit'
    

    In which the id has been omitted so the DB cannot be updated.

    So, I need to know why the editor sends url encoded data when contentType is set to 'application/json' is specified?

    Any ideas?

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Hi Paul,

    Very interesting - thank you! It isn't something that Editor itself is doing, but we just proxy all the Ajax requests through jQuery.ajax() and it looks like it does some smart handling of the contentType parameter, to change the data that is being submitted based on the value you give. It makes sense that if you tell it to submit application/json then it will send data in that format. That could be decoded in the Node application, or you could continue using body parser without that parameter.

    Regards,
    Allan

  • paul_tannerpaul_tanner Posts: 10Questions: 1Answers: 0

    OK. I bodged it so that the message sent with url encoding is decodable and include the row id.

    editor.on('preSubmit', function ( e, data, action ) {
      for (k in data.data) data.id=k;
      console.log("presubmitting",JSON.stringify(data));
    } );
    

    So now the whole example works. In the event of an error in an update it would be good to signal that. Can.t see how to do that.

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    The JSON return from the server should include the error parameter for a general error, or a fieldErrors array in the case of one or more fields being in error (e.g. validation errors) - full details available in the documentation here.

    Allan

Sign In or Register to comment.