Skip to content

Commit abc9e7c

Browse files
arschmitzscottgonzalez
authored andcommitted
Button: Fix backcompat when called on collection of mixed elements
Fixes #15109 Closes jquerygh-1808
1 parent c866e45 commit abc9e7c

File tree

3 files changed

+99
-14
lines changed

3 files changed

+99
-14
lines changed

tests/unit/button/deprecated.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656
<button id="button1">Button</button>
5757
<a href="#" id="anchor-button">Anchor Button</a>
5858

59+
<div class="mixed">
60+
<a href="#" id="mixed-anchor">Anchor</a>
61+
<button id="mixed-button" disabled>Button</button>
62+
<input type="button" value="Button" id="mixed-input">
63+
<input type="checkbox" id="mixed-check" name="check"><label for="mixed-check">Check</label>
64+
<input type="radio" id="mixed-radio" name="radio"><label for="mixed-radio">Radio</label>
65+
</div>
66+
5967
</div>
6068
</body>
6169
</html>

tests/unit/button/deprecated.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,22 @@ QUnit.test( "icon / icons options properly proxied", function( assert ) {
194194
"Icons secondary option sets iconPosition option to end on init" );
195195
} );
196196

197+
QUnit.test( "Calling button on a collection of mixed types works correctly", function( assert ) {
198+
assert.expect( 5 );
199+
200+
var group = $( ".mixed" ).children();
201+
202+
group.button();
203+
204+
$.each( {
205+
anchor: "button",
206+
button: "button",
207+
check: "checkboxradio",
208+
input: "button",
209+
radio: "checkboxradio"
210+
}, function( type, widget ) {
211+
assert.ok( $( "#mixed-" + type )[ widget ]( "instance" ), type + " is a " + widget );
212+
} );
213+
} );
214+
197215
} );

ui/widgets/button.js

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -342,22 +342,81 @@ if ( $.uiBackCompat !== false ) {
342342
} );
343343

344344
$.fn.button = ( function( orig ) {
345-
return function() {
346-
if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
347-
( this.length && this[ 0 ].tagName === "INPUT" && (
348-
this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
349-
) ) ) {
350-
return orig.apply( this, arguments );
351-
}
352-
if ( !$.ui.checkboxradio ) {
353-
$.error( "Checkboxradio widget missing" );
354-
}
355-
if ( arguments.length === 0 ) {
356-
return this.checkboxradio( {
357-
"icon": false
345+
return function( options ) {
346+
var isMethodCall = typeof options === "string";
347+
var args = Array.prototype.slice.call( arguments, 1 );
348+
var returnValue = this;
349+
350+
if ( isMethodCall ) {
351+
352+
// If this is an empty collection, we need to have the instance method
353+
// return undefined instead of the jQuery instance
354+
if ( !this.length && options === "instance" ) {
355+
returnValue = undefined;
356+
} else {
357+
this.each( function() {
358+
var methodValue;
359+
var type = $( this ).attr( "type" );
360+
var name = type !== "checkbox" && type !== "radio" ?
361+
"button" :
362+
"checkboxradio";
363+
var instance = $.data( this, "ui-" + name );
364+
365+
if ( options === "instance" ) {
366+
returnValue = instance;
367+
return false;
368+
}
369+
370+
if ( !instance ) {
371+
return $.error( "cannot call methods on button" +
372+
" prior to initialization; " +
373+
"attempted to call method '" + options + "'" );
374+
}
375+
376+
if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
377+
return $.error( "no such method '" + options + "' for button" +
378+
" widget instance" );
379+
}
380+
381+
methodValue = instance[ options ].apply( instance, args );
382+
383+
if ( methodValue !== instance && methodValue !== undefined ) {
384+
returnValue = methodValue && methodValue.jquery ?
385+
returnValue.pushStack( methodValue.get() ) :
386+
methodValue;
387+
return false;
388+
}
389+
} );
390+
}
391+
} else {
392+
393+
// Allow multiple hashes to be passed on init
394+
if ( args.length ) {
395+
options = $.widget.extend.apply( null, [ options ].concat( args ) );
396+
}
397+
398+
this.each( function() {
399+
var type = $( this ).attr( "type" );
400+
var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
401+
var instance = $.data( this, "ui-" + name );
402+
403+
if ( instance ) {
404+
instance.option( options || {} );
405+
if ( instance._init ) {
406+
instance._init();
407+
}
408+
} else {
409+
if ( name === "button" ) {
410+
orig.call( $( this ), options );
411+
return;
412+
}
413+
414+
$( this ).checkboxradio( $.extend( { icon: false }, options ) );
415+
}
358416
} );
359417
}
360-
return this.checkboxradio.apply( this, arguments );
418+
419+
return returnValue;
361420
};
362421
} )( $.fn.button );
363422

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy