Require navigation header button to work with multiple parent states?


#1

Hi,

I have a simple application which is using the ion-nav-view pattern for navigation. My app is based on the Ionic navigation example app. I would like to have a header button in the ion-nav-bar which always directs the user to the same page.

I have tried various combinations of UI state transitions but the the history seems to always get confused. I guess its probably due to my lack of understanding of the angular router, but some help would be appreciated.

When I click on the profile link I want to be able to click on any navigation item and that will effectively reset the history state and bring me to that menu item content. Currently, the history gets confused and I often end up with the “back button” present after I click one of the main navigation links. This is not what I want.

Please see screen attached. So basically, every time I click the profile button on the nav bar, I should be transported to the same page. If possible, the back button should be present and it should take me to the last page.

And below is my what I currently have for my angular routes. I have tried defining sub-views also but this caused weird behaviour.

Any advice or suggestions appreciated! Thanks.

// Restricted page
            .state('secure', {url: "/secure", abstract: true, templateUrl: "templates/secure.html", controller:"AppCtrl"})
            .state('secure.cards', {url: '/cards', templateUrl: 'templates/cards.html',controller:"CardsIndexCtrl"})
            .state('secure.network', {url: '/network', templateUrl: 'templates/network.html'})
            //.state('secure.network', {url: '/network',views: { 'network' :{templateUrl: 'templates/network.html'}}})
            .state('secure.scrapbook', {url: '/scrapbook',views: { 'scrapbook' :{templateUrl: 'templates/scrapbook.html'}}})
            .state('secure.shop', {url: '/shop',views: { 'shop' :{templateUrl: 'templates/shop.html'}}})
           // .state('secure.cards.profile', {url: '/profile',views: {templateUrl: 'templates/profile.html',controller:"CardsIndexCtrl"}})
            .state('secure.profile', {url: '/profile',templateUrl: 'templates/profile.html'});

#2

If I understand you correctly, you just want to have nav-button that is always visible?

 <ion-nav-bar class="nav-title-slide-ios7 bar-positive">
      <ion-nav-back-button class="button-icon ion-arrow-left-c">
      </ion-nav-back-button>
      
      <a ui-sref="tabs.home" class="button">
        Hello
      </a>
    </ion-nav-bar>

#3

So if I modify your Codepen to this - it shows my issue:

Angular Code

    angular.module('ionicApp', ['ionic']).config(function($stateProvider, $urlRouterProvider) {

  $stateProvider
    .state('tabs', {
      url: "/tab",
      abstract: true,
      templateUrl: "tabs.html"
    })
    .state('tabs.profile', {
      url: "/profile",
      views: {
        'home-tab': {
          templateUrl: "profile.html"
        },
        'about-tab': {
          templateUrl: "profile.html"
        },
        'contact-tab': {
          templateUrl: "profile.html"
        }
      }
    })
    .state('tabs.home', {
      url: "/home",
      views: {
        'home-tab': {
          templateUrl: "home.html",
          controller: 'HomeTabCtrl'
        }
      }
    })
    .state('tabs.facts', {
      url: "/facts",
      views: {
        'home-tab': {
          templateUrl: "facts.html"
        }
      }
    })
    .state('tabs.facts2', {
      url: "/facts2",
      views: {
        'home-tab': {
          templateUrl: "facts2.html"
        }
      }
    })
    .state('tabs.about', {
      url: "/about",
      views: {
        'about-tab': {
          templateUrl: "about.html"
        }
      }
    })
    .state('tabs.navstack', {
      url: "/navstack",
      views: {
        'about-tab': {
          templateUrl: "nav-stack.html"
        }
      }
    })
    .state('tabs.contact', {
      url: "/contact",
      views: {
        'contact-tab': {
          templateUrl: "contact.html"
        }
      }
    });


   $urlRouterProvider.otherwise("/tab/home");

})

.controller('HomeTabCtrl', function($scope) {
  console.log('HomeTabCtrl');
});

HTML

