admin管理员组

文章数量:1421980

The problem

I'm designing a Cordova hybrid app using the (very) new AngularJS Material Design dependency.

I have a log in form in a bottom sheet called via $mdBottomSheet service. Example below:

$scope.showLogin = function ($event) {
  $mdBottomSheet.show({
    templateUrl: 'views/login/login.html',
    controller: 'loginCtrl'
  })
};

The contents of views/login/login.html are:

<md-bottom-sheet ng-controller="loginCtrl" layout="column">
  <form name="signInForm" ng-submit="submitPassword()">
    <md-list>
      <md-item>
        <md-progress-circular md-mode="indeterminate" ng-show="loading"></md-progress-circular>
      </md-item>
      <md-item>
        <md-text-float label="Email address" ng-model="username" required>
        </md-text-float>
      </md-item>
      <md-item>
        <md-text-float type="password" label="Password" ng-model="password" required>
        </md-text-float>
      </md-item>
      <md-item>
        <md-button class="md-primary md-raised submit" type="submit">Sign in</md-button>
      </md-item>
    </md-list>
  </form>
</md-bottom-sheet>

Everything runs and displays just fine.

HOWEVER! when I go to click on the input, the focus is never given to the input, and instead the md-bottom-sheet element is dragged back and forth. Clicking on the button (when not disabled) fires just fine, but the click on the input to give it focus is never recognized.

 


Things I've tried

  1. Adding ng-click="return false", 'ng-click="$event.preventDefault()"`
  2. Adding a -webkit-transform: translate3d(0, 80px, 0) !important; rule to the CSS, as that's the default state of the property which is being altered on drag.
  3. Adding angular.element('md-bottom-sheet').on('click', function() { return false; }); to an ng-init block.
  4. Doing the same as above (using jQuery to try to ham-hand this) on the dragstart event.

 


The question

How can I use an input in a bottom sheet with material design, given I've tried every workaround that I know to get this to work for touch?

 


Caveats

1. I would love to offer a live example for this, but I can't find a CDN source for angular/material

2. This only happens on a mobile device, no idea if it will happen on a mobile website as I've only tested it in a Cordova hybrid app

3. There are no examples of this I've found via search, so I can't even point you to a resource that might emulate the problem.

4. Basically, this is going to be very hard to reproduce.


Update

One possible fix I've identified:

The following block in the function BottomSheet(element) "class" for the provider has the following:

function onTouchStart(e) {
  e.preventDefault();
  /* do the rest of the code */
}

Changing that e.preventDefault() to the following does allow normal input behavior, but requires that I fork their repo.

if (e.target.tagName.toLowerCase() !== 'input')
  e.preventDefault()

Is there a solution that doesn't require me to fork this for such a minor change?

The problem

I'm designing a Cordova hybrid app using the (very) new AngularJS Material Design dependency.

I have a log in form in a bottom sheet called via $mdBottomSheet service. Example below:

$scope.showLogin = function ($event) {
  $mdBottomSheet.show({
    templateUrl: 'views/login/login.html',
    controller: 'loginCtrl'
  })
};

The contents of views/login/login.html are:

<md-bottom-sheet ng-controller="loginCtrl" layout="column">
  <form name="signInForm" ng-submit="submitPassword()">
    <md-list>
      <md-item>
        <md-progress-circular md-mode="indeterminate" ng-show="loading"></md-progress-circular>
      </md-item>
      <md-item>
        <md-text-float label="Email address" ng-model="username" required>
        </md-text-float>
      </md-item>
      <md-item>
        <md-text-float type="password" label="Password" ng-model="password" required>
        </md-text-float>
      </md-item>
      <md-item>
        <md-button class="md-primary md-raised submit" type="submit">Sign in</md-button>
      </md-item>
    </md-list>
  </form>
</md-bottom-sheet>

Everything runs and displays just fine.

HOWEVER! when I go to click on the input, the focus is never given to the input, and instead the md-bottom-sheet element is dragged back and forth. Clicking on the button (when not disabled) fires just fine, but the click on the input to give it focus is never recognized.

 


Things I've tried

  1. Adding ng-click="return false", 'ng-click="$event.preventDefault()"`
  2. Adding a -webkit-transform: translate3d(0, 80px, 0) !important; rule to the CSS, as that's the default state of the property which is being altered on drag.
  3. Adding angular.element('md-bottom-sheet').on('click', function() { return false; }); to an ng-init block.
  4. Doing the same as above (using jQuery to try to ham-hand this) on the dragstart event.

 


The question

How can I use an input in a bottom sheet with material design, given I've tried every workaround that I know to get this to work for touch?

 


Caveats

1. I would love to offer a live example for this, but I can't find a CDN source for angular/material

2. This only happens on a mobile device, no idea if it will happen on a mobile website as I've only tested it in a Cordova hybrid app

3. There are no examples of this I've found via search, so I can't even point you to a resource that might emulate the problem.

4. Basically, this is going to be very hard to reproduce.


Update

One possible fix I've identified:

The following block in the function BottomSheet(element) "class" for the provider has the following:

function onTouchStart(e) {
  e.preventDefault();
  /* do the rest of the code */
}

Changing that e.preventDefault() to the following does allow normal input behavior, but requires that I fork their repo.

if (e.target.tagName.toLowerCase() !== 'input')
  e.preventDefault()

Is there a solution that doesn't require me to fork this for such a minor change?

Share Improve this question edited Dec 6, 2014 at 4:55 Josh Burgess asked Dec 6, 2014 at 4:17 Josh BurgessJosh Burgess 9,5771 gold badge35 silver badges47 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 1

You were near the solution. You had to use stopPropagation() instead of preventDefault(). Here is the simple approach:

Directive (.coffee)

angular.module('Expedite').directive 'stopEvent', ->
  restrict: 'A'
  link: (scope, element, attr) ->
    element.bind attr.stopEvent, (e) ->
      e.stopPropagation()

View (.slim)

input ng-model="user.email" stop-event='touchstart'

This way you will not have to fork material repo.

So I'm running into exactly the same issue. The code above works for pre 0.6.1 - though doesn't work so well afterwards.

I have however found that moving that e.preventDefault() (minus the if() logic) down to the onTouchMove(e) function, seems to fix all scroll glitches (atleast that I can see) - and still allows inputs to function normally.

Agree, it would be super if the ng-material guys could incorporate something like this into the repo to make $mdBottomSheet implementation more flexible.

本文标签: javascriptUse inputs in AngularJS Material bottomsheetStack Overflow