Making tabs for tabbed containers dynamic

Hi everyone. I have a tabbed container inside a tabbed container. tabbedContainer 1 is fine, my problem is with tabbedContainer2. Ideally id like to use an array returned from a query to be the labels for tabbedContianer 2. Id like the tabs for said container to have the names of the strings in my array. I got the tabs to dynamically show value for my sample array. but the container still only has a manually set number of different views Id like the amount of different views to be based on the amount of values of the array.

TLDR version: I want an array of values to dictate the labels and the amount of different tabs in a tabbed container

I would like to know if this is possible and if so how

Hi @colin_k,

Maybe you can try to achieve this dynamic behavior using Retool's JavaScript functionality:

  1. Fetch the Array: Create a query that retrieves the array of values you want to use for tab labels. This could be a database query, an API call, or any other method that returns an array of strings.

  2. Iterate through the Array: Use JavaScript to iterate through the array of values you retrieved. For each value, create a new tab and a corresponding view.

  3. Create Dynamic Tabs: Inside the JavaScript loop, use Retool's Tab component to create a new tab for each value in the array. Set the label property of the Tab component to the current value from the array.

  4. Create Dynamic Views: Inside the JavaScript loop, create a new view for each tab. You can use any Retool components inside the views, such as forms, tables, charts, or other containers.

  5. Link Tabs and Views: Connect each tab to its corresponding view using Retool's linkTo property. Set the linkTo property of the Tab component to the ID of the corresponding view.

Here's an example code snippet you can try to dynamically create tabs and views based on an array:

const arrayOfValues = query.fetchArray();

for (const value of arrayOfValues) {
  const tab = new Tab({
    label: value,
  });

  const view = new Container({
    // Add your components inside the view here
  });

  tab.linkTo(view.id);
  tabbedContainer2.addTab(tab);
  tabbedContainer2.addView(view);
}

This code will dynamically generate tabs and views based on the values in the arrayOfValues array. The number of tabs and views will automatically adjust based on the length of the array.

Please note that this is a suggestion. I was unable to test it locally.

:grinning:

Patrick

Hi @PatrickMast ,

I have a way to get the array. Instead of getting it using fetch array I have an expression like {{transformer4.value}} to get the array of values.

however I am a little confused.

Id like to be able to have the number of tabs to change. but am i able to have the type of content replaceable for each??

Ideally id like the workflow to be i click on a user in a table, it then shows all the tabs for all the teams they're a part of, each tab shows all the data per team in each tab. Do i need to create a module for this and then just have it come up per container? i dont really know what to do here as I am new to retool.

thanks

Hi @colin_k,

Yes, you can definitely have the number of tabs and the type of content change dynamically based on your requirements. Here's a breakdown of how to achieve this:

  1. Fetch the Array: You can use the expression {{transformer4.value}} to retrieve the array of values. This expression will evaluate to the array of values whenever it's referenced.

  2. Dynamic Tab Generation: Instead of creating tabs inside a JavaScript loop, you can use the map function to dynamically generate tabs based on the array. The map function will iterate through the array and create a tab for each value.

  3. Dynamic Content: You can use data binding to populate the content of each tab dynamically. For example, if you want to display all the data per team in each tab, you can use data binding to connect the data source to the view components inside the tabs.

  4. Reusable Modules: You can create a reusable module that encapsulates the logic for creating tabs and views based on an array. This module can then be imported and used in different parts of your workflow.

  5. Clicking on a User: When a user is clicked on in the table, you can trigger an action that retrieves the relevant data for that user and dynamically creates tabs and views based on that data.

Here's an example of how to use the map function to dynamically generate tabs:

const arrayOfValues = {{transformer4.value}};

const tabs = arrayOfValues.map((value) => {
  const tab = new Tab({
    label: value,
  });

  // Create a view for the tab here
  const view = new Container({
    // Add your components inside the view here
  });

  tab.linkTo(view.id);
  return tab;
});

tabbedContainer2.setTabs(tabs);

This code will create a new tab for each value in the arrayOfValues array. The tab labels will be set to the values from the array, and the views will be dynamically generated as well.

To make the content of each tab dynamic, you can use data binding to connect the data source to the view components inside the tabs. For example, if you have a table of team data, you can use data binding to display the relevant team data in each tab.

Creating a reusable module for generating tabs and views is a good practice for code organization and reusability. You can define a module with a function that takes an array of values as input and returns an array of tabs and views. This module can then be imported and used in different parts of your workflow.

To handle clicking on a user in the table, you can attach an event listener to the table row elements. When a row is clicked, you can retrieve the relevant data for that user and dynamically create tabs and views based on that data. This will allow you to display all the tabs for all the teams that the user is a part of.

Hope this helps.

:grinning:

Patrick

@PatrickMast I'm trying to implement something similar but when I try to use new Tab({}) the code fails because Tab is not defined. What do I need to do to correctly reference this component type from javascript?