How to auto-populate table column A based on the value of table column B

Hi there, I have a basic table with two columns: "A" and "B".

A is a boolean column (default: false), represented by a checkbox.
B is an integer column whose default value is null.

When the user ticks column A, then column B must be populated with the row number. Whenever column A is unticked, the value of column B must be changed back to null.

Could you please tell me the easiest / best way to achieve this?

Also, if in a given row column A is ticked, I want column B at that row to be editable. If A is not ticked, then column B should not be editable.

What I tried (but I'm not married to this approach):

I'm trying to attach a handler to the "cell changed" event on my table, but oddly enough, I can't reference the table itself from the handler.

Hi there @Javi_V,

You can use current row within the "mapped value" field within your B column and use a terniary to return different values, e.g. {{ currentRow.a === true ? currentSourceRow.id }} (if by Row number you mean the index, then you can use "i".

You can do the same and make the "Editable" field dynamic:

and you can use {{currentSourceRow.A }} (which if it is a boolean then it will either be true or false.

I hope this helps!

Hey Miguel,

I tried it, but it doesn't work. In the mappedValue field I have access to currentSourceRow, but not currentRow.

Keep in mind that, when the checkbox in col A is ticked, that change is not synchronized with the db (nor it should be). It's just a local change to the table.

When the checkbox is ticked, the local version of column B must be populated with the appropriate value. But then, it is up to the user to synchronize the data with the db.

When I tick the checkbox, currentSourceRow does not change, and therefore, column B is not updated.

How can I fix this?

Hello!

I have a couple of questions about the function of this use case. It seems like what you actually want is to use the Multi-Row selection properties of the table. When you enable this and select the generated checkbox for the row, a property of the table called selectedRowKeys is available as an array of all of the row numbers for the selected rows. There is also selectedDataIndexes.

Either way, you could then tie the edit function of any column to the this array by using the i reserved index property for the column:

{{ table2.selectedDataIndexes.filter(index => index >= 0).includes(i) }}

ETA: I filter for indexes greater than or equal to 0 because I don't trust the table component to not return a -1 value for the "select all" toggle. It used to be wonky and this rules it out regardless of if it gets fixed.

Hi pyrrho,

No, that's not what I'm trying to do, but thanks for your reply. I don't want to allow item selection on my table (single or multiple). I want that, when you change column A's value to true (hence the checkbox), column B gets populated. And when column A is unchecked, column B returns to no value.

Although this might be something which you could achieve I believe you are attempting to use the Retool table slightly outside of its intended purpose.

Regardless... Here is how you can utilize the changesetArray of a table to determine whether or not 1) another column is editable and 2) how to set a value in that column when the row has a changed checked state:

A column value statement to display stuff when another column is checked (id is the PK on the row):

{{ yourTable.changesetArray.filter(change => 
   change.id === currentSourceRow.id) 
   && yourTable.changesetArray.filter(change => 
   change.id === currentSourceRow.id)[0].checkBoxRowStatus 
? "CHECKED VALUE"
 : null }}

Same function for determining editabilty (id is the PK on the row):

{{ yourTable.changesetArray.filter(change => 
   change.id === currentSourceRow.id) 
   && yourTable.changesetArray.filter(change => 
   change.id === currentSourceRow.id)[0].checkBoxRowStatus }}

And an example of the table with various rows checked and updated automatically:
image

Setup in the column:

ETA: code readability.

Thanks, you nailed it this time! I'll give it a go.

1 Like

To auto-populate column A based on the value of column B:

Excel/Google Sheets:

In cell A1, use this formula:

excel

Copy code

=IF(B1>=50, "Pass", "Fail")

Then, drag it down to apply to the entire column.

SQL:

sql

Copy code

UPDATE table_name
SET column_a = CASE WHEN column_b >= 50 THEN 'Pass' ELSE 'Fail' END;

Simple and accurate for both use cases!

Is there a better solution now? I need something similar that column B's value depends on column A's value. (A is editable, B is not)

1 Like

Hey @Wei_Chen! Thanks for stopping by office hours this morning. :slightly_smiling_face:

To summarize, there still isn't a particularly simple solution for updating one column based off of edits made to another column, given that staged edits are stored in the table's changeSet and can't be easily mapped to another column. The implementation previously suggested by @pyrrho is still the best way to do this.

One workaround that I have suggested in the past is to essentially replicate the contents of the backing database as an app variable and use it as the data source for your table. You can then bypass the changeSet and apply all edits directly to this variable, thus allowing you to immediately map changes in one column over to another.

I understand that this is one part of the table component that might feel a little over-engineered, given how simple it would be to accomplish the same task in a spreadsheet. The complicating factor, in this case, is that a Retool table is synced to a backing database and we need to maintain in-progress edits as a distinct entity.

Regardless, I'll take your feedback to the team in order to help steer the direction of future development! Don't hesitate to let us know if you have any follow-up questions or comments.

3 Likes

@Darren

Thanks for your reply. I try to follow your workaround by putting all the data in a Javascript array object. The table data is loaded from the array. But how do I by pass the changeSet and apply the edits directly to the array? The table doesn't automatically update the array, does it? or I miss something?

Thanks.

1 Like

No, unfortunately not - this particular setup requires a bit more manual configuration. You would have to set up an event handler that updates the array variable the same way that you would normally write a query that updates your database.

1 Like

Thanks for the reply, @Darren .

Which event? The Change Cell event or Save Action?

Also can I simply update the data associated with the table directly? I found this post -- I want to be able to save changes to the table itself! (NO DB). But it seems no setData on the table (at the one I have).

1 Like

I'd probably use the "Save Action" event, but that does mean you'd need to trigger an actual update to your database somewhere else. The setData method that you're referencing was defined on the previous generation of the table component but hasn't yet been implemented for the newer one. The feature requests exists, but the current workaround is the state variable middleman that you've already implemented.

1 Like

Is there a way to trigger the Save Action without user interaction (clicking the save button)? Basically I want to this looks like a normal spreadsheet where updating one cell will automatically updating another cell without extra user interactions.

Thanks.

1 Like

In that case, you'll probably want to define an event handler on the "Change cell" event that updates the state variable. If that same variable is set as the data source for your table, everything should update in real time!

1 Like

@Darren I want to let you know that your suggestion works great. Thanks for the help.

2 Likes

Glad to hear it! :+1:

1 Like