4

我有一个表单,有一堆 md-selects、文本字段等等。这是一个很大的表单,用户希望按 Tab 键并在不同的表单字段中导航。当 md-select 通过 tab 键获得焦点时,它不显示下拉菜单。在这种情况下,需要额外按下向下箭头。有没有什么方法可以让选择显示下拉菜单而无需单击鼠标或按下按键?

我尝试将链接函数添加到 mdSelect 指令以注册单击或向下按键事件,但似乎效果不佳。此外,md-autocomplete 具有完全不同的外观和感觉,因此它不会与其他输入容器一起使用。

此外,无论如何都要让选择下拉菜单出现在输入区域下方。

我喜欢干净的代码,并且不喜欢在上面使用任何 jquery 函数。提前致谢。

4

3 回答 3

4

这是结果的屏幕截图:

角度材料 md-select 以在焦点上显示下拉菜单

这是关键的 HTML:

<md-input-container md-no-float flex="30">
  <md-select name="favoriteColor" ng-model="color" placeholder="Pick a Color" 
             ng-init="showOptions=true" 
             my-on-focus="showOptions" 
             md-on-close="showOptions=false">
    <md-option value="red">Red</md-option>
    <md-option value="blue">Blue</md-option>
    <md-option value="green">Green</md-option>
  </md-select>
</md-input-container>

请注意ng-initmy-on-focusmd-on-close属性。

这是 AngularJS 指令:

app.directive('myOnFocus', function() {
  return {
    scope: true,
    restrict: 'A',
    link: function(scope, elem, attr, ctrl) {
      elem.bind('focus', function() {
        if (scope[attr.myOnFocus]) {
          elem.triggerHandler('click');
        }
      });
      elem.bind('blur', function() {
        scope[attr.myOnFocus] = true;
      });
    }
  };
});

诀窍是将showOptions变量设置false为选择关闭时,这样它就不会再次打开,直到blur在指令中运行。

这是让选择下拉菜单显示在输入区域下方的 CSS:

md-select-menu {
  margin-top: 50px;
}

最后,这是一个工作 Plunker,http ://plnkr.co/edit/FD5u78pC3HbO9UwUOKXR?p=preview 。

希望能帮助到你。如果您有任何问题,请告诉我。

于 2017-03-08T03:47:17.603 回答
2

感谢蒂姆哈克的指导。

我稍微修改了指令以隐藏暴露的范围变量和 mdOnClose 以便开发人员可以在一个附加属性中实现它。

plnkr.co/edit/m6LGjVronWR2dMQrwGFn?p=preview

var app = angular.module('app', ['ngMaterial']);
    app.directive('myOnFocus', function() {
        return {
            scope: true,
            restrict: 'A',
            link: function(scope, elem, attr, ctrl) {
                scope.showOptions = true;
                if ((attr['mdOnClose'])) {
                    attr['mdOnClose'] = "showOptions=false;" + (attr['mdOnClose']);
                } else {
                    (attr['mdOnClose']) = "showOptions=false;"
                }

                elem.bind('focus', function() {
                    if (scope.showOptions) {
                        console.log(scope, elem, attr, ctrl)
                        elem.triggerHandler('click');
                    }
                });

                elem.bind('blur', function() {
                    scope.showOptions = true;
                });
            }
        };
    });
于 2017-03-19T13:02:14.087 回答
1

虽然已经回答了,但我更喜欢对装饰器使用另一种方法,并想分享它,因为我不太喜欢声明多个指令来控制单个元素的行为。

.config(function($provide) {
    $provide.decorator('mdSelectDirective', function($delegate) {
        var directive = $delegate[0];
        var originalController = directive.controller;

        var decoratedController = function($scope, $element){
            $element.bind("keyup", function(ev){
                if ( ev.keyCode == 9 ){ //Tab key code
                    $element.triggerHandler('click');
                }
            });

            originalController($scope, $element);
        }

        directive.controller = decoratedController;

        return $delegate;
    });
})
于 2018-10-29T13:30:03.917 回答