Material: md-datepicker should open on focus by default

Created on 15 Sep 2015  路  13Comments  路  Source: angular/material

The datepicker should open its calendar pane as soon as it is focused by default, with an attribute option to go back to the explicit opening behavior. Focus will remain in the text input.

Pull Request fixed enhancement

Most helpful comment

Example of how you can achieve this in the meantime.

angular.module('myApp').directive('autoOpen', function () {

  function compile(tElement) {
    tElement.find('input').attr('ng-focus', 'ctrl.onFocus($event)');

    return function (scope, element, attrs, datePicker) {
      let focused = false;

      datePicker.onFocus = (event) => {
        focused = !focused;

        // The datepicker is going to return focus to the input when
        // the calendar pane is closed. We don't want to reopen the
        // the calendar pane after it is closed.
        if(focused) {
          datePicker.openCalendarPane(event);
        }
      };
    };
  }

  return {
    compile: compile,
    priority: -1,
    require: 'mdDatepicker',
    restrict: 'A'
  };
});
<md-datepicker auto-open></md-datepicker>

Personally, I believe the user should hit enter before the calendar pane opens when the date picker is focused via tabbing. In addition, the arrow button becomes obsolete.

angular.module('myApp').directive('autoOpen', function () {
  const ENTER = 13;

  function compile(tElement) {
    tElement.find('input').attr('ng-click', 'ctrl.onClick($event)').next().remove();

    return function (scope, element, attrs, datePicker) {

      datePicker.onClick = (event) => {
        datePicker.openCalendarPane(event);
      };

      datePicker.ngInputElement.on('keypress', (event) => {
        if(event.keyCode === ENTER) {
          datePicker.openCalendarPane(event);
        }
      });
    };
  }

  return {
    compile: compile,
    priority: -1,
    require: 'mdDatepicker',
    restrict: 'A'
  };
});

All 13 comments

For what it's worth, consider a disabled user that can't use a mouse and has to tab through all of the inputs. The most common case is that the user simply wants to tab past the date without changing it.

Now, by opening on focus by default, you're making the disabled user have to escape out of the calendar every time.

My plan is for nothing to change for screen reader users; the calendar will be visually present, but hidden to screen readers until "opened".

Oh OK. I thought that users with mobility impairments would use adaptive keyboards/alternative mice but no screen reader, and that screen readers would be used mostly by those with visual/audio impairments.

I meant for keyboard interaction as well. Even now, the calendar is not in the tab order; you have to use a specific keyboard shortcut (Alt + Down) to move focus into the calendar.

@jelbourn Is there a workaround to get this working until it officially lands in master?

@mattdanna You could set up a focus handler on the datepicker's input and then programatically click the "open calendar" button, but it will probably mess up the keyboard flow.

+1

Example of how you can achieve this in the meantime.

angular.module('myApp').directive('autoOpen', function () {

  function compile(tElement) {
    tElement.find('input').attr('ng-focus', 'ctrl.onFocus($event)');

    return function (scope, element, attrs, datePicker) {
      let focused = false;

      datePicker.onFocus = (event) => {
        focused = !focused;

        // The datepicker is going to return focus to the input when
        // the calendar pane is closed. We don't want to reopen the
        // the calendar pane after it is closed.
        if(focused) {
          datePicker.openCalendarPane(event);
        }
      };
    };
  }

  return {
    compile: compile,
    priority: -1,
    require: 'mdDatepicker',
    restrict: 'A'
  };
});
<md-datepicker auto-open></md-datepicker>

Personally, I believe the user should hit enter before the calendar pane opens when the date picker is focused via tabbing. In addition, the arrow button becomes obsolete.

angular.module('myApp').directive('autoOpen', function () {
  const ENTER = 13;

  function compile(tElement) {
    tElement.find('input').attr('ng-click', 'ctrl.onClick($event)').next().remove();

    return function (scope, element, attrs, datePicker) {

      datePicker.onClick = (event) => {
        datePicker.openCalendarPane(event);
      };

      datePicker.ngInputElement.on('keypress', (event) => {
        if(event.keyCode === ENTER) {
          datePicker.openCalendarPane(event);
        }
      });
    };
  }

  return {
    compile: compile,
    priority: -1,
    require: 'mdDatepicker',
    restrict: 'A'
  };
});

@daniel-nagy That's very useful..Thanks a lot

@daniel-nagy Is there a working demo ?

@sajeetharan this is now supported in Material. You can check out the datepicker demo to see an example.

  • I have resolved issues of the focus not proper in Firefox using md-datepickar component.
    WORKING DEMO
  • Refer below code : -
<md-content>
      <md-datepicker ng-model="birthdate" 
                  placeholder="Enter date" 
                  md-min-date="minDate"
                  md-max-date="maxDate" 
                  ng-focus="open()">
        </md-datepicker>
</md-content>

Controller

angular.module('datepickerBasicUsage', ['ngMaterial'])
  .controller('AppCtrl', function($scope, $timeout) {
    $scope.birthdate = new Date();
    $scope.maxDate = new Date(
      $scope.birthdate.getFullYear(),
      $scope.birthdate.getMonth(),
      $scope.birthdate.getDate());

    $scope.open = function() {
      $timeout(function () {
                  $scope.birthdate = new Date($scope.birthdate);
              }, 400);
    }
  });

It's Working fine!!!!!

@daniel-nagy thanks, working like a charm.

Was this page helpful?
0 / 5 - 0 ratings