diff --git a/js/jquery.mobile.forms.checkboxradio.js b/js/jquery.mobile.forms.checkboxradio.js index 61d37588..18d14d98 100644 --- a/js/jquery.mobile.forms.checkboxradio.js +++ b/js/jquery.mobile.forms.checkboxradio.js @@ -3,7 +3,7 @@ * Copyright (c) jQuery Project * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license -*/ +*/ (function($, undefined ) { $.widget( "mobile.checkboxradio", $.mobile.widget, { options: { @@ -30,17 +30,17 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { icon: this.element.parents( "[data-type='horizontal']" ).length ? undefined : uncheckedicon, shadow: false }); - - // wrap the input + label in a div + + // wrap the input + label in a div input .add( label ) .wrapAll( "
" ); - + label.bind({ mouseover: function() { if( $(this).parent().is('.ui-disabled') ){ return false; } }, - + "touchmove": function( event ){ var oe = event.originalEvent.touches[0]; if( label.data("movestart") ){ @@ -53,8 +53,13 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { label.data("movestart", [ parseFloat( oe.pageX ), parseFloat( oe.pageY ) ]); } }, - + "touchend mouseup": function( event ){ + if ( input.is( ":disabled" ) ){ + event.preventDefault(); + return; + } + label.removeData("movestart"); if( label.data("etype") && label.data("etype") !== event.type || label.data("moved") ){ label.removeData("etype").removeData("moved"); @@ -69,46 +74,46 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { self._updateAll(); event.preventDefault(); }, - + click: false - + }); - + input .bind({ mousedown: function(){ this._cacheVals(); }, - + click: function(){ self._updateAll(); }, - focus: function() { - label.addClass( "ui-focus" ); + focus: function() { + label.addClass( "ui-focus" ); }, blur: function() { label.removeClass( "ui-focus" ); } }); - + this.refresh(); - + }, - + _cacheVals: function(){ this._getInputSet().each(function(){ $(this).data("cacheVal", $(this).is(":checked") ); - }); + }); }, - + //returns either a set of radios with the same name attribute, or a single checkbox _getInputSet: function(){ return this.element.closest( "form,fieldset,[data-role='page']" ) .find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.element.attr( "type" ) +"']" ); }, - + _updateAll: function(){ this._getInputSet().each(function(){ var dVal = $(this).data("cacheVal"); @@ -118,7 +123,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { }) .checkboxradio( "refresh" ); }, - + refresh: function( ){ var input = this.element, label = input.closest("form,fieldset,[data-role='page']").find("label[for='" + input.attr( "id" ) + "']"), @@ -126,18 +131,18 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { icon = label.find( ".ui-icon" ), checkedicon = "ui-icon-" + inputtype + "-on", uncheckedicon = "ui-icon-" + inputtype + "-off"; - + if ( input[0].checked ) { label.addClass( "ui-btn-active" ); icon.addClass( checkedicon ); icon.removeClass( uncheckedicon ); } else { - label.removeClass( "ui-btn-active" ); + label.removeClass( "ui-btn-active" ); icon.removeClass( checkedicon ); icon.addClass( uncheckedicon ); } - + if( input.is( ":disabled" ) ){ this.disable(); } @@ -145,11 +150,11 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, { this.enable(); } }, - + disable: function(){ this.element.attr("disabled",true).parent().addClass("ui-disabled"); }, - + enable: function(){ this.element.attr("disabled",false).parent().removeClass("ui-disabled"); } diff --git a/js/jquery.mobile.init.js b/js/jquery.mobile.init.js index 500f52b5..619f9e04 100644 --- a/js/jquery.mobile.init.js +++ b/js/jquery.mobile.init.js @@ -20,7 +20,12 @@ //add dialogs, set data-url attrs $pages.add( "[data-role='dialog']" ).each(function(){ - $(this).attr( "data-url", $(this).attr( "id" )); + var $this = $(this); + + // unless the data url is already set set it to the id + if( !$this.data('url') ){ + $this.attr( "data-url", $this.attr( "id" ) ); + } }); //define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback) diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js index 4c0d1afb..094373ff 100644 --- a/js/jquery.mobile.navigation.js +++ b/js/jquery.mobile.navigation.js @@ -225,6 +225,7 @@ else{ // defer execution for consistency between webkit/non webkit setTimeout(callback, 0); + return $(this); } }; @@ -287,20 +288,25 @@ // guess if it came from the history menu if( fromHashChange ){ + // determine new page index + var newActiveIndex; + // check if url is in history and if it's ahead or behind current page $.each( urlHistory.stack, function( i ){ //if the url is in the stack, it's a forward or a back if( this.url === url ){ - urlIndex = i; //define back and forward by whether url is older or newer than current page back = i < urlHistory.activeIndex; //forward set to opposite of back forward = !back; //reset activeIndex to this one - urlHistory.activeIndex = i; + newActiveIndex = i; } }); + // save new page index + urlHistory.activeIndex = newActiveIndex ? newActiveIndex : urlHistory.activeIndex; + //if it's a back, use reverse animation if( back ){ reverse = true; diff --git a/tests/jquery.testHelper.js b/tests/jquery.testHelper.js index b1d94bad..244de4e1 100644 --- a/tests/jquery.testHelper.js +++ b/tests/jquery.testHelper.js @@ -53,6 +53,16 @@ } else { setTimeout($.testHelper.hideActivePageWhenComplete, 500); } + }, + + openPage: function(hash){ + location.href = location.href.split('#')[0] + hash; + }, + + sequence: function(fns, interval){ + $.each(fns, function(i, fn){ + setTimeout(fn, i * interval); + }); } }; })(jQuery); \ No newline at end of file diff --git a/tests/unit/checkboxradio/checkboxradio_core.js b/tests/unit/checkboxradio/checkboxradio_core.js new file mode 100644 index 00000000..490c55c7 --- /dev/null +++ b/tests/unit/checkboxradio/checkboxradio_core.js @@ -0,0 +1,29 @@ +/* + * mobile page unit tests + */ +(function($){ + module('jquery.mobile.forms.checkboxradio.js'); + + test( "widget can be disabled and enabled", function(){ + var input = $("#checkbox-1"); + var button = input.parent().find(".ui-btn"); + + input.checkboxradio("disable"); + input.checkboxradio("enable"); + ok(!input.attr("disabled"), "start input as enabled"); + ok(!input.parent().hasClass("ui-disabled"), "no disabled styles"); + ok(!input.attr("checked"), "not checked before click"); + button.trigger("mouseup"); + ok(input.attr("checked"), "checked after click"); + ok(button.hasClass("ui-btn-active"), "active styles after click"); + button.trigger("mouseup"); + + input.checkboxradio("disable"); + ok(input.attr("disabled"), "input disabled"); + ok(input.parent().hasClass("ui-disabled"), "disabled styles"); + ok(!input.attr("checked"), "not checked before click"); + button.trigger("mouseup"); + ok(!input.attr("checked"), "not checked after click"); + ok(!button.hasClass("ui-btn-active"), "no active styles after click"); + }); +})(jQuery); \ No newline at end of file diff --git a/tests/unit/checkboxradio/index.html b/tests/unit/checkboxradio/index.html new file mode 100644 index 00000000..3117aa6e --- /dev/null +++ b/tests/unit/checkboxradio/index.html @@ -0,0 +1,37 @@ + + + + +