]> source.dussan.org Git - jquery-ui.git/commitdiff
Button: Fix backcompat when called on collection of mixed elements
authorAlexander Schmitz <arschmitz@gmail.com>
Wed, 19 Apr 2017 15:32:13 +0000 (11:32 -0400)
committerScott González <scott.gonzalez@gmail.com>
Tue, 2 May 2017 19:11:24 +0000 (15:11 -0400)
Fixes #15109
Closes gh-1808

tests/unit/button/deprecated.html
tests/unit/button/deprecated.js
ui/widgets/button.js

index 73f62921ce058eb17e87ccfbc82abd4cc0e2fac9..8b5270baaa5d1eeeaff916067aa872f6a403f518 100644 (file)
 <button id="button1">Button</button>
 <a href="#" id="anchor-button">Anchor Button</a>
 
+<div class="mixed">
+       <a href="#" id="mixed-anchor">Anchor</a>
+       <button id="mixed-button" disabled>Button</button>
+       <input type="button" value="Button" id="mixed-input">
+       <input type="checkbox" id="mixed-check" name="check"><label for="mixed-check">Check</label>
+       <input type="radio" id="mixed-radio" name="radio"><label for="mixed-radio">Radio</label>
+</div>
+
 </div>
 </body>
 </html>
index 81a0281b707df7deab25db091cd9a171c741d40e..86fca797e94b3af98312654b3a8d9d26a893d56c 100644 (file)
@@ -194,4 +194,22 @@ QUnit.test( "icon / icons options properly proxied", function( assert ) {
                "Icons secondary option sets iconPosition option to end on init" );
 } );
 
+QUnit.test( "Calling button on a collection of mixed types works correctly", function( assert ) {
+       assert.expect( 5 );
+
+       var group = $( ".mixed" ).children();
+
+       group.button();
+
+       $.each( {
+               anchor: "button",
+               button: "button",
+               check: "checkboxradio",
+               input: "button",
+               radio: "checkboxradio"
+       }, function( type, widget ) {
+               assert.ok( $( "#mixed-" + type )[ widget ]( "instance" ), type + " is a " + widget );
+       } );
+} );
+
 } );
index 50da9f9e22ec972f7529fe20f55507bfdfa57388..42cfec06d2a80702ecc9f366ee0f98d73e350f3a 100644 (file)
@@ -342,22 +342,81 @@ if ( $.uiBackCompat !== false ) {
        } );
 
        $.fn.button = ( function( orig ) {
-               return function() {
-                       if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
-                                       ( this.length && this[ 0 ].tagName === "INPUT" && (
-                                               this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
-                                       ) ) ) {
-                               return orig.apply( this, arguments );
-                       }
-                       if ( !$.ui.checkboxradio ) {
-                               $.error( "Checkboxradio widget missing" );
-                       }
-                       if ( arguments.length === 0 ) {
-                               return this.checkboxradio( {
-                                       "icon": false
+               return function( options ) {
+                       var isMethodCall = typeof options === "string";
+                       var args = Array.prototype.slice.call( arguments, 1 );
+                       var returnValue = this;
+
+                       if ( isMethodCall ) {
+
+                               // If this is an empty collection, we need to have the instance method
+                               // return undefined instead of the jQuery instance
+                               if ( !this.length && options === "instance" ) {
+                                       returnValue = undefined;
+                               } else {
+                                       this.each( function() {
+                                               var methodValue;
+                                               var type = $( this ).attr( "type" );
+                                               var name = type !== "checkbox" && type !== "radio" ?
+                                                       "button" :
+                                                       "checkboxradio";
+                                               var instance = $.data( this, "ui-" + name );
+
+                                               if ( options === "instance" ) {
+                                                       returnValue = instance;
+                                                       return false;
+                                               }
+
+                                               if ( !instance ) {
+                                                       return $.error( "cannot call methods on button" +
+                                                               " prior to initialization; " +
+                                                               "attempted to call method '" + options + "'" );
+                                               }
+
+                                               if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
+                                                       return $.error( "no such method '" + options + "' for button" +
+                                                               " widget instance" );
+                                               }
+
+                                               methodValue = instance[ options ].apply( instance, args );
+
+                                               if ( methodValue !== instance && methodValue !== undefined ) {
+                                                       returnValue = methodValue && methodValue.jquery ?
+                                                               returnValue.pushStack( methodValue.get() ) :
+                                                               methodValue;
+                                                       return false;
+                                               }
+                                       } );
+                               }
+                       } else {
+
+                               // Allow multiple hashes to be passed on init
+                               if ( args.length ) {
+                                       options = $.widget.extend.apply( null, [ options ].concat( args ) );
+                               }
+
+                               this.each( function() {
+                                       var type = $( this ).attr( "type" );
+                                       var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
+                                       var instance = $.data( this, "ui-" + name );
+
+                                       if ( instance ) {
+                                               instance.option( options || {} );
+                                               if ( instance._init ) {
+                                                       instance._init();
+                                               }
+                                       } else {
+                                               if ( name === "button" ) {
+                                                       orig.call( $( this ), options );
+                                                       return;
+                                               }
+
+                                               $( this ).checkboxradio( $.extend( { icon: false }, options ) );
+                                       }
                                } );
                        }
-                       return this.checkboxradio.apply( this, arguments );
+
+                       return returnValue;
                };
        } )( $.fn.button );