Dynamically Selecting Pages in Tab Container

I am creating the titles of the Tab Container from a query. Based on a person’s permissions, the appropriate number of tabs are created. However, when embedding a view inside, I want to fill the view path part from the path field in the database. In other words, I want to automatically create the Tab name, the view under the tab, and the path information of the view under the tab based on the query response. Is this possible? Since I am a beginner, my explanation might be a bit unclear.

Technically, I manually added the embeddedView to take a screenshot, but it also needs to be added automatically. My goal is to create dynamic screens based on a person’s permissions.

Hi, this might not be ideal but what you could do is create a view with a flex container as root.

Then, you add a TabContainer and an EmbeddedView component (make sure the EmbeddedView is NOT part of the TabContainer!) .

Then, based on the prop "currentTabIndex" of your Tab Container, you can dynamically update the path in the props of the EmbeddedView component.

You could for example store your tab and view configurations in a custom property of your view, and based on the currentTabIndex, get and display only the view with the correct params.

Some screenshots to illustrate what I mean :

image

The "currentTabConfig" is just an expression binding on the view.custom.tabConfig, but you only get the element at the "selectedTab" index :

Once you've successfully created the "currentTabConfig" binding, all you need to do is feed the "associatedView" value to the path prop of your embedded view, and feed your "associatedParams" object to the "params" prop of your embedded view!

Let me know if that's what you're looking for!

1 Like

Hi,

It actually worked the way I wanted. For a beginner, I can say that it broadened my perspective on methods. Thank you very much.

However, instead of using two different containers, I will consider if I can put it inside the tab. For a production application, maybe I should be able to put the view inside a tab container. Thanks a lot.

1 Like

I don't think there's a "good" way to do this, and here's why:

Suppose you have a user who only has access to 2 tabs. It's easy enough to build a View with two tabs and give them each an Embedded View. Then you can build some property which represents the data structure needed so that you can properly bind the paths of the Embedded Views against the data structure.

The problem becomes users who have access to N number of tabs. You would actually have to build up to N number of tabs manually, then bind them all against the generated structure.

This will work for users who have access to between-and-including 1-N tabs, as you would also bind the tabs property against what a user could see - thus "removing" the no-access tabs from the structure and the browser.

Unfortunately, as soon as you have a user who has access to N+1 tabs, the Container will just not render the body of tabs beyond what you have manually configured.

Hello @cmallonee,

I created a value called “limit” on the page. This parameter indicates the number of tabs to be displayed. Since I haven’t connected to the SQL yet, I wanted to test it this way.

Below, I created three views for three tabs as marked in the image. Additionally, I created an EmbeddedView inside the TabContainer.

When I query the SQL, I thought it would respond according to the user as shown below.

Then, in the embeddedView section, I change the tabIndex based on the selected tab’s information, so that it navigates to the tab the user clicked on.

When I entered "1" for the page parameter, I saw 3 tab.

When I entered "3" for the page parameter, I saw 3 tab.

I thought I had completed the screen. Won’t this method work? I didn’t quite understand what you meant.

Of course, when I add a new page to the database, it will need to be created on the perspective side as well.

@Samuel_Sueur I just used one embeddedView inside the TabContainer. If you want you can check.

This approach could potentially get you most of the way, but with a lot of maintenance overhead. Additionally, you'll lose out on some container bookkeeping in the way of tab maintenance. Even if you can get the Embedded View to display the expected View based on the URL, how are managing user interaction with the tab bar?

Really though, it seems like you've gone way out of your way to make the Tab Container... not a Tab Container; you've turned it into an Embedded View that has a tabbed header. There's no reason you can't do this, but it seems like it would have been easier to build yourself a tabbed header of your own design alongside an Embedded View.

Actually, the goal here was to create a foundation for developing an MES application. Some machines can complete their tasks with a view containing 3 tabs, while others might require 5 tabs. I didn’t want to give the user a URL containing two different tab containers to achieve this. I thought it would be more efficient if the tabs were shaped according to the user’s permissions, so I wouldn’t have to create two or more different views. This would reduce the workload. However, if this approach isn’t reliable, it might be more logical to create a separate screen for each tab view. You are right, I won’t be able to carry the information entered in the first tab to the second tab in this way because it will be lost.

