Matt
Matt

Reputation: 822

Angular Material Dialog Mobile Keyboard Issue

The issue I'm seeing occurs on a mobile device, specifically I'm using an iPhone 6s Plus with iOS 10.0.

http://codepen.io/AstroDroid/pen/beqjoL

class AppController {
  status = '';
  customFullscreen;
  constructor(private $scope, private $mdDialog, private $mdMedia, private $mdToast) {
    this.customFullscreen = this.$mdMedia('xs') || this.$mdMedia('sm');
  }

  showDialog(event) {
    var useFullScreen = (this.$mdMedia('sm') || this.$mdMedia('xs')) && this.customFullscreen;

    this.$mdDialog.show({
      controller: LoginDialogController,
      controllerAs: 'dialog',
      templateUrl: 'login-dialog.template.html',
      parent: angular.element(document.body),
      targetEvent: event,
      clickOutsideToClose: true,
      fullscreen: useFullScreen
    })
    .then(credentials => this.showToast(`Thanks for logging in, ${credentials.username}.`),
      () => this.showToast('You canceled the login.'));

    this.$scope.$watch(() => this.$mdMedia('xs') || this.$mdMedia('sm'),
      wantsFullScreen => this.customFullscreen = wantsFullScreen === true);
  }

  showToast(content: string) {
    this.$mdToast.show(
      this.$mdToast.simple()
        .content(content)
        .position('top right')
        .hideDelay(3000)
    );
  }
}

class LoginDialogController {
  username: string;
  password: string;

  constructor(private $mdDialog) { }

  hide() {
    this.$mdDialog.hide();
  }

  close() {
    this.$mdDialog.cancel();
  }

  login() {
    this.$mdDialog.hide({username: this.username, password: this.password});
  }
}

function config($mdThemingProvider) {
  $mdThemingProvider.theme('default')
    .primaryPalette('blue')
    .accentPalette('orange');
  $mdThemingProvider.theme('input', 'default')
    .primaryPalette('grey')
}

angular
  .module('app', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
  .controller('AppController', AppController)
  .config(config);
.dialogdemoBasicUsage #popupContainer {
  position: relative;
}

#login-dialog {
  max-width: 90%;
  width: 500px;
}
<div ng-app="app" ng-controller="AppController as login" class="md-padding dialogdemoBasicUsage" id="popupContainer" ng-cloak>
  <div class="dialog-demo-content" layout="row" layout-wrap layout-margin layout-align="center">
    <md-button class="md-primary md-raised" ng-click="login.showDialog($event)">
      Login
    </md-button>
  </div>
  <div hide-gt-sm layout="row" layout-align="center center" flex>
    <md-checkbox ng-model="login.customFullscreen" aria-label="Fullscreen Custom Dialog">Force Custom Dialog Fullscreen</md-checkbox>
  </div>

  <div ng-if="login.status" id="status">
    <b layout="row" layout-align="center center" class="md-padding">
      {{login.status}}
    </b>
  </div>

  <script type="text/ng-template" id="login-dialog.template.html">
    <md-dialog id="login-dialog" aria-label="Login" ng-cloak>
      <form name="loginForm" ng-submit="dialog.login()">
        <md-toolbar>
          <div class="md-toolbar-tools">
            <h2>Log In</h2>
            <span flex></span>
            <md-button class="md-icon-button" ng-click="dialog.close()">
              <md-icon md-svg-src="img/icons/ic_close_24px.svg" aria-label="Close dialog"></md-icon>
            </md-button>
          </div>
        </md-toolbar>

        <md-dialog-content>
          <div class="md-dialog-content">
            <md-input-container class="md-block">
              <label>Username</label>
              <input name="username" ng-model="dialog.username" md-autofocus required />
            </md-input-container>
            <md-input-container class="md-block">
              <label>Password</label>
              <input type="password" name="password" ng-model="dialog.password" required />
            </md-input-container>
          </div>
        </md-dialog-content>

        <md-dialog-actions layout="row">
          <a href="" class="md-primary">Forgot Password?</a>
          <span flex></span>
          <md-button type="submit" ng-disabled="loginForm.$invalid" class="md-raised md-primary">Login</md-button>
        </md-dialog-actions>
      </form>
    </md-dialog>
  </script>
</div>

Sorry for the code, it wouldn't let me post without it. A complete, working example is already in the pen, so this is not bad, nor do I feel bad, nor should I.

When I bring up the modal and focus one of the text inputs and close the modal, either by the 'X' or by filling out the fields and tapping 'Login', when the modal is dismissed, the keyboard remains on the screen. When I tap 'Done' in the keyboard, it is dismissed, but comes back anytime I tap anywhere else on the screen. The only way I can keep it away is if I make sure I tap 'Done' before either closing the dialog with the 'X' or tapping 'Login'.

I am guessing the issue is with how Angular Material 'hides' the dialog, the onscreen keyboard still thinks the text inputs are valid.

Does anyone know of a workaround, or if this pen is not using $mdDialog correctly?

Upvotes: 1

Views: 1790

Answers (1)

Matt
Matt

Reputation: 822

A workaround I have found is to make sure the inputs are blurred as the dialog is closed. I did this by adding

this.$document[0].activeElement.blur();

to my dialog.login() method.

Upvotes: 1

Related Questions