From 288fe45ff1c6673cf832ef347f0b36c288c8194f Mon Sep 17 00:00:00 2001 From: scottjehl Date: Fri, 14 Jan 2011 13:02:24 -0500 Subject: [PATCH 1/5] added option for useNativeMenu. Should be updated so, when set, the custom menu markup is never created. --- js/jquery.mobile.forms.select.js | 55 ++++++++++++------- themes/default/jquery.mobile.forms.select.css | 4 +- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js index a28382e4..728eb873 100644 --- a/js/jquery.mobile.forms.select.js +++ b/js/jquery.mobile.forms.select.js @@ -18,7 +18,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { menuPageTheme: 'b', overlayTheme: 'a', hidePlaceholderMenuItems: true, - closeText: 'Close' + closeText: 'Close', + useNativeMenu: true }, _create: function(){ @@ -27,7 +28,6 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { o = this.options, select = this.element - .attr( "tabindex", "-1" ) .wrap( "
" ), selectID = select.attr( "id" ), @@ -152,26 +152,39 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { select .change(function(){ self.refresh(); - }) - .focus(function(){ - $(this).blur(); - button.focus(); - }); - - //button events - button - .bind( $.support.touch ? "touchend" : "click" , function( event ){ - if( $( this ).data( "moved" ) ){ - $( this ).removeData( "moved" ); - } - else{ - self.open(); - event.preventDefault(); - } - }) - .bind( "touchmove", function(event){ - $( this ).data( "moved", true ); }); + + //support for using the native select menu with a custom button + if( o.useNativeMenu ){ + + select + .appendTo(button) + .bind( "touchstart mousedown", function( e ){ + //add active class to button + button.addClass( $.mobile.activeBtnClass ); + + //ensure button isn't clicked + e.stopPropagation(); + }) + .bind( "focus mouseover", function(){ + button.trigger( "mouseover" ); + }) + .bind( "blur mouseout", function(){ + button + .trigger( "mouseout" ) + .removeClass( $.mobile.activeBtnClass ); + }); + + button.attr( "tabindex", "-1" ); + } + else { + select + .attr( "tabindex", "-1" ) + .focus(function(){ + $(this).blur(); + button.focus(); + }); + } //events for list items list.delegate("li:not(.ui-disabled, .ui-li-divider)", "click", function(event){ diff --git a/themes/default/jquery.mobile.forms.select.css b/themes/default/jquery.mobile.forms.select.css index 8023f435..efefcf5a 100644 --- a/themes/default/jquery.mobile.forms.select.css +++ b/themes/default/jquery.mobile.forms.select.css @@ -3,8 +3,10 @@ * Copyright (c) jQuery Project * Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. */ -.ui-select { display: block; } +.ui-select { display: block; position: relative; } .ui-select select { position: absolute; left: -9999px; top: -9999px; } +.ui-select a select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; } + .ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } .ui-select .ui-btn-icon-right .ui-icon { right: 15px; } From 0cdf9df11cb04899e465bd6cd0f1cab505330c8b Mon Sep 17 00:00:00 2001 From: scottjehl Date: Fri, 14 Jan 2011 13:02:24 -0500 Subject: [PATCH 2/5] added option for useNativeMenu. Should be updated so, when set, the custom menu markup is never created. --- js/jquery.mobile.forms.select.js | 36 +++++++++++++++++-- themes/default/jquery.mobile.forms.select.css | 4 ++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js index f892cddf..9b0e7fb0 100644 --- a/js/jquery.mobile.forms.select.js +++ b/js/jquery.mobile.forms.select.js @@ -18,7 +18,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { menuPageTheme: 'b', overlayTheme: 'a', hidePlaceholderMenuItems: true, - closeText: 'Close' + closeText: 'Close', + useNativeMenu: false }, _create: function(){ @@ -27,7 +28,6 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { o = this.options, select = this.element - .attr( "tabindex", "-1" ) .wrap( "
" ), selectID = select.attr( "id" ), @@ -151,6 +151,36 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { //disable if specified if( o.disabled ){ this.disable(); } + //support for using the native select menu with a custom button + if( o.useNativeMenu ){ + + select + .appendTo(button) + .bind( "touchstart mousedown", function( e ){ + //add active class to button + button.addClass( $.mobile.activeBtnClass ); + + //ensure button isn't clicked + e.stopPropagation(); + }) + .bind( "focus mouseover", function(){ + button.trigger( "mouseover" ); + }) + .bind( "blur mouseout", function(){ + button + .trigger( "mouseout" ) + .removeClass( $.mobile.activeBtnClass ); + }); + + button.attr( "tabindex", "-1" ); + } + else { + select + .attr( "tabindex", "-1" ) + .focus(function(){ + $(this).blur(); + button.focus(); + }); //events on native select select .change(function(){ @@ -189,6 +219,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { } }); + } + //events for list items list.delegate("li:not(.ui-disabled, .ui-li-divider)", "click", function(event){ diff --git a/themes/default/jquery.mobile.forms.select.css b/themes/default/jquery.mobile.forms.select.css index 8023f435..efefcf5a 100644 --- a/themes/default/jquery.mobile.forms.select.css +++ b/themes/default/jquery.mobile.forms.select.css @@ -3,8 +3,10 @@ * Copyright (c) jQuery Project * Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. */ -.ui-select { display: block; } +.ui-select { display: block; position: relative; } .ui-select select { position: absolute; left: -9999px; top: -9999px; } +.ui-select a select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; } + .ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } .ui-select .ui-btn-icon-right .ui-icon { right: 15px; } From aa234961cca905cccb77b1f1339de6dd6bb43a63 Mon Sep 17 00:00:00 2001 From: John Bender Date: Tue, 25 Jan 2011 22:50:55 -0800 Subject: [PATCH 3/5] whitespace correction on rebase fix --- js/jquery.mobile.forms.select.js | 65 ++++++++++++++++---------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js index 9b0e7fb0..d3bc924a 100644 --- a/js/jquery.mobile.forms.select.js +++ b/js/jquery.mobile.forms.select.js @@ -181,43 +181,44 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { $(this).blur(); button.focus(); }); - //events on native select - select - .change(function(){ - self.refresh(); - }) - .focus(function(){ - $(this).blur(); - button.focus(); - }); - //button events - button - .bind( "touchstart" ,function( event ){ - //set startTouches to cached copy of - $( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) ); - }) - .bind( $.support.touch ? "touchend" : "mouseup" , function( event ){ - //if it's a scroll, don't open - if( $( this ).data( "moved" ) ){ - $( this ).removeData( "moved" ); - } - else{ - self.open(); - } - event.preventDefault(); - }) - .bind( "touchmove", function( event ){ - //if touch moved enough, set data moved and don't open menu - var thisTouches = event.originalEvent.touches[ 0 ], + //events on native select + select + .change(function(){ + self.refresh(); + }) + .focus(function(){ + $(this).blur(); + button.focus(); + }); + + //button events + button + .bind( "touchstart" ,function( event ){ + //set startTouches to cached copy of + $( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) ); + }) + .bind( $.support.touch ? "touchend" : "mouseup" , function( event ){ + //if it's a scroll, don't open + if( $( this ).data( "moved" ) ){ + $( this ).removeData( "moved" ); + } + else{ + self.open(); + } + event.preventDefault(); + }) + .bind( "touchmove", function( event ){ + //if touch moved enough, set data moved and don't open menu + var thisTouches = event.originalEvent.touches[ 0 ], startTouches = $( this ).data( "startTouches" ), deltaX = Math.abs(thisTouches.pageX - startTouches.pageX), deltaY = Math.abs(thisTouches.pageY - startTouches.pageY); - if( deltaX > 10 || deltaY > 10 ){ - $( this ).data( "moved", true ); - } - }); + if( deltaX > 10 || deltaY > 10 ){ + $( this ).data( "moved", true ); + } + }); } From 244e46b8edacc5a4af852eb6fd3d98c0369ab127 Mon Sep 17 00:00:00 2001 From: John Bender Date: Tue, 25 Jan 2011 23:11:15 -0800 Subject: [PATCH 4/5] data-native attribute check for native select menus Fixes #847 --- js/jquery.mobile.forms.select.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js index d3bc924a..db6689dd 100644 --- a/js/jquery.mobile.forms.select.js +++ b/js/jquery.mobile.forms.select.js @@ -115,6 +115,9 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { menuType; + // set to native menu + o.useNativeMenu = select.is( "[data-native]"); + // add counter for multi selects if( isMultiple ){ self.buttonCount = $('') From b81248f2381659cfa83c4959af5f1c3512ac8327 Mon Sep 17 00:00:00 2001 From: John Bender Date: Wed, 26 Jan 2011 21:20:40 -0800 Subject: [PATCH 5/5] fixed android select menu failure with a delay. I'm doubtful that this is the best solution to the problem but the cause was the click being passed through to the screen or the select menu itself a split second after opening. Open to alternatives. Fixes #873 --- js/jquery.mobile.forms.select.js | 41 +++++++++++++++++------------- tests/unit/select/index.html | 9 +++++++ tests/unit/select/select_events.js | 32 +++++++++++++++++++++++ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/js/jquery.mobile.forms.select.js b/js/jquery.mobile.forms.select.js index db6689dd..e8d79ba5 100644 --- a/js/jquery.mobile.forms.select.js +++ b/js/jquery.mobile.forms.select.js @@ -156,7 +156,6 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { //support for using the native select menu with a custom button if( o.useNativeMenu ){ - select .appendTo(button) .bind( "touchstart mousedown", function( e ){ @@ -176,8 +175,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { }); button.attr( "tabindex", "-1" ); - } - else { + } else { select .attr( "tabindex", "-1" ) .focus(function(){ @@ -197,7 +195,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { //button events button - .bind( "touchstart" ,function( event ){ + .bind( "touchstart" , function( event ){ //set startTouches to cached copy of $( this ).data( "startTouches", $.extend({}, event.originalEvent.touches[ 0 ]) ); }) @@ -205,8 +203,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { //if it's a scroll, don't open if( $( this ).data( "moved" ) ){ $( this ).removeData( "moved" ); - } - else{ + } else { self.open(); } event.preventDefault(); @@ -222,12 +219,10 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { $( this ).data( "moved", true ); } }); - } //events for list items list.delegate("li:not(.ui-disabled, .ui-li-divider)", "click", function(event){ - // clicking on the list item fires click on the link in listview.js. // to prevent this handler from firing twice if the link isn't clicked on, // short circuit unless the target is the link @@ -260,16 +255,19 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { }); //events on "screen" overlay + close button - screen.add( headerClose ).add( menuPageClose ).click(function(event){ - self.close(); - event.preventDefault(); + screen + .add( headerClose ) + .add( menuPageClose ) + .bind("click", function(event){ + self.close(); + event.preventDefault(); - // if the dialog's close icon was clicked, prevent the dialog's close - // handler from firing. selectmenu's should take precedence - if( $.contains(menuPageClose[0], event.target) ){ - event.stopImmediatePropagation(); - } - }); + // if the dialog's close icon was clicked, prevent the dialog's close + // handler from firing. selectmenu's should take precedence + if( $.contains(menuPageClose[0], event.target) ){ + event.stopImmediatePropagation(); + } + }); }, _buildList: function(){ @@ -457,10 +455,15 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { focusMenuItem(); } + + // wait before the dialog can be closed + setTimeout(function(){ + self.isOpen = true; + }, 400); }, close: function(){ - if( this.options.disabled ){ return; } + if( this.options.disabled || !this.isOpen ){ return; } var self = this; function focusButton(){ @@ -484,6 +487,8 @@ $.widget( "mobile.selectmenu", $.mobile.widget, { focusButton(); } + // allow the dialog to be closed again + this.isOpen = false; }, disable: function(){ diff --git a/tests/unit/select/index.html b/tests/unit/select/index.html index 0d932231..0aeae0b9 100644 --- a/tests/unit/select/index.html +++ b/tests/unit/select/index.html @@ -61,6 +61,15 @@
+
+ +
+