[IGN-2207] Is there a way to stop/intercept a Tab Container tab change?

I have embedded views in different tabs of a tab container that are different forms for a user to fill out. What I’m looking for is a way to stop a change to a different tab when I detect that they have filled information that hasn’t been saved yet to ask if they are okay with losing their currently entered information before navigating to the next tab, else stay on the current tab they are working in so they can save their changes/continue editing. The current issue is that since it is an embedded view (with nested embedded views), every time a tab change happens, it reloads the view(s) and everything that was entered before switching tabs would be lost, and there doesn’t seem to be a way to intercept the tab change before it happens. My initial thought is to just make my own ‘tab container’ with a multistate button or the horizontal menu component, but that doesn’t look as clean.

Consider bidirectionally binding your various entry fields to session custom properties.

I don’t think that’ll be very reasonable considering we already have 200+ form values for them to fill out throughout the current application and it is still growing as of now too!

There isn’t a way to prevent tab changing as of today, but I have two pieces of good news:

  1. Nightly 8.1.5 builds should have a code change which keeps Views running even while in tabs which are not active. You should see this change the behavior you’re experiencing such that your fields will retain their values as you switch tabs.
  2. I’ve also opened a feature request to allow for “disabling” tabs via a property of each tab. No ETA on when this feature could be implemented.
  3. If/when you take the content in 8.1.5, you could use that new behavior along with logic within a Change Script on the currentTabIndex property of the Tab Container to determine when a tab can be changed. Something like this:
# Use a message handler for each tab's internal view to declare when a form is complete.
complete = self.custom.complete  
if not complete:
    self.props.currentTabIndex = previousValue.value
1 Like

Thanks for the replies! I will move forward with using MultiStateButtons and EmbeddedViews and handle everything with scripts and messages as we are not in a place to update Ignition at this time.

Has there been any movement on this feature request? This would be very handy to have.

I’m in 8.1.5 still and can can’t do this already

Really ? I’m on 8.1.10 and can’t find how to do this.

Oh wait… I was thinking of the horizontal menu bar. My bad!
Could you use some CSS magic using pointer-events: none? (I can’t remember if you can set styling on individual tabs)

Otherwise you could just use a view for your tabs (that’s what I’m doing)

Maybe. Gonna be hard to dynamically make the selector point at the right tab though.

Yeah, I thought there might have been a style prop for each tab, but doesn’t look like it :confused: that makes it harder…

Without looking at it, so don’t take me too seriously, but I guess something like nthchild could allow targeting a specific tab. If more than one tab can be subject to this treatment, maybe a series of different classes with different values for nthchild can be made, then added dynamically.

There’s a point where it just becomes easier to make the component yourself ;p

1 Like

Haha, it also gives you complete control over all visuals and functionality

1 Like

The feature has not yet been begun.

In the meantime…

} .psc-target_first_tab .tab-menu-item[data-index="0"] {pointer-events: None } {

Replace the number in data-index="0" to target the tab you want, remember it’s 0-based.
If you need to make it dynamic… The best I can think of is making multiple copies of this class, for different tab indices, and assign the class dynamically.

You could put a binding on the backgroundPosition style attribute, and use the currentTabIndex to assign the index number.

Something like:

concat('} .psc-target_tab .tab-menu-item[data-index="',{TabContainer.props.currentTabIndex},'"] {pointer-events: None } {')

But you don’t want to put that on the current tab though. It’s supposed to be a way to block access to some other tab while a condition has not been met.