<html ng-app="ionicApp">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    
    <title>Tabs Example</title>

    <link href="http://code.ionicframework.com/1.0.0-beta.6/css/ionic.css" rel="stylesheet">
    <script src="http://code.ionicframework.com/1.0.0-beta.6/js/ionic.bundle.js"></script>
  </head>

  <body>
    
    <ion-nav-bar class="nav-title-slide-ios7 bar-positive">
      <ion-nav-back-button class="button-icon ion-arrow-left-c">
      </ion-nav-back-button>
      
      <a ui-sref="tabs.profile" class="button">
        Profile
      </a>
    </ion-nav-bar>
             
    <ion-nav-view animation="slide-left-right"></ion-nav-view>


    <script id="tabs.html" type="text/ng-template">
      <ion-tabs class="tabs-icon-top tabs-positive">

        <ion-tab title="Home" icon="ion-home" href="#/tab/home">
          <ion-nav-view name="home-tab"></ion-nav-view>
        </ion-tab>

        <ion-tab title="About" icon="ion-ios7-information" href="#/tab/about">
          <ion-nav-view name="about-tab"></ion-nav-view>
        </ion-tab>

        <ion-tab title="Contact" icon="ion-ios7-world" ui-sref="tabs.contact">
          <ion-nav-view name="contact-tab"></ion-nav-view>
        </ion-tab>

      </ion-tabs>
    </script>

    <script id="home.html" type="text/ng-template">
      <ion-view title="Home">
        <ion-content class="padding">
          <p>Example of Ionic tabs. Navigate to each tab, and
          navigate to child views of each tab and notice how
          each tab has its own navigation history.</p>
          <p>
            <a class="button icon icon-right ion-chevron-right" href="#/tab/facts">Scientific Facts</a>
          </p>
        </ion-content>
      </ion-view>
    </script>
    
    <script id="profile.html" type="text/ng-template">
      <ion-view title="Profile">
        <ion-content class="padding">
          <p>My Profile</p>
        </ion-content>
      </ion-view>
    </script>

    <script id="facts.html" type="text/ng-template">
      <ion-view title="Facts" class="padding">
        <ion-content>
          <p>Banging your head against a wall uses 150 calories an hour.</p>
          <p>Dogs have four toes on their hind feet, and five on their front feet.</p>
          <p>The ant can lift 50 times its own weight, can pull 30 times its own weight and always falls over on its right side when intoxicated.</p>
          <p>A cockroach will live nine days without it's head, before it starves to death.</p>
          <p>Polar bears are left handed.</p>
          <p>
            <a class="button icon ion-home" href="#/tab/home"> Home</a>
            <a class="button icon icon-right ion-chevron-right" href="#/tab/facts2">More Facts</a>
          </p>
        </ion-content>
      </ion-view>
    </script>

    <script id="facts2.html" type="text/ng-template">
      <ion-view title="Also Factual">
        <ion-content class="padding">
          <p>111,111,111 x 111,111,111 = 12,345,678,987,654,321</p>
          <p>1 in every 4 Americans has appeared on T.V.</p>
          <p>11% of the world is left-handed.</p>
          <p>1 in 8 Americans has worked at a McDonalds restaurant.</p>
          <p>$283,200 is the absolute highest amount of money you can win on Jeopardy.</p>
          <p>101 Dalmatians, Peter Pan, Lady and the Tramp, and Mulan are the only Disney cartoons where both parents are present and don't die throughout the movie.</p>
          <p>
            <a class="button icon ion-home" href="#/tab/home"> Home</a>
            <a class="button icon ion-chevron-left" href="#/tab/facts"> Scientific Facts</a>
          </p>
        </ion-content>
      </ion-view>
    </script>

    <script id="about.html" type="text/ng-template">
      <ion-view title="About">
        <ion-content class="padding">
          <h3>Create hybrid mobile apps with the web technologies you love.</h3>
          <p>Free and open source, Ionic offers a library of mobile-optimized HTML, CSS and JS components for building highly interactive apps.</p>
          <p>Built with Sass and optimized for AngularJS.</p>
          <p>
            <a class="button icon icon-right ion-chevron-right" href="#/tab/navstack">Tabs Nav Stack</a>
          </p>
        </ion-content>
      </ion-view>
    </script>

    <script id="nav-stack.html" type="text/ng-template">
      <ion-view title="Tab Nav Stack">
        <ion-content class="padding">
          <p><img src="http://ionicframework.com/img/diagrams/tabs-nav-stack.png" style="width:100%"></p>
        </ion-content>
      </ion-view>
    </script>

    <script id="contact.html" type="text/ng-template">
      <ion-view title="Contact">
        <ion-content>
          <p>@IonicFramework</p>
          <p>@DriftyCo</p>
        </ion-content>
      </ion-view>
    </script>

  </body>
</html>

If you click between the tab menus and also click the profile button - the whole state seems to get confused. I think my problem is with the way I am defining the tabs.profile view… ?


#4

Here is a demo of the problem…

When I click profile, it shows profile page, but navigates to “contact” tab. And when I click back to home, the profile tab is still selected. I guess I have declared my view states wrong and might also need to clear my history on a nav click? But im stuck on how to do this in Ionic/Angular… ?

Thanks


#5

I fixed my issue with the following Angular route:

.state('secure.profile', {url: '/profile',views: {
              'cards-tab@secure': {templateUrl: 'templates/profile.html'},
              'network-tab@secure': {templateUrl: 'templates/profile.html'},
              'scrapbook-tab@secure': {templateUrl: 'templates/profile.html'},
              'shop-tab@secure': {templateUrl: 'templates/profile.html'}
            }})

#6

Yep, your profile step is wrong.

You fill home-tab with your profile template.
In this case you need to set your profile in the main nav-view.

.state('profile', {
   url: "/profile",
   templateUrl: "profile.html"
})

But then you will loose the tabbar in the footer.

You can add an additional view in your baselayout.
To handle this.


#7

My solution still has a few issue. The UI State gets confused randomly.

Is there any solution that allows me to navigate to the profile view - but keep the nav menu at the bottom. I DRY solution is preferable, without duplicating if possible! Please edit my code pen if you can help!


#8

did you post your final edits somewhere?


#9

I don’t have any final codepen. I dont think that my solution would have worked without a hack. If I set up my profile view correctly(as the post mentions) - I would have lost the nav bar, but trying to share the profile view with the other tab views confused the state change router and it just did not work reliably.

I decided to use this solution. Im hoping that Ionic will support a feature like this soon. It works for me.