I want to connect the checkboxes with the filter option of the table.
I have played a little bit with table.setFilter and setFilterStack. I did not exactly know what table.updateLinkedFilter() should do?
My solution looks like (see below). Do you know if there is a better way?
pcbPage_sqlQuery_setTableFilterByComponents to update the filter setting of the table (called when a checkbox is changed):
const productionOnlyStatus = pcbPage_checkbox_productionOnly.value;
const showDeletedStatus = pcbPage_checkbox_showDeleted.value;
//const appMode = var_appMode;
var stack = pcbPage_table_pcb.filterStack;
console.log(stack);
var productionOnlyFilter = {columnId: "productionStatusName", operator: "=", value: "In Production", id: "pcbPage_checkbox_productionOnly"};
var notDeletedOnlyFilter = {columnId: "deleted", operator: "=", value: false, id: "pcbPage_checkbox_showDeleted"};
console.log(stack);
// handle filter
var filter = [];
if (productionOnlyStatus) {
filter.push(productionOnlyFilter)
}
if (!showDeletedStatus) {
filter.push(notDeletedOnlyFilter)
}
// handle stack
stack = {filters: filter, operator: "and"}
// set stack
pcbPage_table_pcb.setFilterStack(stack);
pcbPage_table_pcb.updateLinkedFilter(stack);
pcbPage_sqlQuery_setComponentsByTableFilter to update to checbox settings if somebody changed the filter settings of the table by hand (called when filter of table is changed):
// get stack
var stack = pcbPage_table_pcb.filterStack;
console.log(stack);
// get app mode
const appMode = var_appMode.value;
// set helper variables
var productionOnlyFound = false;
var showDeletedFound = false;
// if stack is not null
if (stack != null)
{
// search for ids and at found flag
for (const element of stack.filters) {
if ('id' in element)
{
if (element.id == 'pcbPage_checkbox_productionOnly')
{
console.log("pcbPage_checkbox_productionOnly");
productionOnlyFound = true;
}
else if (element.id == 'pcbPage_checkbox_showDeleted')
{
console.log("pcbPage_checkbox_showDeleted");
showDeletedFound = true;
}
}
}
}
// set checkboxes
if (productionOnlyFound) {
pcbPage_checkbox_productionOnly.setValue(true);
}
else
{
pcbPage_checkbox_productionOnly.setValue(false);
}
if (!showDeletedFound) {
// handle error in case of viewer mode
if (appMode == 'viewer') {
// show error
utils.showNotification({
title: "Filter Change Error",
description: "In viewer mode you can't display deleted items!",
notificationType: "error",
duration: 4.5,
});
// retun set filter stack query
pcbPage_sqlQuery_setTableFilterByComponents.trigger()
}
else {
pcbPage_checkbox_showDeleted.setValue(true);
}
}
else
{
pcbPage_checkbox_showDeleted.setValue(false);
}
Your code stucks in a endless loop. when deleting the filter for deleted rows of the table. Thank you very much. Could Retool optimize the description of the function table.updateLinkedFilter()? My code runs wonderful without this function... I am very confused...
The endless loop occurs because, when you remove the "Show Deleted" filter, the script sets the checkbox back to false. Then, it triggers the pcbPage_sqlQuery_setTableFilterByComponents function to reapply the filter. This re-adds the filter, which triggers the table filter change again. The cycle keeps repeating indefinitely.
Let's modify your function to only update the checkboxes if necessary, and prevent triggering pcbPage_sqlQuery_setTableFilterByComponents again if it's already correcting the filter.
// Get current filter stack
const stack = pcbPage_table_pcb.filterStack || { filters: [] };
// Determine applied filters
const productionOnlyFound = stack.filters.some(f => f.id === "pcbPage_checkbox_productionOnly");
const showDeletedFound = stack.filters.some(f => f.id === "pcbPage_checkbox_showDeleted");
// Update checkbox 'in production only'
pcbPage_checkbox_productionOnly.setValue(productionOnlyFound);
// Handle Viewer Mode Restriction
if (!showDeletedFound && var_appMode.value === 'viewer') {
utils.showNotification({
title: "Filter Change Error",
description: "In viewer mode, you can't display deleted items!",
notificationType: "error",
duration: 4.5,
});
// Prevent an infinite loop by checking if the checkbox is already false
if (pcbPage_checkbox_showDeleted.value !== false) {
pcbPage_checkbox_showDeleted.setValue(false);
// Prevent unnecessary recursive trigger
setTimeout(() => {
pcbPage_sqlQuery_setTableFilterByComponents.trigger();
}, 100); // Small delay to prevent immediate retrigger loop
}
} else {
// Update checkbox 'show deleted' only if needed
if (pcbPage_checkbox_showDeleted.value !== !showDeletedFound) {
pcbPage_checkbox_showDeleted.setValue(!showDeletedFound);
}
}
Thank you @Shawn_Optipath I prefer my solution. My function mentioned here also prevents infinite loop.
Could somebody help?
I did not exactly know what table.updateLinkedFilter() should do? Can somebody explain it? I think I don't need this function.
My solution looks like (see above). Do you know if there is a better way?
To the second question: It seems not. @Shawn_Optipath has a lot of retool experience. If he optimize my approach, this way is the best way to synchronize external filter components with the table.
To the first question: @Tess Is it possible to get an example for the usage of table.updateLinkedFilter()?
updateLinkedFilter is helpful if you add a filter component to your app and link it to a table. Then, you can programmatically add filters to the filter component: