Scroll to new row

Scroll to new row

markmcwmarkmcw Posts: 12Questions: 0Answers: 0

Hey,

Looking for some advice.

I've implemented an AJAX datatable onto a php site.

The idea is that users can add a 'song' into the table via a form (this form adds a new row into the DB, then performs a reload of the table once completed).

This works great, the new song is added in the correct position etc.

However, I would love to scroll the table to this new row when it's added. I was planning on doing this by using lastindexof or indexof and searching a hidden field for the unique song ID.

This works ONLY when I refresh the page or try scrolling to a row that was already in the table when the page first loads.

Hopefully, to explain this further, I'm saying that the newly added row that's been added to the table via the table.ajax.reload can't be found. But if I reload the page and do the search again. It will find it this time.

Any ideas what I'm doing wrong/how I fix this?

Code is below:

function addSong() {
  [...]
  songtable.ajax.reload(scrollto(songID));
  [...]

}
}

function scrollto(songID){

var index = songtable
    .column( 4 )
    .data()
    .indexOf(songID);

if ( index < 0 ) {
  alert( 'Song was not found in the result set - '+index );
    }
else {
alert( 'Song was found in the result set at '+index );
    songtable.scroller.toPosition(index);
}
}

Replies

  • kthorngrenkthorngren Posts: 21,147Questions: 26Answers: 4,918

    The code looks good. Its hard to say why your code isn't working without seeing it in action. Can you post a link to your page or a test case showing the issue?

    In your scrollto function I would use console.log(songID) to see what value is passed into the function. column(4) points to the 5th column in the table. Is this the correct column?

    Kevin

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Cheers for the response Kevin.

    So the console comes back with the correct songID 3 times (& alerts 3 times). Which is a bit odd. And yes, it's the 5th column that has the songIDs in there.

    I can't sadly post the URL on here :neutral: - but I can share it via a direct message if that helps?

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    I'm wondering if this .data() has something to do with it, considering it's AJAX do I need to point this element elsewhere perhaps?

  • kthorngrenkthorngren Posts: 21,147Questions: 26Answers: 4,918

    Your code works here with ajax:
    http://live.datatables.net/cugukuri/1/edit

    All I changed is the column number and it looks for a name by clicking the button.

    Are you using server side processing? The filter() only works with the data that is client side.

    Kevin

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Cheers Kevin.

    The only bit that's missing from that example is the dynamic adding (and subsequent reloading of all rows).

    When the user completes the form, AJAX submits it to a php script. This adds it to the DB and then on a '200' HTTP response, it reloads the datatable.

    It's on that reload of the data that it can't find the new row. But if I refresh the page and then try it'll work fine.

  • kthorngrenkthorngren Posts: 21,147Questions: 26Answers: 4,918

    The only bit that's missing from that example is the dynamic adding (and subsequent reloading of all rows).

    Not quite true. Clicking the button performs and ajax.reload the same as yours:

      $('button').on('click', function () {
        songtable.ajax.reload(scrollto('Lael Greer'));
      })
      
    

    Got your link. What are the steps to recreate the problem?

    Kevin

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0
    edited March 2019

    Agreed Kevin, but it's not a new row being added that wasn't there when the page was loaded. So that Lael Greer was present in the initial data load.

    Steps to recreate;
    1. In the console, if you paste scrollto("4gvea7UlDkAvsJBPZAd4oB"); and hit return you'll see it works for a song already in the datatable.
    2. At the bottom of the page, if you search for a song. Click on its name when it appears below the input field and click on Add! it will add the song to the datatable [and will attempt to perform the scrollto].

    The songID will be in the console too so you can use it in future (i.e. if you refresh and manually do a scrollto in the console you'll see it works that time.

  • kthorngrenkthorngren Posts: 21,147Questions: 26Answers: 4,918

    but it's not a new row being added that wasn't there when the page was loaded. So that Lael Greer was present in the initial data load.

    Ajax reload removes the data and refreshes it. Semantics I guess but it is a fresh load of data. Not arguing just explaining :smile:

    I'm not doing something right. In the Suggest a song input I type a song name but not seeing this happen Click on its name when it appears below the input field.

    In step 1 I see this output:

    ```
    scrollto("4gvea7UlDkAvsJBPZAd4oB");

    <?php search=kashmire:338 4gvea7UlDkAvsJBPZAd4oB undefined ``` ?>

    I see only one console.log statement which is in the scrollto function. Do you know where the undefined is coming from? Is this causing one of the events to occur that use songtable.ajax.reload(scrollto(songID));?

    Kevin

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Sorry Kevin, just wanted to make sure it was clear. Wasn't arguing! :smile:

    So when you search for a song, about 2 seconds later it should have a list of results below the input field...?

    Highlighted in red in the image below.

    The undefined is just the result of the console evaluating an expression. Nothing that my code is causing [i.e. it's just because you paste'd in scrollto(x); and it didn't return anything.

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    I've just found out that if you give it a few seconds then try again it does work.... Very odd! It's as if something is holding it up...

  • kthorngrenkthorngren Posts: 21,147Questions: 26Answers: 4,918

    So when you search for a song, about 2 seconds later it should have a list of results below the input field...?

    Got it working now, I was hitting enter which I shouldn't do :smile:

    I added We Will Rock You and got the alert indicating it couldn't find the record. The record is in the JSON response and it can be found using search. Tried a second time and it was found and scrolled to.

    I'm not sure why unless there is a race condition with the ajax.reload callback. Wonder if you used a short settimeout in the scrollto function before using indexOf would solve/work around the issue.

    function scrollto(songID){
    console.log(songID);
      var index = songtable
        .column( 4 )
        .data()
        .indexOf(songID);
    

    The developers @allan or @colin will need to take a look. Please send one or both of them the link and the link to this thread.

    Kevin

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Thanks, Kevin for your assistance up to now. Very much appreciated.

    I've messaged @allan & @colin

    Mark

  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    Thanks for that, @markmcw . Allan just took a glance but said it requires some thinking - he'll reply back later.

    C

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Hey @allan - any thoughts on this one?

  • allanallan Posts: 63,161Questions: 1Answers: 10,406 Site admin

    Sorry - I've not forgotten. I'll take a look at it in the morning :).

    Allan

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    Thanks!!! :smile:

  • allanallan Posts: 63,161Questions: 1Answers: 10,406 Site admin

    Sorry for the delay. I'm up to speed now and believe I see the issue - this line of code:

    songtable.ajax.reload(scrollto(id));
    

    will actually execute the scrollto() function and then pass the result into the ajax.reload() call (which happens to be undefined since scrollto isn't returning anything).

    What you actually want is to pass in a function which ajax.reload() will execute when the reload is done:

    songtable.ajax.reload( function () {
      scrollto(id);
    } );
    

    Another option would be to have scrollto return a function, but for this sort of thing I prefer the above.

    Allan

  • markmcwmarkmcw Posts: 12Questions: 0Answers: 0

    @allan you absolute hero. Thank you so much!

    Problem Solved!

This discussion has been closed.