30

What is the elegant way to trigger a state with angular-ui-router by clicking <button>?

I am using ui-sref="main" and it doesn't seem to work although it works with <a> though.

HTML:

<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <link data-require="[email protected]" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="[email protected]" src="http://code.angularjs.org/1.2.13/angular.js" data-semver="1.2.13"></script>
  <script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js" ></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">

  <nav class="navbar navbar-default">
    <div class="navbar-header">
      <a class="navbar-brand" href="#">Brand</a>
    </div>  
    <ul class="nav navbar-nav navbar-left">
      <li>
        <button class="btn btn-danger navbar-btn" ui-sref="main" >Button Submit</button>
      </li>
      <li>
        <a class="btn btn-danger navbar-btn" ui-sref="main" >Anchor Link Submit</a>
      </li>
    </ul>
  </nav>


</body>

</html>

Javascript:

var app = angular.module('plunker', ['ui.router']);

'use strict';

app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {

  $stateProvider
    .state("main", {
      url: "/main",
      resolve: {
        test: function() {
          alert("Triggered main state");
          return true;
        }
      }
    });

}]);


app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

Link: http://plnkr.co/edit/vMtLN0ncpqAfgM6S1Ng4?p=preview

3
  • You are just asking which is the better way to specify ui-sref either as button attribute of anchor tag attribute Commented Mar 2, 2014 at 7:08
  • I have to use <button> as it's required by bootstrap in nav (you can see <a> css got messed up). So I need to find an easy way to trigger state with <button> and not end up having to write ng-click for it if possible. Maybe I have to write a separate directive?!
    – HP.
    Commented Mar 2, 2014 at 7:15
  • Please close this question. My code worked.
    – HP.
    Commented Mar 3, 2014 at 4:41

7 Answers 7

51

Wrap the button in an anchor and you are good to go:

<a ui-sref="main">
    <button class="btn btn-danger navbar-btn" >Button Submit</button>
</a>

DEMO

7
  • 10
    Button in link with some extra work makes keyboard accessibility ugly: tab to link give focus to not-button, that activates the ui-sref; but tab again and the button has focus but Enter doesn't do anything. @Lalit's suggestion to just put ui-sref in the button instead of ng-click works better in my test.
    – Daryn
    Commented Apr 9, 2015 at 18:23
  • That's a valid point Daryn. Thanks for pointing out the accessibility issues.
    – Alp
    Commented Apr 10, 2015 at 21:32
  • 1
    why even use a button then?
    – VeXii
    Commented May 6, 2015 at 10:32
  • 6
    ui-sref directive now supports being applied to any clickable element as the directive internally binds to the "click" event for the specified element. Commented Sep 14, 2015 at 19:28
  • 1
    As the OP is using Bootstrap, it's actually easier to get rid of the button all together and style the "A" as being a button. <a class="btn btn-danger navbar-btn" ui-sref="main">Button Submit</a> Commented Apr 11, 2016 at 5:16
44

the other solutions didn't work for me. Here's what I did using ui-router:

    <button ui-sref="app.schedule" class="btn btn-danger navbar-btn">
      Schedule
    </button>

Piece of pie :-)

2
  • 11
    ui-sref internally binds to the "click" event so this attribute can be applied to any clickable elements. Commented Sep 14, 2015 at 19:26
  • this converts the button to a link (a). Applied css is not working anymore.
    – kaiser
    Commented Nov 16, 2018 at 2:36
8

I guess better option is to use it with button as suggested in angular-ui-bootstrap controls guidelines, so i have implemented the plnkr code. and have tried it to work with button click only, no ng-click need to be written as ui-sref works easily with the button click as it is; Please have a look.

1
  • Confirmed ui-sref in button instead of ng-click seems to be working great for me.
    – Daryn
    Commented Apr 9, 2015 at 18:26
2

For accessibility compliance, I'm implementing this solution to preserve the styling of anchor tags and implement the desired keyboard functionality of a menu (top, bottom arrow keys move focus through list items and the enter key activates the focused link).

              <ul class="dropdown-menu white" role="menu">
                <li role="menuitem">
                    <a href="#" ng-click="go('main')">
                        <i class="glyphicon glyphicon-log-out"></i> Sign Out
                    </a>
                </li>
              </ul>

The go function is a facade/wrapper around the ui-router state service to navigate to a state.

        $scope.go = function (page) {
               $state.go(page);
        };
0

I use navbar too and don't need to use buttons. I have this:

<div class="collapse navbar-collapse navbar-ex1-collapse">
    <ul class="nav navbar-nav">
        <li ng-class="{ active: $state.includes('mystate1') }"><a ui-sref='mystate1'>mystate1</a></li>
        <li ng-class="{ active: $state.includes('mystate2') }"><a ui-sref='mystate2'>mystate2</a></li>
        <li ng-class="{ active: $state.includes('mystate3') }"><a ui-sref='mystate3'>mystate3</a></li>
        <li ng-class="{ active: $state.includes('mystate4') }"><a ui-sref='mystate4'>mystate4</a></li>
    </ul>
</div>
5
  • I cannot use <a> as it is the constraint from Bootstrap getbootstrap.com/components/#navbar-buttons
    – HP.
    Commented Mar 3, 2014 at 4:23
  • There is no constraints of using buttons in navbars. If you don't want to use buttons, you can use anchors: getbootstrap.com/components/#navbar-default
    – mlim1972
    Commented Mar 10, 2014 at 22:11
  • It said loud and clear right here Like the standard button classes, .navbar-btn can be used on <a> and <input> elements. However, neither .navbar-btn nor the standard button classes should be used on <a> elements within .navbar-nav.
    – HP.
    Commented Mar 11, 2014 at 5:29
  • I don't know how you read it but I read it that you can use .navbar-btn inside <a> and <input> but .navbar-btn and standard buttons should NOT be used inside a <a> in a .navbar-nav
    – mlim1972
    Commented Mar 14, 2014 at 4:08
  • Not use on a <a> element. The note didn't say not inside a <a>. So on is like together in this context. Try to test it yourself. Using %a.navbar-btn will mess up the button css.
    – HP.
    Commented Mar 14, 2014 at 8:03
0

Main is not a child view, and since you have defined a url for this, why not try this instead:

<a href="/main">
    <button class="btn btn-danger navbar-btn" >Button Submit</button>
</a>

In this case, I'm assuming that you want the button the link to another page.

However, a better way to use ui-router is to create a parent and child view, read the documentation below: https://github.com/angular-ui/ui-router/wiki#state-change-events

0

Try this and see if it works. All I did was create a div with a type button

<div ui-sref="main" type="button" >Go To Main State</div>

Not the answer you're looking for? Browse other questions tagged or ask your own question.