Inline editor with custom ajax function loses focus on keytable tab with async success callback

Inline editor with custom ajax function loses focus on keytable tab with async success callback

huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0

Link to test case: Test case
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem: When the editor's success() callback is called asynchronously (e.g. using setTimeout), and tab is used to submit&switch to next field, the editor is moved to the next field, but the focus is lost.

 var editor = new $.fn.dataTable.Editor({
      ajax: function(_method, _url, _data, success, _error) {
        console.log("Entering editor ajax function");
        setTimeout(function() {
          console.log("Before calling success");
          success({"data":[{"id": 1, "name": "Penguins", "position": "Bird", "office": "Beach"}]});
          console.log("After calling success");
        }, 1000);
        console.log("Leaving editor ajax function");
      },
      table: "#example",
      idSrc: "id",
      fields: [{"label": "ID", "name": "id"},
               {"label": "Name", "name": "name"},
               {"label": "Position", "name": "position"},
               {"label": "Office", "name": "office"}],
      formOptions: {
            inline: {
                onBlur: 'submit'
            }
      }
    });
  

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,480Questions: 1Answers: 10,467 Site admin

    It takes a second (due to the timer), but the focus follows for me. It moves the outline to the next field, finishes the submit and then enabled the edit and focuses the cursor I beam on the next cell. Is that not what you are seeing?

    Allan

  • huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0
    edited June 2020

    Ah - sorry, my description has been not quite correct.

    The focus is indeed set to the next cell, but the "hard edit mode / orange border" is not set on the next cell. If you now edit the next cell and press the tab key again, this doesn't result in a submit, as I would have expected.

    If both the editor and the table ajax callbacks are synchronous, the behavior is as expected - see http://live.datatables.net/hucekuje/1/edit, where one can press tab, then edit, then press tab, then edit and so forth in order to edit a series of adjacent cells.

    Another thing to try: In the original test case http://live.datatables.net/vatovuhu/1/edit, do the following:

    • click on the first field ("Penguin"), edit it somehow and press "tab"
    • wait two seconds, then edit the next field ("Bird") somehow
    • if you now press "tab", the focus is moved out of the table to the first pagination button
    • however, if you press "shift-tab" instead of "tab", the focus is moved to the previous field ("Penguin"), which you can then edit

    It seems to me that the hard/soft edit state is not handled correctly (or, at least, consistently) by keytable in this case.

  • allanallan Posts: 63,480Questions: 1Answers: 10,467 Site admin

    Got it now - thank you! It looks like the issue was originally introduced with this commit. I've just committed this patch which fixes it.

    With the original issue, I think it actually should attempt to focus on a cell if it can, even if the original was deleted - the code does that with the latest releases.

    The change will be in the nightly build shortly.

    Allan

  • huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0
    edited June 2020

    Thank you very much for the quick fix - the initial problem is gone.

    However, I think the solution to focus on a cell under all circumstances ("if it can") is not optimal. If the focus is on a certain cell and then, for example, the table is sorted, a completely unrelated other cell is then focused, only because it is at the same location as the old cell.

    Would it be possible to check whether the rowId of the new cell to be focused hasn't changed, and only then focus on the new cell? In other words, if the new cell's rowId is not equal to the old cell's rowId, the focus should be lost.

  • huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0
    edited June 2020

    Upon further thinking and experimenting, I think that the nightly build solution is not only sub-optimal, but not a viable solution at all.

    Assume that the the user edits a cell's value in a way that changes the sort order for that cell's row. Upon pressing "return", he then won't see the newly entered value, but some other value (at least if the old and new value are different). This will be surprising and disorienting.

    If the user doesn't notice the row switch (for example, because the old and new values are sufficiently similar to trick him into believing that he is still editing the old row), it may even lead to him "correcting" the value, thereby corrupting the data.

    Klaus :-)

  • allanallan Posts: 63,480Questions: 1Answers: 10,467 Site admin

    Fair point - you could use the drawType option of the form-options object set to none to disable the sorting and mitigate that issue.

    I need to have a bit of a think about the use of the row id - its a good idea, thanks for the suggestion.

    Allan

  • huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0
    edited June 2020

    I tried setting drawType to 'none'. As you said, this disables the (immediate) sorting. However, the keytable still doesn't behave well: on submitting with "tab", I can see a blue row flash (nice! - this cannot be seen when the draw is enabled), but the focus doesn't move to the next cell, but is lost. If I then sort the table, the focus miraculously reappears.

    Meanwhile, I think the "correct" (and thus, default) behavior for the table and editor should not rely on the row id idea. Instead, the solution should build upon not redrawing the table after an edit, but leaving the edited row in place. Perhaps it could be somehow marked, e.g. with a blue afterglow, in order to show that it has been edited.

    Advantages:

    • It is possible to edit consecutive fields of a row by using tab, because the row will stay in place even when the sorting would move it away.
    • It's the least surprising behavior for the user - no "row jumping on edit".
    • No costly server roundtrip for the unnecessary redraw.
    • The nice blue after-edit flash is visible.

    What do you think?

    Klaus

    P.S.: This could also be done for newly created rows. The default behavior could be to insert them regardless of sorting order at the beginning of the table, somehow marked as new.

  • allanallan Posts: 63,480Questions: 1Answers: 10,467 Site admin
    Answer ✓

    Possibly... :). It is something I've wondered about before, for more or less this reason. The problem is that it leaves the table in an inconsistent state - the sort / filter won't have been applied and I'm not too keen on that.

    It is a valid point though and something we do need to consider more closely. I don't have an immediately fix for you though I'm afraid.

    Allan

  • huxelpuxhuxelpux Posts: 6Questions: 1Answers: 0
    edited June 2020

    OK - my short-term solution will then likely be to not use the editor in combination with keytable, waiting for a fix in the longer term.

    Personally, I don't see a problem with an "inconsistent state". At each moment in time, the state is as the user has wanted it to be: the table is ordered or filtered after the user has ordered or filtered it, and it might not be ordered / filtered after the user has deliberately changed the information in the visible table rows, with the possible exceptions to the sorting / filter regime visibly marked.

    At least, it should be possible to implement a behavior like this without much struggle.

    In any case, thank you for your thoughtful answers! I think you may close the discussion as of now.

    Klaus

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    This has now been addressed. We're hoping to make releases this afternoon which will address this,

    Colin

This discussion has been closed.