Jumping to the inserted row after an insert

Jumping to the inserted row after an insert

FurburgerFurburger Posts: 37Questions: 8Answers: 0

Hi

I want to jump to the inserted row in the Datatable after a record is inserted by the Editor

I have a function that finds the row (by its id) and highlights it which I want to call after a new row is inserted.

I decided to try the postCreate event, but it seems that the when this event fires, the row is added to the DataTable object, but it is not in the DOM yet and so my function fails to find it.

It is simple to replicate: Put a debugger statement after the event fires and you will see the row is not there yet.

    editor.on( 'postCreate', function ( e, json, data ) {

      console.log('New row added - is it in the DOM?' );

      debugger;

      
    });

Is there some other method (or event) I can use to accomplish the above?

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    the row is added to the DataTable object, but it is not in the DOM yet and so my function fails to find it.

    This is correct. Because it is possible to add multiple rows, and postCreate is triggered after each row, in order to keep performance manageable it will only do one draw after all rows have been added.

    What to do is use submitComplete which it triggered after the table has been draw:

    editor.on( 'submitComplete', function ( e, json, data ) {
      if ( data.action === 'create' ) {
        ...
      }
    } );
    

    To actually jump to the row, you could use a plug-in such as this one - or do you already have a method for that?

    Regards,
    Allan

  • FurburgerFurburger Posts: 37Questions: 8Answers: 0

    Hi Allan

    Thanks for the quick response.

    I failed to mention that I am using serverSide processing. I have to because we have large datasets (i.e. financial transactions) and the plugin you suggest (and my code) fails because they both expect the row to be in the DOM.

    I was hoping your Editor PHP library would cater for this, i.e. if the created row was added outside the last offset, it would issue a draw() with offset and limit set to include the newly inserted record or just do a full draw with pageLen = -1. But then it is asynchronous and so you have to wait for the ajax success and so I guess things get rather messy.

    I notice that serverSide processing complicates things quite a lot - especially with the situation discussed here and the print and export buttons.

    I may just change back to clientSide processing to resolve all the above issues, but our testing shows considerable delays in loading the data.

    You see . . .we don't use the paging buttons. Our user testing shows considerable negative feedback when users have to click on the next page and then the next page etc. They like scrolling through their data. I agree with them.

    Our application is trying to replace and replicate a desktop experience and our existing users are used to just scrolling down a list. I think that UX is much more intuitive and user-friendly than having to use the page button paradigm and our users seem to agree.

    I am thinking of ways to cache the data before the user even gets to the screen so it looks almost instantaneous to the user. I could create the table in a hidden screen and then just unhide it when the user gets there, but I notice that some of the javascript fails (such as height() ) if an element is hidden so you get a few weird issues if you operate on a hidden table.

    It is quite an issue and I am not sure in which direction to go.

    Any thoughts or comments on the above would be appreciated.

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin
    Answer ✓

    I was hoping your Editor PHP library would cater for this

    No sorry! The position of the new row in the data set is defined by the ordering applied to the table and any filtering - with server-side processing, that can only be determined by the server. The client would need to request that position from the server and then redraw the table to that location.

    How many rows of data are we talking about here? With deferRender and Scroller it should be possible to handle fairly large data sets at the client-side (tens of thousands of rows - depending on how complex the data is of course).

    I notice that serverSide processing complicates things quite a lot - especially with the situation discussed here and the print and export buttons.

    It does yes. The Buttons extension is client-side, so it can only export what is available at the client-side. If the full data set is only available at the server-side, then you'd need to create the export files on the server-side.

    Paging is good because it helps with performance and being able to chuck the data, but scrolling can be really useful for a desktop UI. Its a trade off :smile:.

    Allan

  • FurburgerFurburger Posts: 37Questions: 8Answers: 0

    Hi Allan

    Wow. OK. I have just realised that when we were testing the difference in speed between clientSide and serverSide, we forgot to turn on deferRender when we changed back to clientSide.

    What a difference - it is now much, much faster and totally acceptable.

    Thanks very much - that solves a whole lot of issues.

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    Excellent! Great to hear that deferRender does the job for you :smile:.

    With the next major upgrade to DataTables I'm considering having it enabled by default - the difference it can make is, as you have seen, really significant.

    Regards,
    Allan

  • FurburgerFurburger Posts: 37Questions: 8Answers: 0

    Hi Allan

    The page.jumpToData() plugin doesn't seem to work if:

    1) You have an ajax data source; and
    2) You have Scroller enabled

    If you remove the ajax from this JS Bin

    live.datatables.net/nuhuqeso/2

    you will see that the paging is suddenly available and I can issue commands such as

    table.page( 'next' ).draw( 'page' );
    

    and everything seems to work (from a paging point of view).

    But with the Scroller and the Ajax data source enabled, this functionality is no longer available and so the plugin you recommend does not work.

    Do you have any idea how I can to jump to a new record when using ajax and the Scroller.

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    I think the Scroller aspect will be key here since it hijacks DataTables pagination for its own use, which the plug-in method doesn't take account of.

    Instead, what I would suggest is using the row().scrollTo() method that Scroller adds, along with row-selector being used as a function, which allows the data to be selected.

    For example:

    table
      .row( function ( idx, data, node ) {
        return data.myProperty == 'mySearchValue';
      } )
      .scrollTo();
    

    Regards,
    Allan

  • FurburgerFurburger Posts: 37Questions: 8Answers: 0

    This works well - thanks.

    Last thing: How do I add the selected class to the row that it scrolls to?

    If the inserted row is in the current page, this works, but if the inserted row is not in the current page, node() returns a null and in fact I cannot find it in the DOM.

    var addedRow = addressBookTable.row( function ( idx, data, node ) {
      return data.reference == json.data[0].reference;
    })
    .scrollTo( false );
    
    //This works well and the datatable is now scrolled to the inserted row
    
    //Now lets try and add the selected class to the node
    
    console.log("addedRow node", addedRow.node() ); // Null if not in the current page
    
    $( addedRow.node() ).addClass("selected").siblings().removeClass("selected");
    
    

    BTW I tried adding the "Select" extension to the datatables options, but it made no difference.

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin
    Answer ✓

    Try this:

    table
      .one( 'draw', function () {
        table
          .row( function ( idx, data, node ) {
            return data.myProperty == 'mySearchValue';
          } )
          .select();
      } )
      .row( function ( idx, data, node ) {
        return data.myProperty == 'mySearchValue';
      } )
      .scrollTo();
    

    It isn't ideal since that row selector function is running twice, but since the row doesn't exist on the client-side when you first call that code, you need to wait for it to be loaded before it can be selected (which is why I use one() with draw).

    Allan

  • FurburgerFurburger Posts: 37Questions: 8Answers: 0

    Hi Allan

    I am no longer using the Editor (because I need multiple modals open at the same time) but I applied the above logic to the DataTable and it works very well.

    Once I have saved the record in the backend (and got its id) I do this:

    var id = 1234; // Simulating - this comes from the backend
    
    table.one( 'draw', function () {
        table.row( "#" + id).select();
        table.row( "#" + id).scrollTo( false );
    });
    table.row.add( data ).draw();
    
This discussion has been closed.