Dynamically switch tabs in NavTabs from dynamic success event

Hi all

I currently have a 5 tab Navtab panel as below

image

Tab Pane 2 contains a server connect form.

I would like to open tab Pane 3 when the form is successfully submitted (which shows the history the subscribers submissions)

I see nothing in the Success event of the form that i can “hook into”

I have using browser goto to the tabs id i.e. browser1.goto(’#tab_id’) but that doesn’t seem to work (tried the tab id, the panel id and container names inside)

Anyone any ideas?

Brian

We recently had a similar use case. We created a structure out of buttons and div to achieve this, instead of using tab element.
Show/hide ofndov depends on a variable value.
We created a flow with the rules that would allow to move to next pane/tab and cal. This flow on click of next.
In you case, you could set a variable value of success event of the form and call the flow to validate moving to the next step.
Hope this helps.

Thanks Nishkarsh

I did consider that option but I really don’t want to have to re-do the whole section, it’s not that important! I will just pop up a message telling them the submission is now available in the list and they can do it manually

I had to do a similar thing once @Hyperbytes and used this tutorial from https://webdesign.tutsplus.com/tutorials/how-to-add-deep-linking-to-the-bootstrap-4-tabs-component--cms-31180

With a standard Wappler “Tabs with Nav” component placed on my page I need to just make a few adjustments to it, I can keep all the standard naming in place as Wappler provides it however in the href="#" of each button I need to enter the ID of the relative panel like this.

<ul class="nav nav-tabs" id="navTabs1_tabs" role="tablist">
    <li class="nav-item">
        <a class="nav-link active" id="navTabs1_1_tab" data-toggle="tab" href="#navTabs1_1" data-target="#navTabs1_1" role="tab" aria-controls="navTabs1_1" aria-selected="true">Home</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="navTabs1_2_tab" data-toggle="tab" href="#navTabs1_2" data-target="#navTabs1_2" role="tab" aria-controls="navTabs1_2" aria-selected="false">Profile</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="navTabs1_3_tab" data-toggle="tab" href="#navTabs1_3" data-target="#navTabs1_3" role="tab" aria-controls="navTabs1_3" aria-selected="false">Messages</a>
    </li>
</ul>
<div class="tab-content" id="navTabs1_content">
    <div class="tab-pane fade show active" id="navTabs1_1" role="tabpanel">
        <p>Consequat occaecat ullamco amet non eiusmod nostrud dolore irure incididunt est duis anim sunt officia. Fugiat velit proident aliquip nisi incididunt nostrud exercitation proident est nisi. Irure magna elit commodo anim ex
            veniam culpa eiusmod id nostrud sit cupidatat in veniam ad. Eiusmod consequat eu adipisicing minim anim aliquip cupidatat culpa excepteur quis. Occaecat sit eu exercitation irure Lorem incididunt nostrud.</p>
    </div>
    <div class="tab-pane fade" id="navTabs1_2" role="tabpanel">
        <p>Ad pariatur nostrud pariatur exercitation ipsum ipsum culpa mollit commodo mollit ex. Aute sunt incididunt amet commodo est sint nisi deserunt pariatur do. Aliquip ex eiusmod voluptate exercitation cillum id incididunt elit
            sunt. Qui minim sit magna Lorem id et dolore velit Lorem amet exercitation duis deserunt. Anim id labore elit adipisicing ut in id occaecat pariatur ut ullamco ea tempor duis.</p>
    </div>
    <div class="tab-pane fade" id="navTabs1_3" role="tabpanel">
        <p>Est quis nulla laborum officia ad nisi ex nostrud culpa Lorem excepteur aliquip dolor aliqua irure ex. Nulla ut duis ipsum nisi elit fugiat commodo sunt reprehenderit laborum veniam eu veniam. Eiusmod minim exercitation
            fugiat irure ex labore incididunt do fugiat commodo aliquip sit id deserunt reprehenderit aliquip nostrud. Amet ex cupidatat excepteur aute veniam incididunt mollit cupidatat esse irure officia elit do ipsum ullamco Lorem.
            Ullamco ut ad minim do mollit labore ipsum laboris ipsum commodo sunt tempor enim incididunt. Commodo quis sunt dolore aliquip aute tempor irure magna enim minim reprehenderit. Ullamco consectetur culpa veniam sint cillum
            aliqua incididunt velit ullamco sunt ullamco quis quis commodo voluptate. Mollit nulla nostrud adipisicing aliqua cupidatat aliqua pariatur mollit voluptate voluptate consequat non.</p>
    </div>
</div>

At this point the only change made from standard is the href on each button link, then at the bottom of my document I add this custom script

<script>
    $(document).ready(() => {
        let url = location.href.replace(/\/$/, "");

        if (location.hash) {
            const hash = url.split("#");
            $('#navTabs1_tabs a[href="#'+hash[1]+'"]').tab("show");
            url = location.href.replace(/\/#/, "#");
            history.replaceState(null, null, url);
            setTimeout(() => {
                $(window).scrollTop(0);
            }, 400);
        }

        $('a[data-toggle="tab"]').on("click", function() {
            let newUrl;
            const hash = $(this).attr("href");
            if(hash == "#navTabs1_1") {
                newUrl = url.split("#")[0];
            } else {
                newUrl = url.split("#")[0] + hash;
            }
            newUrl += "/";
            history.replaceState(null, null, newUrl);
        });
    });
</script>

Once this is added I can control which nav is displayed using my URL, and therefore it works using a browser goto

Thanks Paul, that almost works "straight out the box’

I just need to look at the JS to resolve on small issue

The page is in a sub directory so the link is: /agency/#navTabs1_3/

The correct tab is selected and displayed however the URL is changed and the slash following agency is removed so the url shown is:
/agency#navTabs1_3/

Edit

changing js to

url = location.href.replace(/\/#/, "/#");

did the trick

1 Like

Couple of other tweaks for info

base of page was adding an extra / to the URL i.e. /agency// rather than /agency/ so

newUrl += "/";

simply became

newUrl += "";

Also didn’t like the id’s being shown when tabs clicked manually so changed:

            if(hash == "#navTabs1_1") {
                newUrl = url.split("#")[0];
            } else {
                newUrl = url.split("#")[0] + hash;
            }

to

            if(hash == "#navTabs1_1") {
                newUrl = url.split("#")[0];
            } else {
                newUrl = url.split("#")[0];
}

Any yes i know these lines could just have been taken out but i wanted to illustrate the changes

1 Like

This is a useful technique from @psweb, but I think there is also a Wappler-only method to do this. You can use a variable to determine which tab is active, and in this case, set the variable on the dynamic success event.

You need to add this dynamic attribute to the links in the nav-items and to the divs containing the tab panels:
dmx-class:active="tab_selected.value == 'tabname"
and, to the panels, a second attribute:
dmx-class:show="tab_selected.value == 'tabname"
You also need to add an onclick event to the links in the nav items - to set the variable to the current link.

1 Like

I also had to make quite a few little tweaks to the base code to fit my exact needs, for me I did not want the url changing at all onclick, I really just needed it to be able to read in if a hash URL was passed.

I have used it similarly on other strange things, like when a client does a special price only for clients that have clicked through from Facebook or something. This way the Facebook posted link would be example.com/holiday#facebook_special as a silly example, however the website itself actually never uses the #facebook_special as a link within itself, if that makes sense, it just allows me to alter the price based on the URL.

The base code does offer quite a bit of flexibility, so I have used it pretty often and just modified for my needs, glad it helped though.

@TomD, sounds like an interesting way to go about achieving this, will try it out sometime and post the code, unless you have something already similar handy, would be good to have a few different methods posted here.
Bootstrap documentation kind of talks about this as 2 different methods like an either/or situation of using data-target vs href method, however I kind of need a combination of the two half the time, and I use Tabs and Accordions quite a bit so any different methods, please share, they will come in handy.

I used this approach because I wanted a way to set the default tab dynamically - as a user preference, not in relation to the result of a server action as in @Hyperbytes’ request. However, the same method seemed appropriate.

Here’s a very simple example. Obviously you’ll need to add your own server connect action. The default tab is set according the default value of the variable tab_selected. This is changed following the onsuccess event of the server action.

<!doctype html>
<html>

<head>
	<base href="/">
	<meta charset="UTF-8">
	<title>Untitled Document</title>
	<script src="dmxAppConnect/dmxAppConnect.js"></script>
	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css" integrity="sha384-REHJTs1r2ErKBuJB0fCK99gCYsVjwxHrSU0N7I1zl9vZbggVJXRMsv/sLlOAGb4M" crossorigin="anonymous">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>

<body is="dmx-app" id="" dmx-class="">
	<dmx-serverconnect id="serverconnect1" url="dmxConnect/api/tests/cars.php" dmx-on:success="tab_selected.setValue('success')" noload="noload"></dmx-serverconnect>
	<dmx-value id="tab_selected" dmx-bind:value="'default'"></dmx-value>
	<div class="container">
		<div class="row mt-5">
			<div class="col">
				<p class="float-right  ">var_tab_selected: {{tab_selected.value}}</p>
				<ul class="nav nav-tabs" id="navTabs1_tabs" role="tablist">
					<li class="nav-item">
						<a class="nav-link" dmx-class:active="tab_selected.value == 'home'" id="navTabs1_1_tab" data-toggle="tab" href="#" data-target="#navTabs1_1" role="tab" aria-controls="navTabs1_1" aria-selected="false"
							dmx-on:click="tab_selected.setValue('home')">Home</a>
					</li>
					<li class="nav-item">
						<a class="nav-link" dmx-class:active="tab_selected.value == 'default'" id="navTabs1_2_tab" data-toggle="tab" href="#" data-target="#navTabs1_2" role="tab" aria-controls="navTabs1_2" aria-selected="false"
							dmx-on:click="tab_selected.setValue('default')">Default</a>
					</li>
					<li class="nav-item">
						<a class="nav-link" dmx-class:active="tab_selected.value == 'success'" id="navTabs1_3_tab1" data-toggle="tab" href="#" data-target="#navTabs1_3" role="tab" aria-controls="navTabs1_3" aria-selected="false"
							dmx-on:click="tab_selected.setValue('success')">Success</a>
					</li>
				</ul>
				<div class="tab-content" id="navTabs1_content">
					<div class="tab-pane fade" dmx-class:show="tab_selected.value == 'home'" dmx-class:active="tab_selected.value == 'home'" id="navTabs1_1" role="tabpanel">
						<p>HOME<br>Consequat occaecat ullamco amet non eiusmod nostrud dolore irure incididunt est duis anim sunt officia. </p>
					</div>
					<div class="tab-pane fade" dmx-class:show="tab_selected.value == 'default'" dmx-class:active="tab_selected.value == 'default'" id="navTabs1_2" role="tabpanel">
						<p>DEFAULT<br>Ad pariatur nostrud pariatur exercitation ipsum ipsum culpa mollit commodo mollit ex.</p>
					</div>
					<div class="tab-pane fade" dmx-class:show="tab_selected.value == 'success'" dmx-class:active="tab_selected.value == 'success'" id="navTabs1_3" role="tabpanel">
						<p>SUCCESS<br>Est quis nulla laborum officia ad nisi ex nostrud culpa Lorem excepteur aliquip dolor aliqua irure ex. </p>
					</div>
				</div>
			</div>
		</div>
		<div class="row">
			<div class="col">
				<p class="mt-3 text-danger"><button id="btn1" class="btn btn-secondary" wappler-command="editContent" dmx-on:click="serverconnect1.load({})">load SC action</button></p>
			</div>
		</div>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>

</html>
6 Likes

This is a really helpful thread. I needed to have the url change when a tab was clicked so that I could link to a page and a specific tab rather than always land on the first tab.

I did what @TomD described but instead of using a variable I used the query manager so the value was stored in the URL. Something like ?tab=intro for example.

2 Likes