# Update Navigation First Tier Tabs

**URL:** <https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [August 2, 2024, 12:31pm UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110 "2024-08-02T12:31:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Gomes](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@Alex\_Gomes](https://forum.inductiveautomation.com/u/Alex_Gomes)\
**Post date:** [August 2, 2024, 12:31pm UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/1 "2024-08-02T12:31:34Z")

</div>

Hi,  
I have a project with screen navigation through a set of first tier tabs across the top of the screen, on a docked window. I want to have another button in the project automatically switch to another screen as it performs it's button (outside of the navigation window). However when I the screen change happens the selection on the navigation tabs does not update properly.

I assume I need to use a script to update the selected data property manually, however since it's in a different window I'm not sure how to access that property.  
Is there a command to access/update that data in the nav window?  
Is there a better way to have the selection in the nav bar stay up to date with the screen being shown?

Thanks!

---

<div class="post-metadata">

**Author:** ![andrews](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@andrews](https://forum.inductiveautomation.com/u/andrews)\
**Post date:** [August 3, 2024, 6:48am UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/2 "2024-08-03T06:48:15Z")

</div>

Its been awhile since I touched ignition so I could be wrong.

But you'd have to fenagle it a bit. by not using an actual docked windows but rather "simulating" one. Then you could use said button to pass properties into next window. So youd turn that dock into a template of sorts.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 3, 2024, 6:58am UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/3 "2024-08-03T06:58:49Z")

</div>

~~Make your own menu and bind the buttons' classes/styles to `page.props.primaryView` (I think, just use the property browser in the binding popup to find the actual property).~~

~~Built-in navigation components are fine as long as your needs are very basic. As soon as you hit some particular navigation scheme, or you need to add some level of customization... you run into a road block.~~  
~~But making you own should be easy enough.~~

Edit: Missed the vision tag.

---

<div class="post-metadata">

**Author:** ![michael.flagler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michael.flagler/32/26272_2.png) [@michael.flagler](https://forum.inductiveautomation.com/u/michael.flagler)\
**Post date:** [August 5, 2024, 2:56am UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/4 "2024-08-05T02:56:34Z")

</div>

I don't have the designer open in front of me, but you can bind the selected tab property essentially to the system client tag named like "CurrentWindow" if I recall.

---

<div class="post-metadata">

**Author:** ![Alex\_Gomes](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@Alex\_Gomes](https://forum.inductiveautomation.com/u/Alex_Gomes)\
**Post date:** [August 6, 2024, 1:03pm UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/5 "2024-08-06T13:03:30Z")

</div>

I tried the currentwindow system tag binding to the selected tab, but that still doesn't seem to update properly.

I used pascal's concept to make my own multi-state button tied to a new client tag to accomplish, I just setup a client even script to drive the changes based on the number from the multi-state button. Seems to be working well. Thanks guys!

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [August 6, 2024, 2:20pm UTC](https://forum.inductiveautomation.com/t/update-navigation-first-tier-tabs/94110/6 "2024-08-06T14:20:52Z")

</div>

This is going to be highly dependent on how the navigation was set up. That said:

First off, I want to let you know that I've had to full-scale redo 2-tier navigation 3 times with this project until I got it down. It's pretty well "final" at this point in time. It's made in a way that also allows [multiple desktops](https://forum.inductiveautomation.com/t/mutli-monitor-to-show-4-different-display/93034/5), as has been discussed on this forum a couple of times. I'll link to that as well.

It's not super straightforward, or intuitive, but it gets the job done and allows for context buttons as well, and is pretty flexible.

Here's what I've come up with.

Docked navigation window custom properties:

1. `currentTier1` : INT
2. `currentWindow` : STRING
3. `designer` : BOOL | `{[System]Client/System/SystemFlags} = 1`

Docked navigation window components:

1. `Tier1` : Tab Strip  
a. Navigation Mode, disabled  
b. The "Window Name" for each tab is the tier 1 index (INT)  
c. Add a custom "Tier2" (STRING) column to the `tabData` with a path to the  
"main" window for that tier.  
d. `selectedTab` bidirectionally bound to the custom `currentTier1` prop.
2. `Tier2` : Tab Strip  
a. Navigation Mode, swap windows  
b. `selectedTab` bidirectionally bound to the custom `currentWindow` prop.  
c. Configure appearances as desired
3. `Tier2_1` : Tab Strip  
a. Configure these 2nd tier tab strips using the customizer. These tab strips will be off-screen and the `tabData` will be transferred to `Tier2` as needed.  
b. Bind the `visible` property to the `designer` custom prop.
4. ...
5. `Tier2_X` : Tab Strip

A few scripts, in a library of course:

```python
dockedNavPath = 'Nav'

def tier1MouseClicked(tabStrip, selectedTab = None):
	'''
	Swap window from the docked 1st tier navigation tab. 1st tier tabStrip must include "Tier2" column with path to the main window.
		
		Args:
			tabStrip (Tab Strip obj)	:	1st tier tab strip object. (event.source)
																	Must include custom "Tier2" column in tabData dataset
			seledctedTab (INT) :	Selected first tier tab. (optional, default uses tabStrip.selectedTab)
																	(0-based index for tabData dataset)
			
		Returns:
			n/a
			*Nav.Root Container.currentWindow	(string) :	update navigation docked view current window
	'''
	#selected tab not specified, use selectedTab prop on tab strip
	if selectedTab is None:
		selectedTab = tabStrip.selectedTab
		
	#get window path
	tier1 = int(selectedTab)
	windowPath = tabStrip.tabData.getValueAt(tier1,'Tier2')
	
	#special condition example
	if windowPath == 'SLDG-10 SLUDGE OVERVIEW':
		area = system.tag.readBlocking('[client]Areas/Station_Area')[0].value
		if not area == 0:
			windowPath = 'Phase_2B/10-RAS_WAS/RAS_WAS'
			
	#special condition example
	elif windowPath == 'Phase_2B/09-Final Clarifiers/Overview':
		area = system.tag.readBlocking('[client]Areas/Station_Area')[0].value
		if not area == 0:
			windowPath = 'Phase_2B/02-Waste/INP'
			
	#swap to window and update properties
	contextNavButtonClicked(tier1, windowPath)
	

def contextNavButtonClicked(tier1, windowPath):
	'''
	Swap windows from a context navigation button.
	
	Args:
		tier1 (string)	:	0-based index for tier 1 tab strip
		windowPath (string)	:	window to swap to
	
	Returns:
		n/a
	'''
	#swap to window
	system.nav.swapTo(windowPath)
	
	system.util.invokeLater(lambda : setDockedNavSelections(tier1,windowPath), 200)
	

def setDockedNavSelections(tier1, windowPath):
	'''
	Set root container props on the docked navigation view for tier 1 and tier 2 nav strips.
	
	Args:
		tier1 (string)	:	0-based index for tier 1 tab strip
		windowPath (string)	:	current window
		
	Returns:
		n/a
		*Nav.Root Container.currentWindow	(string)	:	update navigation docked view current window
		*Nav.Root Container.currentTier1	(string)	:	update navigation docked view tier 1 tab
	'''
	
	#update tier 1 and tier 2 props
	dockedNavRootContainer = system.gui.getWindow(dockedNavPath).getComponentForPath('Root Container')
	dockedNavRootContainer.currentTier1 = tier1
	dockedNavRootContainer.currentWindow = windowPath

```

Docked navigation window scripting:

1. `visionWindowOpened()` : set up a script to set the initial `Tier1` tab as desired

```python
#set the initial tier 1 navigation to tab "0"
Common.Nav.tier1MouseClicked(system.gui.getParentWindow(event).getComponentForPath('Root Container.Tier1'), 0)

```

1. `Tier1.mouseClicked()` : call tier 1 mouse click library script

```python
Common.Nav.tier1MouseClicked(event.source)

```

1. `Tier1.propertyChange()` : assign `tabData` for `Tier2` to the associated `Tier2_X` tab strip `tabData`.

```python
if event.propertyName == 'selectedTab':
	
	selectedTab = event.source.selectedTab
	
	event.source.parent.getComponent('Tier2').tabData = event.source.parent.getComponent('Tier2_'+selectedTab).tabData

```

Looks something like this, with all of the sub-strips visible

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/1/a177dd183f1348a1eac6084df3ffccf69789537f.png)  
Just change the window height to hide the sub-tabs.  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/b/eb9c5da5c881ff924d22c68a8f4aeb19944428b3.png)

A context navigation button's script would look like this:

```python
Common.Nav.contextNavButtonClicked(0, '0/Sub_1')

```

I would recommend defining some constants in the script library to use, instead of the hardcoded "0".

Results (simple example):  
 ![Tier2_Nav](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/f/1fbbada453d72acb5811a2105c8fa1865363eb03.gif)
