Menu: Don't move focus from the active item on click. Fixes #8552 - selected value overwritten/not correctly set.

This commit is contained in:
Scott González 2012-09-05 16:07:36 -04:00
parent 6abb10766c
commit e162fddd95
2 changed files with 32 additions and 21 deletions

View File

@ -57,13 +57,15 @@ asyncTest( "handle blur", function() {
}); });
click( element, "1" ); click( element, "1" );
setTimeout( function() { setTimeout(function() {
element.blur(); element.blur();
start(); setTimeout(function() {
}, 350 ); start();
}, 350 );
});
}); });
asyncTest( "handle blur on click", function() { asyncTest( "handle blur via click outside", function() {
expect( 1 ); expect( 1 );
var blurHandled = false, var blurHandled = false,
element = $( "#menu1" ).menu({ element = $( "#menu1" ).menu({
@ -77,10 +79,12 @@ asyncTest( "handle blur on click", function() {
}); });
click( element, "1" ); click( element, "1" );
setTimeout( function() { setTimeout(function() {
$( "<a>", { id: "remove"} ).appendTo( "body" ).trigger( "click" ); $( "<a>", { id: "remove"} ).appendTo( "body" ).trigger( "click" );
start(); setTimeout(function() {
}, 350 ); start();
}, 350 );
});
}); });
test( "handle focus of menu with active item", function() { test( "handle focus of menu with active item", function() {

35
ui/jquery.ui.menu.js vendored
View File

@ -72,17 +72,23 @@ $.widget( "ui.menu", {
event.preventDefault(); event.preventDefault();
}, },
"click .ui-menu-item:has(a)": function( event ) { "click .ui-menu-item:has(a)": function( event ) {
var target = $( event.target ); var target = $( event.target ).closest( ".ui-menu-item" );
if ( !mouseHandled && target.closest( ".ui-menu-item" ).not( ".ui-state-disabled" ).length ) { if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
mouseHandled = true; mouseHandled = true;
this.select( event ); this.select( event );
// Open submenu on click // Open submenu on click
if ( this.element.has( ".ui-menu" ).length ) { if ( target.has( ".ui-menu" ).length ) {
this.expand( event ); this.expand( event );
} else if ( !this.element.is(":focus") ) { } else if ( !this.element.is( ":focus" ) ) {
// Redirect focus to the menu // Redirect focus to the menu
this.element.focus(); this.element.trigger( "focus", [ true ] );
// If the active item is on the top level, let it stay active.
// Otherwise, blur the active item since it is no longer visible.
if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
clearTimeout( this.timer );
}
} }
} }
}, },
@ -95,12 +101,14 @@ $.widget( "ui.menu", {
}, },
mouseleave: "collapseAll", mouseleave: "collapseAll",
"mouseleave .ui-menu": "collapseAll", "mouseleave .ui-menu": "collapseAll",
focus: function( event ) { focus: function( event, keepActiveItem ) {
// If there's already an active item, keep it active // If there's already an active item, keep it active
// If not, activate the first item // If not, activate the first item
var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
this.focus( event, item ); if ( !keepActiveItem ) {
this.focus( event, item );
}
}, },
blur: function( event ) { blur: function( event ) {
this._delay(function() { this._delay(function() {
@ -195,7 +203,7 @@ $.widget( "ui.menu", {
this.collapse( event ); this.collapse( event );
break; break;
case $.ui.keyCode.RIGHT: case $.ui.keyCode.RIGHT:
if ( !this.active.is( ".ui-state-disabled" ) ) { if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
this.expand( event ); this.expand( event );
} }
break; break;
@ -587,12 +595,11 @@ $.widget( "ui.menu", {
}, },
select: function( event ) { select: function( event ) {
// Save active reference before collapseAll triggers blur // TODO: It should never be possible to not have an active item at this
var ui = { // point, but the tests don't trigger mouseenter before click.
// Selecting a menu item removes the active item causing multiple clicks to be missing an item this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
item: this.active || $( event.target ).closest( ".ui-menu-item" ) var ui = { item: this.active };
}; if ( !this.active.has( ".ui-menu" ).length ) {
if ( !ui.item.has( ".ui-menu" ).length ) {
this.collapseAll( event, true ); this.collapseAll( event, true );
} }
this._trigger( "select", event, ui ); this._trigger( "select", event, ui );