Jump to newly AJAX created record

Jump to newly AJAX created record

FedericoVFedericoV Posts: 35Questions: 9Answers: 0

Hi, firs of all I have to say sorry for the question: this topic has already been discussed in the forum but wasn't able to fix my issue.
In my project I have a Datatable that collect data via AJAX, below the link of the page:
https://gavs.it/nuovo/census/admin/records

The user can add new record to the database filling some data into a modal form ( click on the CREA SCHEDA button to show the modal ...in the link the form has been disabled in any case )

After the new data has been added to the database, I'd like to reload the Datatable jumping to the new created record..bb but
I'm not able to do that.
Below the code I'm trying to test but it doesn't work.
As you can see, after a success in AJAX call to create the data, I close the modal and at this point I'd have the code to jump to the new record.
In my page the modal succesfully create the new recor din database ... but nothing happens in Datatable

$.ajax({
    dataType: 'json',
    type:'POST',
    url: form_action,
    data: data,
    processData:false,
    contentType:false,
    cache:false,
    async:true,
}).done(function(data){
    if(data.status)
    {
        $('#recordModal').modal('hide');
        let table = $('#datatable').DataTable();
        let idx = data.idx; // DON'T KNOW HOW TO GET IDX AND WHAT EXACTLY IS
        // Create single event call
        table.one('xhr.dt', function (e, settings, json, xhr) {
             $(table.row(idx).node()).addClass('highlight-row');  //No worky
             table.cell($(table.row(idx).node()).find('td:first')).focus();  //Won't focus
        });
        table.scroller.toPosition(idx);  //Scroll to index works!
    }
    else
    {
        notify(data.notifymsg,data.typemsg);
    }  
}); 

