Editor: Field disappears after focus is lost, and appears when focused

Editor: Field disappears after focus is lost, and appears when focused

VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

I have one field that when the user inserts a value, the value is checked from the database, and if the value is valid, it automatically sets the value for the next field.

Next field is set using:
datatable.cell(row, 3).data(value);

The cell value is set correctly, but after it looses the focus, the value disappears.
And when it receives the focus, it appears again.

Please see the following video, it will show a live example: https://meocloud.pt/link/7a7fc072-d964-481f-affd-b1548495a59b/Editor.mkv

There is nothing in the code that can cause this, and i'm totally baffled.
Any idea on what can cause this problem, or how to avoid it?

Answers

  • allanallan Posts: 61,438Questions: 1Answers: 10,050 Site admin

    I'm not sure what would cause that I'm afraid. When you submit the data to the server, does it correctly return the data for the whole row after each inline submission?

    Can you show me your code, and even better would be a test case showing the issue so I can debug it.

    Allan

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    Yes, the data correctly sent to the server.

    I can try to create a live example, but i doubt i will be able to replicate the problem.

    I also tried using this code, and it didn't work (with a row selected):
    editor.edit(datatable.rows({ selected: true }).indexes(), false).set("Field3", value);

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    I've used the browser inspect functionality, and when the focus is not on the Cell, there is no value in the cell <td>. Only when focused the cell <td> has (and shows) the value.

  • allanallan Posts: 61,438Questions: 1Answers: 10,050 Site admin

    Its actually the data coming back from the server that I am interested in, rather than that being sent to it. Can you show me an example of the returned JSON when you submit a cell?

    Allan

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    I'm sorry if i was not clear, but the Editor is not using server side data.

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    You can see a live example, that shows the core of the code i'm executing, here.

    Due to the problem discussed here with FF and Edge, i'm not using the onchange as presented in above live example, and i have a slighter complex method that stores and compares the old/new values every time a change happens. I don't think it has any relevance here, so i used the simple version.

    Regarding the problem discussed in this issue, there is a stranger fact:

    • When the table loads, it is populated with some rows from the server. THESE rows do not have this problem.
    • The problem ONLY happens with newly dynamically created rows (you can see in the live example how i'm adding new rows dynamically).

    I'm clueless, i can't see anything in the code that justifies this behavior.
    Do you have any suggestion in order to detect the problem?

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735

    Interesting, the behavior seems to change depending on the browser and how the cell input is exited. Anyway I think there might be a couple issues you can experiment with. Instead of var row = table.rows({selected: true});, which returns an array, maybe you should use var row = table.row({selected: true}); to return just the one row.

    I also think that at the point you are trying to get the data from the name column using table.cell(row, 2).data(table.cell(row, 1).data()); Datatables hasn't updated its data cache so it still has "" as the value for name. You could use the Editor API to get the value. I tried the below here and it seems to work a bit better, depending on how you exit the cell.

        editor.field('name').input().on('change', function(e, d) {
            if (!d) {
                var row = table.row({
                    selected: true
                });
                var name = editor.field('name').val();
                table.cell(row, 1).data(name);
                table.cell(row, 2).data(name);
            }
        });
    

    HTH,
    Kevin

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    Kevin, thank you very much for your analysis.

    Regarding your suggestions:

    1. As i'm using Select: 'single', using table.row vs table.rows seems to have no difference.
    2. I'm sorry if my example mislead you, as the use of the bellow code was just to make it simple:
    table.cell(row, 2).data(table.cell(row, 1).data());
    

    Actually, i'm using something like:

    const value = 'Some value';
    table.cell(row, 2).data(value);
    

    The only suspicions i have with my limited Editor knowledge, would be something like:
    1. Cache
    2. Hiding/disable the field using Editor

    Unfortunately, i can't find any occurrence in the code that could lead to this situation, but i'm surely missing something :(

  • allanallan Posts: 61,438Questions: 1Answers: 10,050 Site admin

    Could you give me step by step instructions for how to reproduce the error? Do I need to use keyboard navigation for example? I wasn't able to reproduce it in Chrome / Linux with mouse interaction, but I might just not be taking the correct steps.

    Thanks,
    Allan

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    Unfortunately, i don't think i will be able to reproduce the problem.
    I tried to create a similar process in this live example, but here everything executes correctly.

    I can send you the full file, but it has too much business logic to be of any use.

    Maybe some type of "reverse engineering" can help analyzing this?

    For example, from a Datatables/Keytable/Editor perspective, and assuming i wanted to do it on purpose (the effect you can see in the video, with the value disappearing after loosing the focus), how could i do it? What API methods i would need to execute to achieve that effect?

  • allanallan Posts: 61,438Questions: 1Answers: 10,050 Site admin

    The chain of events should be that when you click on another cell and call the inline() method, it will check to see if there is another inline editing cell active. If there is, it will wait for that cell to submit and that submit to complete before then making the cell that was clicked on editable.

    What appears to be happening in your video is that it isn't waiting - it immediately makes the other cell editable, while the one which was updated is done in the background.

    Assuming you are using Editor in a configuration like this then I'm afraid, without a test case, I don't know how that can happen.

    Perhaps you can show me your Editor configuration and how you are calling the inline() method please?

    Allan

  • VascoSaavedraVascoSaavedra Posts: 42Questions: 8Answers: 1

    This my editor/datatables configuration (resumed):

                .editor = new $.fn.dataTable.Editor({
                    table: "#" + id,
                    fields: editorFields
                });
    
    
                datatable = $("#" + id).DataTable({
                    ajax: {
                        url: getUrl(),
                        data: createBaseRequest(),
                        type: "POST",
                        datatype: "json",
                        error: function(xhr, error, thrown) {
                            const json = $.parseJSON(xhr.responseText);
                            swal(json.Message, json.ExceptionMessage, "error");
                        },
                        dataSrc: ""
                    },
                    columns: datatableColumns,
                    bPaginate: false,
                    bFilter: false,
                    bInfo: false,
                    bSort: false,
                    bSortable: false,
                    scrollX: true,
                    scrollY: "200px",
                    scrollCollapse: true,
                    keys: {
                        editor: editor,
                        editOnFocus: true
                    },
                    select: {
                        style: 'single'
                    }
                });
    
                // Inline editing on tab focus
                datatable.on('key-focus', function(e, datatable, cell, originalEvent) {
                    datatable.row(cell.index().row).select();
                    editor.inline(cell.index());
                });
    
                // Storing last KeyDown
                datatable.on('keydown', function(e, datatable, cell, originalEvent) {
                    focusKey = e.keyCode;
                });
    
                // Inline editing on click
                datatable.on('click', 'tbody td', function(e) {
                    e.stopPropagation();
                    editor.inline(this);
                });
    
                datatable.on('key-blur', function(e, d, cell) {
                    const td = $(cell.node());
                    const parent = td.parent('tr');
    
                    if (parent.is(':last-child') && td.is(':last-child')) {
                        if (focusKey === addNewLineKey) {
                            addNewRowInternal(datatable);
                        }
                    }
                });
    
  • allanallan Posts: 61,438Questions: 1Answers: 10,050 Site admin
    datatable.on('key-focus', function(e, datatable, cell, originalEvent) {
        datatable.row(cell.index().row).select();
        editor.inline(cell.index());
    });
    

    You almost certainly don't want to do that. Likewise:

    datatable.on('click', 'tbody td', function(e) {
        e.stopPropagation();
        editor.inline(this);
    });
    

    Remove that as well.

    Let KeyTable triggering the inline editing.

    Use keys.editOnFocus if you want KeyTable to activate editing as soon as a cell gets focus.

    Allan

This discussion has been closed.