Tabbed app, define link target app tab

I’ve a tabbed app structure like this example:

https://framework7.io/docs/tabs.html#views-as-tabs

Is it possible for links in a side panel to define on which tab it should open, and activate that tab? If this isn’t built in, I think I add a custom callback, which utilizes a custom attribute like below and switches the tab before processing the route. Is this a good way to go?

... in side menu ....
  <a href="/news-index" data-tab="#tab-news">
....

And then a event handler like this:

$('body').on('.panel-left a', function() {
  if ( $(this).attr('data-tab') ) {
    myf7app.tab.show( $(this).attr('data-tab') );
  }
});

Yes, you need to specify the View where to load the page with data-view attribute. And add tab-link class and data-tab attribute to specify Tab-View to show:

<a href="/news-index" class="tab-link" data-tab="#tab-news" data-view="#tab-news">

I’ve tested that combination. It switches to the correct tab/view, but the tabbar doesn’t update to the active tab, and the app doesn’t navigate to the given route. If I remove the data-tab attribute, it correctly navigates to the route on #view-events, but obviously doesn’t change the active tab.

Could it be that the handler for ‘data-tab’ attribute stops event propagation, so that regular navigation is prevented?

<div id="app">
    <!-- Status bar overlay for fullscreen mode-->
    <div class="statusbar"></div>

    <div class="panel panel-left panel-cover">
	<a href="/contact" class="tab-link panel-close" data-tab="#view-events" data-view="#view-events">
	    Test
	</a>
    </div>

    <div id="view-intro" class="view"></div>

    <!-- Views/Tabs container -->
    <div id="views-main" class="views tabs safe-areas">
	<!-- Tabbar for switching views-tabs -->
	<div class="toolbar tabbar-labels toolbar-bottom">
	    <div class="toolbar-inner">
		<a href="#view-home" class="tab-link tab-link-active">
		    <i class="icon material-icons">home</i>
		    <span class="tabbar-label">Nieuws</span>
		</a>
		<a href="#view-events" class="tab-link">
		    <i class="icon material-icons">date_range</i>
		    <span class="tabbar-label">Events</span>
		</a>
		<a href="#view-info" class="tab-link">
		    <i class="icon material-icons">info_outline</i>
		    <span class="tabbar-label">Informatie</span>
		</a>
		<a href="#view-video" class="tab-link">
		    <i class="icon material-icons">play_circle_outline</i>
		    <span class="tabbar-label">Video</span>
		</a>
		<a href="#view-more" class="tab-link">
		    <i class="icon material-icons">more_horiz</i>
		    <span class="tabbar-label">Meer</span>
		</a>
	    </div>
	</div>

	<div id="view-home" class="view view-main tab tab-active"></div>
	<div id="view-events" class="view tab"></div>
	<div id="view-info" class="view tab"></div>
	<div id="view-video" class="view tab"></div>
	<div id="view-more" class="view tab"></div>

    </div>
</div>

Yes, you are right, having tab-link class prevent router from loading this url. So, here is a safe workaround. Just use custom route-tab-link class instead on such link, and this live handler after app init:

$(document).on('click', '.route-tab-link', function (e) {
  var url = $(this).attr('href');
  var view = app.views.get($(this).attr('data-view'));
  var tabId = $(this).attr('data-tab');
  app.tab.show(tabId);
  view.router.navigate(url);
});
2 Likes

I will remove this limitation in next update

Great! This was the workaround I was trying to get working :slight_smile: Thanks!

I removed the ‘view.router.nagivate(url)’ as that already happens automatically.

Has this been updated in the F7 release or is the workaround still recommended?

I have a similar situation where I was to update a view when click on one of the tabs + I want to update the tab that is selected.

Also, what is the proper structure for managing a page from a scrollable tabbar? Currently I have a view called #offers that takes a parameter. The tab-link is then ‘/offers/topic:BUSINESS’. But the entire page is loaded and the tabbar is recreated each time. I imagine I need to split my offers.html into a wrapper page that includes the top nav and scrollable tabbar and then somehow have each tab-link update only the content area each time a tab is clicked by calling the database to load that topic? I am still trying to get my head around views and pages obviously. (let me know if you want me to make this a separate question)

<div id="omsmian-toolview" class="views tabs">
		<div id="omsmian-toolbarbox" class="toolbar tabbar-labels toolbar-bottom  omsmiantoolbar" style="display: ;height: 30px">
			<div id="omsmian-toolbar" class="toolbar-inner">
				<!-- --------------------------------------------------------------------- -->
				<a id="home" href="#view-home" class="tab-link tab-link-active omsmain-tablink">
					<span class="tabbar-label">Home</span>
        </a>
        <!-- --------------------------------------------------------------------- -->
        <a id="p2index" href="#view-p2index" class="tab-link omsmain-tablink">
          <span class="tabbar-label">Page2</span>
        </a>
        <!-- --------------------------------------------------------------------- -->
        <a id="p3" href="#view-p3" class="tab-link omsmain-tablink">
          <span class="tabbar-label">P3</span>
        </a>
        <!-- --------------------------------------------------------------------- -->
         <a id="p5index" href="#view-p5index" class="tab-link omsmain-tablink">
          <span class="tabbar-label">P5</span>
        </a>
        <!-- --------------------------------------------------------------------- -->
      </div>
    </div>
    <div id="view-home" class="view view-main tab tab-active">
      <div class="page " data-name="home" style="background-color: ">
        <div class="page-content" style="padding: 0;margin:0">
         ...  
      </div>
   </div>
  var homeView = app.views.create('#view-home', {
    name: 'view-home',
    url: '/',
    on: {
      pageInit: function() {
        console.log('homeView init!');
        $$('html').addClass('device-windows theme-dark color-theme-teal');
      }
    }
  });
  $$('.omsmain-tablink').on('click', function() {
    if ($$('#view-' + this.id).length == 0) {
      var tabname = this.id;
      var taburl = '/' + this.id + '/';
      var htmladd = '<div id="view-' + tabname + '" class="view tab"></div>';
      $$('#omsmian-toolview').append(htmladd);
      ////////////////////////////////////step1. ADD view tab html done, if having 30+ tabs, not everyone will 
      ////////////////////////////////////be used/clicked ... so only add/create once by clicked.


      app.views.create('#view-' + this.id, {
        name: tabname,
        url: taburl
      });
    ////////////////////////////////////////step2. create view >>> linek to routes path done


    };
    app.tab.show('#view-' + this.id, true);
    tabname = null;
    taburl = null;
    htmladd = null;
    console.log('now this tab=' + this.id);
  });

0.need set routes done at 1st!!!

KEEP INMIND :

If  ur <a id="page2"  href="#view-page2" 
thus
The ID of class="view tab"  >>>  id="view-page2"
thus
The url in app.views.create >>>  '/page2/' = routes path 
app.views.create('#view-page2' , {
    name: 'page2',
    url:  '/page2/'
   });
and in the  routes :
    {
        path: '/page2/',
        componentUrl: '/uQbKp.html',
        options: {
            context: {
                pagetitle: 'page2',
            },
        },
    },

*******. view url in app.views.create = routes path
this way will keep tabs KeepAlive…If u needed

works in F74.5.0

1 Like