Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular material md-select to show the dropdown on focus

I have a form and has a bunch of md-selects, text fields and so on. It is a large form and the users expect to press tab and navigate through different form fields. When md-select receives focus via tab key press, it doesnt show the dropdown. An additional down arrow press is required in this case. Is there any way to get the select to display the dropdown without a mouseclick or a down key press ?

I tried adding link functions to mdSelect directive to register a click or a down key press event and it seemed to not work as well. Also, md-autocomplete has a different look and feel altogether, so it doesnt go along with the other input containers.

Additionally is there anyway to get the select dropdown to appear below the input area.

I like the code to be clean and prefer not to use any jquery functions on it. Thanks in advance.

like image 862
jose Avatar asked Mar 09 '23 17:03

jose


2 Answers

Here's a screen shot of the results:

angular material md-select to show the dropdown on focus

Here's the key 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>

Note the ng-init, my-on-focus, and md-on-close attributes.

Here's the AngularJS directive:

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;
      });
    }
  };
});

The trick is to set the showOptions variable to false when the select is closed so it doesn't open again until blur is run in the directive.

Here's the CSS to get the select dropdown to appear below the input area:

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

Finally, here's a working Plunker, http://plnkr.co/edit/FD5u78pC3HbO9UwUOKXR?p=preview.

Hope it helps. Let me know if you have any questions.

like image 101
Tim Harker Avatar answered Apr 06 '23 13:04

Tim Harker


Thanks to Tim Harker for the guidance.

I have modified the directive a bit to hide the exposed scope variables and the mdOnClose so that the developer can achieve it in one additional attribute.

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;
                });
            }
        };
    });
like image 45
jose Avatar answered Apr 06 '23 14:04

jose