Select next row in a sorted and/or filtered table

I'm working on a tabbed container which has 2 tabs, one tab shows a table of items and the second tab displays data for the selected row. When a user clicks on a row they are moved to the tab showing data for that selected row.

I would like to implement a button on the second tab for the user to select the next row of the (sorted and likely filtered) table without moving back to the first tab. {{ table.selectedRow.index }} wont work here because the table is likely to always be sorted and often filtered.

Anybody have working solution to do something like this?

Hey @derekchisholm!

There's a post here with a solution that uses some JS to navigate a sorted/filtered table. It works by storing the sorted and filtered indices of your table in a temporary state using the following script:

//read sorted column from table and whether to sort desc
const {sortedColumn, sortedDesc} = table1; 

//attach the retool index of each row to its data
const dataToSort = table1.displayedData.map((row, index) => ({index, ...row})); 

//manually sort the data by the correct column and then retrieve sorted indices
const sortedIndices = _.sortBy(dataToSort, sortedColumn).map(row => row.index); 

//reverse if sorting desc
sortedDesc && sortedIndices.reverse(); 

//store sorted indices in tempstate
sortedIndicesState.setValue(sortedIndices); 

From there, you can use the following to navigate to the next row:

const currentSortedIndex = sortedIndicesState.value.indexOf(table1.selectedIndex);
const nextTableIndex = sortedIndicesState.value[currentSortedIndex + 1] ?? table1.selectedIndex;
table1.selectRow(nextTableIndex);

It's a bit of a workaround so let me know if any questions/trouble arises! The post has a working sample app you can play with as well.

Hope it helps :slightly_smiling_face:

I did come across this post when I started working on solving this problem. Unfortunately, I wasn't able to get it working at that time, I'll give it another go today and see if I can get it working.

I'll report back with results.

@Kabirdas Thank you for your input here! I was able to get this working (mostly) on a second attempt, your added comments were helpful. I've configured the scripts as described in the reference thread and also added event handlers on the table for sorting and filtering to trigger the sorting script.

When sorting and filtering the table manually, this solution works beautifully. However, I still have a couple bugs to work out.

  1. I've setup a text field for users to filter the table. I added a line to the end of the search filter script to trigger the sorting script, but that doesn't seem to be working. Perhaps its an execution order problem I'm unaware of?
  2. When the app loads, the table is sorted on a column (not the key column) in the table configuration. This means the tables initial state is sorted, not as presented by the original SQL query. I guess I need the sort query to run and load the temporary state after everything on the page has loaded?

Good to hear it working so far! :sweat_smile:

I think that, for both of these cases, it'll help to add the updateSortedIndices query as a success handler on the query that fetches your table data. Since you want it to run after the data has been fetched.

The default sort does use a different table property than the manual sort though so you might try

const sortedColumn = table1.sort[0].id;
const sortedDesc = table1.sort[0].desc;

instead of

const {sortedColumn, sortedDesc} = table1;

Can you let me know if that works?

Fantastic! These two bits solves everything for this particular functionality of the app. The table is working exactly as expected now. Thanks so much!