Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

fix(menu): focus first non disabled item #9228

Merged
merged 1 commit into from
Sep 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/menu/js/menuController.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function MenuController($mdMenu, $attrs, $element, $scope, $mdUtil, $timeout, $r
var focusTarget = menuContainer[0]
.querySelector(prefixer.buildSelector(['md-menu-focus-target', 'md-autofocus']));

if (!focusTarget) focusTarget = menuContainer[0].querySelector('.md-button');
if (!focusTarget) focusTarget = menuContainer[0].querySelector('.md-button:not([disabled])');
focusTarget.focus();
};

Expand Down
17 changes: 13 additions & 4 deletions src/components/menu/js/menuServiceProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,23 @@ function MenuProvider($$interimElementProvider) {
opts.menuContentEl.on('keydown', onMenuKeyDown);
opts.menuContentEl[0].addEventListener('click', captureClickListener, true);

// kick off initial focus in the menu on the first element
// kick off initial focus in the menu on the first enabled element
var focusTarget = opts.menuContentEl[0]
.querySelector(prefixer.buildSelector(['md-menu-focus-target', 'md-autofocus']));

if ( !focusTarget ) {
var firstChild = opts.menuContentEl[0].firstElementChild;

focusTarget = firstChild && (firstChild.querySelector('.md-button:not([disabled])') || firstChild.firstElementChild);
var childrenLen = opts.menuContentEl[0].children.length;
for(var childIndex = 0; childIndex < childrenLen; childIndex++) {
var child = opts.menuContentEl[0].children[childIndex];
focusTarget = child.querySelector('.md-button:not([disabled])');
if (focusTarget) {
break;
}
if (child.firstElementChild && !child.firstElementChild.disabled) {
focusTarget = child.firstElementChild;
break;
}
}
}

focusTarget && focusTarget.focus();
Expand Down
52 changes: 52 additions & 0 deletions src/components/menu/menu.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,62 @@ describe('material.components.menu', function() {
expect(getOpenMenuContainer(menu).length).toBe(0);
}));

describe('default focus', function() {
it('should focus on first item automatically', inject(function($compile, $rootScope, $document) {
var menu = $compile(
'<md-menu>' +
'<button ng-click="$mdOpenMenu($event)">Hello World</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<button id="menuItem0" ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'<md-menu-item>' +
'<button ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'</md-menu-content>' +
'</md-menu>'
)($rootScope);

openMenu(menu);

var menuTarget = $document[0].querySelector('#menuItem0');

expect(document.activeElement).toBe(menuTarget);
}));

it('should focus on first non-disabled item', inject(function($compile, $rootScope, $document) {
var menu = $compile(
'<md-menu>' +
'<button ng-click="$mdOpenMenu($event)">Hello World</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<button disabled ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'<md-menu-item>' +
'<button id="menuItem1" ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'</md-menu-content>' +
'</md-menu>'
)($rootScope);

openMenu(menu);

var menuTarget = $document[0].querySelector('#menuItem1');

expect(document.activeElement).toBe(menuTarget);
}));
});

describe('autofocus', function() {

it('should focus a button with md-menu-focus-target', inject(function($compile, $rootScope, $document) {
var menu = $compile(
'<md-menu>' +
'<button ng-click="$mdOpenMenu($event)">Hello World</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<button ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'<md-menu-item>' +
'<button id="menuFocus" md-menu-focus-target ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
Expand All @@ -178,6 +227,9 @@ describe('material.components.menu', function() {
'<md-menu>' +
'<button ng-click="$mdOpenMenu($event)">Hello World</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<button ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
'<md-menu-item>' +
'<button id="menuFocus" md-autofocus ng-click="doSomething($event)"></button>' +
'</md-menu-item>' +
Expand Down