So, what would your recommendation be for this need?

Either way you go, the tabs will not have direct insight into the properties of others, so this would be a blocker either way. For tabs to share information, the data to be shared either needs to live and be updated externally (DB/tag), or written to a property high enough in the schema that all tabs can reference it (so a custom property at either the Tab Container, View, or Session level).

A little bit of extra development is not a terrible thing. I personally find that the trade-off between bespoke configurations for a small set of resources is preferable to one "dynamic" resource in most instances. The effort to maintain the dynamic configuration (your specialized Tab Container/Embedded View combo), can often become exponential as you find edge cases and additional requirements because they only apply to one of N configurations.

1 Like

To sum it up, if he created a tabbed header (not a horizontal menu?) with an embedded view, then he would have the ability to hide or display the buttons that each user would have permissions to see and use, correct?

And, the information that needs to be shared would still require this:

Perhaps an object or array in the embedded view's parent container? Assuming a lot of information to share.

Edit: I am working on something like this as well, and was thinking of some kind of dynamic Horizontal Menu or Tab Container, but being able to pull the names for the menu/tabs from a query and display only the ones desired for that user is where I am stuck. So a tabbed header, with a Flex Container and a bunch of buttons sounds like something I am going to try.

Which part are you stuck on? Actually, in the section above, I fetched the tab names from an SQL query. However, the values in the input fields disappear when switching tabs. I’m not sure if it’s worth investing more time into this.

In such a dynamic structure, you could actually create each tab individually and place separate views inside them, then remove the visible property of the tab. I’m not sure either. I love dynamic structures. I want to create a project where all the screens are shaped according to the settings configured in the database, so when I visit a customer, the developer colleagues have very little to do. I can’t get rid of this dream :slight_smile:

That's due to a property setting of the tab itself.

From what I've heard on another post, somewhere in the "ether", in order to create custom menus, with the ability to go from one to N menu options, I would need to construct it with JSON every time a user logs in or changes work areas/machines. I haven't yet created a table for the menu options, as I am still working it out on paper, but that is easy. We have something like that in Vision.

As far as storing values, cmallonee mentioned a couple of ways to accomplish this. You could also use a temp table in the DB to store information.

1 Like

If you are working with SQL Server, the Adventure Works DB, if I remember correctly, has an example of a table that you can set up to use with a recursive query, similar to this:

image

Where you list all the menu options, then using ParentMenu indicate which Sub Menu Item belongs to which Main Menu option. When I created this I was going to create more than one table, but then remembered the whole ParentMenu concept, so the ID column name will change to MenuID.

EDIT:
I decided to add a menu numbering system as well, because the primary ID numbers may get wonky.

CREATE TABLE [Menus].[MenuSystem](
	[MenuID] [int] IDENTITY(1,1) NOT NULL,
	[MenuName] [nvarchar](50) NOT NULL,
	[DisplayName] [nvarchar](50) NOT NULL,
	[DisplayOrder] [int] NOT NULL,
	[ParentMenu] [int] NOT NULL,
	[MenuNumber] [int] NOT NULL,
 CONSTRAINT [PK_MainMenu] PRIMARY KEY CLUSTERED 
(
	[MenuID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [Menus].[MenuSystem] ADD  CONSTRAINT [DF_MenuSystem_ParentMenu]  DEFAULT ((0)) FOR [ParentMenu]
GO

EDIT:
Is it possible to send a session property to a project script to determine which menu values are available to an authorized user? Or would it be better to setup a table with the roles and menu items and just query that?

I don't see another way to dynamically enforce security without a lot of IF statements.

Hello, since I use a single EmbeddedView and change its view path each time, it seems that’s why it didn’t work.

Would be more simple to show/hide Tabs according to Roles or permission.