Thanks a lot for any help or hint to fix the issue

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 3,021Questions: 88Answers: 421
    edited July 5

    I would use Editor. Much easier.

    Here is an example from my own coding.

    editor
     .on('submitSuccess', function (e, json, data, action) {   
         if ( action === "create" && typeof json.data[0] !== 'undefined' ) {            
             yourDataTable.row('#' + json.data[0].DT_RowId).select();  // "#row_99"
         }
     })
    

    This one should even work without Editor. Clicking this button I copy a record on the server and on "success" I deselect all current rows, do an ajax.reload and subsequently select the newly created record. That should help, I guess.

    This requires the "select" extension of course.
    https://datatables.net/extensions/select/
    But you might be able to use something similar just using "focus()".

    //custom button to copy a subsidy
    $.fn.dataTable.ext.buttons.copySub = {
        //only enabled when one row is selected (like edit / delete)
        extend: 'selectedSingle', //alternative would be 'selected' (multiple rows)
        text: copySubLabel,
        action: function ( e, dt, button, config ) {            
            var selected = dt.row( {selected: true} );
            if (selected.any()) {
                $.busyLoadFull("show");
                $.ajax({
                    type: "POST",
                    url: 'actions.php?action=copySub',
                    data: {
                        ctrId: selected.data().ctr.id
                    },
                    dataType: 'JSON',
                    success: function (newCtrId) {
                        dt.rows().deselect(); //otherwise the source record remains selected                        
                        dt.ajax.reload( function(){
                            dt.row('#row_' + newCtrId).select();  // "#row_99"
                            $.busyLoadFull("hide");
                        }, false)
                        .columns.adjust()
                        .responsive.recalc();
                    }
                });
            }
        } 
    };  
    
  • FedericoVFedericoV Posts: 35Questions: 9Answers: 0

    Hi rf1234, thanks a lot for your hint. I didn't realize there was the Editor, I'll give it a try for sure.
    For this project I'd like to keep actual code, in any case. Any way to fix the issue with the code above?
    Honestly I'm not sure, from the best user experience, if it would be better to display just the newly created row after the user has sent data from modal form, or just scroll the datatable to get the new record on top of the table.
    Just remember that I use AJAX datatable in the project.
    Again, thanks a lot for any help

  • rf1234rf1234 Posts: 3,021Questions: 88Answers: 421

    Well, my second example does not require Editor. Just the "select" extension which is free. If you don't want to use the "select" extension you would need to use something else which does something similar.

    This line of code makes you "jump" to the defined record and "select" it. Whatever does something similar in your code would need to replace this.

    dt.row('#row_' + newCtrId).select();
    

    "newCtrId" is the id of the newly created record.

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975
    edited July 8

    Your test case link is redirecting to this URL:
    https://gavs.it/nuovo/census/error

    I'm not sure where to find your Datatables init code.

    Just remember that I use AJAX datatable in the project.

    Are you saying you have server side processing ( serverSide: true ) enabled? If yes then it would be difficult to display that record because it likely isn't at the client when trying to scroll to it. It would require finding the record server side then returning that page to Datatables to display.

    We will need more details about the Datatables config, etc. Please provide a link or fix the above to show what you are doing, tell use where to find the Datatables init code and steps to show the issue.

    Kevin

  • FedericoVFedericoV Posts: 35Questions: 9Answers: 0

    Hi kevin and rf1234, thanks a lot for your time and feeback.
    Kevin, you are right: in my config serverSide is true...so the displaied rows in my datatable are selected from mySQL database and then sent to browser...below my code.

    var table = $('#records-datatable');
            table.DataTable({
                responsive: true,
                autoWidth: false,
                searchDelay: 500,
                processing: true,
                serverSide: true,
                stateSave: true,
                mark: {
                    exclude: [".no-marking"],
                },
                ajax: {
                    url: `${controller_url}/list`,
                    type: "POST",
                    "data": function ( d ) {
                        d.csrf_test_name = token_hash;
                    },
                    "dataSrc": function ( json ) {
                        token_hash = json['csrf_test_name'];
                        return json.data;
                    }
                },
                columns: [
                    {data: 'oggetto'},
                    {data: 'tipo'},
                    {data: 'classificazione'},
                    {data: 'regione'},
                    {data: 'stato_scheda'},
                    {data: 'azioni', responsivePriority: -1},
                ],
                rowId: function(a) {
                    return 'id_' + a.uid;
                },
                createdRow: function ( row, data, index ) {
                    $('td', row).eq(5).attr('data-id', data.id);
                },  
                columnDefs: [
                    {
                        targets: -1,
                        orderable: false,
                        searchable: false,
                        render: function(data, type, val, meta) {
                            return `
                            <td><a class="ms-2 text-reset record-action" href="#" data-bs-toggle="tooltip" data-bs-original-title="Immagine scheda"><i class="icon-image"></i></a>
                                <a class="ms-2 text-reset record-action" href="#" data-bs-toggle="tooltip" data-bs-original-title="Cancella scheda"><i class="icon-trash-2"></i></a>
                                <a class="ms-2 text-reset record-action" href="#" data-bs-toggle="tooltip" data-bs-original-title="Completa scheda"><i class="icon-settings"></i></a>
                                ${(() => {
                                    if ( val.stato_scheda == 1) {
                                        return `<a class="ms-2 text-reset record-action" href="#" data-bs-toggle="tooltip" data-bs-original-title="Sospendi"><i class="icon-zap-off"></i></a>`
                                    } else {
                                        return `<a class="ms-2 text-reset record-action" href="#" data-bs-toggle="tooltip" data-bs-original-title="Attiva"><i class="icon-zap"></i></a>`
                                    }
                                })()}
                            </td>`;
                        },
                    },
                    {
                        targets: -2,
                        orderable: false,
                        searchable: false,
                        className: 'no-marking',
                        render: function(data, type, val, meta) {
                            var status = {
                                0: {'title': 'Sospesa', 'class': 'bg-warning'},
                                1: {'title': 'Pubblica', 'class': 'bg-success text-light'},
                            };
                            if (typeof status[data] === 'undefined') {
                                return data;
                            }
                            return '<span class="badge badge-pill no-marking ' + status[data].class + '">' + status[data].title + '</span>';
                        },
                    },
                ],
                language: {"url": `/assets/nuovo/plugins/datatables/_lang/dataTables.${actual_lang}.lang`},
                pagingType: "numbers",
                "drawCallback": function () {
                    $('.dataTables_paginate > .pagination').addClass('pagination-flat');
                }
            });
    

    Maybe, after created the new data, I should reload the AJAX datatable but I'm not sure if it would be possible to select and limit the rows with new record on top of the page.

    Thanks again for any hint or feedback...and sorry if right now I cannot provide a working link

  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin
    Answer ✓

    You'd need the server's response to tell DataTables where it could find the new row in the dataset, so that DataTables can then make the request to jump to that row. Possible, but not something that it will do out of the box.

    Allan

  • FedericoVFedericoV Posts: 35Questions: 9Answers: 0

    Many thanks for your feedback Allan. I'll give it a try.

Sign In or Register to comment.