简体   繁体   中英

angular material dialog tabbed

I have two tabs on my dialog. How do I dynamically set which one is active depending on which button the user hits.

Here are my buttons:

<md-button ng-click="showTabDialog($event, 'login')" class="md-raised md-primary">Login</md-button>

<md-button ng-click="showTabDialog($event, 'signup')" class="md-raised md-primary">Signup</md-button>

Here is my dialog html template

<md-dialog aria-label="Login">
<form>
    <md-toolbar>
        <div class="md-toolbar-tools">
            <h2>Login</h2>
            <span flex></span>
            <md-button class="md-icon-button" ng-click="cancel()">
                <md-icon aria-label="Close dialog"></md-icon>
                <!--md-svg-src="img/icons/ic_close_24px.svg"-->
            </md-button>
        </div>
    </md-toolbar>
    <md-dialog-content style="max-width:800px;max-height:810px; ">
        <md-tabs md-dynamic-height md-border-bottom>
            <md-tab label="Login">
                <md-content class="md-padding">
                    <h1 class="md-display-2">Log In</h1>
                    <p>Login here or click sign up to create a new account.</p>
                </md-content>
            </md-tab>
            <md-tab label="Sign Up">
                <md-content class="md-padding">
                    <h1 class="md-display-2">Sign Up</h1>
                    <p>Sign Up here</p>
                </md-content>
            </md-tab>
        </md-tabs>
    </md-dialog-content>
    <md-dialog-actions layout="row">
        <span flex></span>
        <md-button ng-click="answer('not useful')" >
            Not Useful
        </md-button>
        <md-button ng-click="answer('useful')" style="margin-right:20px;" >
            Useful
        </md-button>
    </md-dialog-actions>
</form>
</md-dialog>

Here is my JS:

$scope.showTabDialog = function(ev, button) {
    var useFullScreen = ($mdMedia('sm') || $mdMedia('xs'))  &&       
$scope.customFullscreen;
    $mdDialog.show({
        controller: 'SignUpCTRL',
        templateUrl: 'app/login/signup.modal.html',
        parent: angular.element(document.h1),
        targetEvent: ev,
        clickOutsideToClose:true,
        openFrom: '#center',
        fullscreen: useFullScreen
    })
        .then(function(answer) {
            $scope.status = 'You said the information was "' + answer + '".';
        }, function() {
            $scope.status = 'You cancelled the dialog.';
        });
};

So to reiterate, the user hits the signup dialog and the box opens with the signup tab focused. The user hits the login button and the dialog appears with the login tab focused.

Edit: Better solution:

You can put "selected" property with a scope variable "selectedIndex" which will have wanted seleted tab value.

<md-tabs selected="selectedTab" >

In corresponding controller:

$scope.selectedTab=1;//tab number

You can then have a scope function changing its value using ng-click on your buttons to change this value;

Angular Material's built in md-tabs & md-tab directive has defaults that would need to be overwritten in order to set md-active by including your own ng-class . The Angular Material default ng-class on tabs looks like this:

ng-class="{ 'md-active':tab.isActive(), 'md-focused':tab.hasFocus(), 'md-disabled':tab.scope.disabled }"

Because my problem only had two tabs I disabled the default tab by capturing which button was pushed passing into locals then assigned it to a variable in my controller $scope.active and then disabled the default tab if the user didn't push login like so:

<md-tab label="Login" ng-disabled="active!='Login'">

I used two templates, two controllers, and a factory. The first template has the buttons that the user clicks:

<md-button ng-click="showTabDialog({tab: 0, event: $event})">One</md-button>

<md-button ng-click="showTabDialog({tab: 1, event: $event})">Two</md-button>

<md-button ng-click="showTabDialog({tab: 2, event: $event})">Three</md-button>

Note the zero-based counting. The click passes through a data object with two items: which tab the user selected, and the $event (a MouseEvent ).

The first controller includes this handler function:

  $scope.showTabDialog = function(data) {
    var userData = {
      selectedTab: data.tab
    };
    userFactory.set(userData); // passes data object to other controllers
    $mdDialog.show({
      controller: DialogController,
      templateUrl: 'javascript/templates/tabDialog.html',
      parent: angular.element(document.body),
      targetEvent: data.event,
      clickOutsideToClose:true
    })
    .then(function(answer) {
      // fires on $scope.hide
    })
    .catch(function(error) {
      if (error) {
          console.error(error);
        }
      {
        // fires on $scope.cancel
      }
    });
  };

The handler function takes the data object passed in from the clicked button, then sends the data object to a factory that will pass the data object to the second controller. Next, $mdDialog.show is used to make the tabbed dialog, with parameters for the second controller and second template. The rest is boilerplate. targetEvent stops propagation up the DOM tree. I put in then and catch in case you want to do something with $scope.hide and $scope.cancel .

Here's the factory:

app.factory('userFactory', function() {

  var userObject = null;

  function set(user) {
    userObject = user;
  };

  function get() {
    return userObject;
  };

  return {
    set: set,
    get: get
  };
});

I put the second controller in the first controller, below the handler function:


  function DialogController($scope, $mdDialog) {
    $scope.user = userFactory.get();
    $scope.selectedTab = $scope.user.selectedTab || 0;

    $scope.hide = function() {
      $mdDialog.hide();
    };

    $scope.cancel = function() {
      $mdDialog.cancel();
    };

    $scope.answer = function(answer) {
      $mdDialog.hide(answer);
    };
  }

This controller gets the data passed in through the factory, then sets the data to its $scope . Note that this controller has its own $scope , not the $scope of the first controller. I don't use $scope.hide or $scope.answer but I left these in case you need them.

And, finally, here's my template for the dialog:

<md-dialog aria-label="tabbed dialog">
  <form>
    <md-toolbar>
    <div class="md-toolbar-tools">
      <img ng-src="myLogo.png" alt="logo" style="height: 36px;">
      <h2> MyCompany.com</h2>
      <span flex></span>
      <md-button class="md-icon-button" ng-click="cancel()">
        <md-icon md-svg-src="media/icons/ic_close_24px.svg" aria-label="Close dialog"></md-icon>
      </md-button>
    </div>
  </md-toolbar>

  <md-dialog-content style="max-width:800px;max-height:810px; ">
    <md-tabs md-dynamic-height md-border-bottom md-selected="selectedTab">
      <md-tab label="one">
        <md-content class="md-padding">
          <h1 class="md-display-2">Tab One</h1>
          <p>Lorem ipsum...</p>
        </md-content>
      </md-tab>

      <md-tab label="two">
        <md-content class="md-padding">
          <h1 class="md-display-2">Tab Two</h1>
          <p>Lorem ipsum...</p>
        </md-content>
      </md-tab>

      <md-tab label="three">
        <md-content class="md-padding">
          <h1 class="md-display-2">Tab Three</h1>
          <p>Lorem ipsum...</p>
        </md-content>
      </md-tab>
</md-tabs>
</md-dialog-content>

</form>
</md-dialog>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM