/*! * jQuery UI Checkboxradio @VERSION * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/checkboxradio/ */ ( function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./core", "./widget" ], factory ); } else { // Browser globals factory( jQuery ); } }( function( $ ) { // Remove and replace with reset handler extension var formResetHandler = function() { var form = $( this ); // Wait for the form reset to actually happen before refreshing setTimeout( function() { // We dont filter for css only versions since css only is not supported form.find( ".ui-checkboxradio" ).checkboxradio( "refresh" ); } ); }; $.widget( "ui.checkboxradio", { version: "@VERSION", options: { disabled: null, label: null, icon: true, classes: { "ui-checkboxradio-label": "ui-corner-all", "ui-checkboxradio-icon": "ui-corner-all" } }, _getCreateOptions: function() { var disabled, labels, that = this, options = this._super() || {}; // We read the type here, because it makes more sense to throw a element type error first, // rather then the error for lack of a label. Often if its the wrong type, it // won't have a label (e.g. calling on a div, btn, etc) this._readType(); labels = this.element.labels(); // Todo: For now we will use the last label we need to check about the best // way to handle multiple labels with some accessability experts this.label = $( labels[ labels.length - 1 ] ); if ( !this.label.length ) { $.error( "No label found for checkboxradio widget" ); } this.originalLabel = ""; // We need to get the label text but this may also need to make sure it does not contain the // input itself. this.label.contents().not( this.element ).each( function() { // The label contents could be text html or a mix we concat each element to get a string // representation of the label without the input as part of it. that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; } ); // Set the label option if we found label text if ( this.originalLabel ) { options.label = this.originalLabel; } disabled = this.element[ 0 ].disabled; if ( disabled != null ) { options.disabled = disabled; } return options; }, _create: function() { var formCount, checked = this.element[ 0 ].checked, form = this.element.form(); this.formParent = !!form.length ? form : $( "body" ); formCount = this.formParent.data( "uiCheckboxradioCount" ) || 0; // We don't use _on and _off here because we want all the checkboxes in the same form to use // single handler which handles all the checkboxradio widgets in the form if ( formCount === 0 ) { this.formParent.on( "reset." + this.widgetFullName, formResetHandler ); } this.formParent.data( "uiCheckboxradioCount", formCount + 1 ); if ( this.options.disabled == null ) { this.options.disabled = this.element[ 0 ].disabled || false; } this._setOption( "disabled", this.options.disabled ); this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); if ( this.type === "radio" ) { this._addClass( this.label, "ui-checkboxradio-radio-label" ); } if ( this.options.label && this.options.label !== this.originalLabel ) { this._updateLabel(); } else if ( this.originalLabel ) { this.options.label = this.originalLabel; } this._enhance(); if ( checked ) { this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); this._addClass( this.icon, null, "ui-state-hover" ); } this._on( { "change": "_toggleClasses", "focus": function() { this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); }, "blur": function() { this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); } } ); }, _readType: function() { var nodeName = this.element[ 0 ].nodeName.toLowerCase(); this.type = this.element[ 0 ].type; if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + " and element.type=" + this.type ); } }, // Support jQuery Mobile enhanced option _enhance: function() { this._updateIcon( this.element[ 0 ].checked ); }, widget: function() { return this.label; }, _getRadioGroup: function() { var name = this.element[ 0 ].name, that = this, radios = $( [] ); if ( name ) { name = $.ui.escapeSelector( name ); radios = this.formParent.find( "[name='" + $.ui.escapeSelector( name ) + "']" ).filter( function() { var form = $( this ).form(); return ( form.length ? form : $( "body" ) )[ 0 ] === that.formParent[ 0 ]; } ); } return radios.not( this.element ); }, _toggleClasses: function() { var checked = this.element[ 0 ].checked; this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); if ( this.options.icon && this.type === "checkbox" ) { // We add ui-state-highlight to change the icon color this._toggleClass( this.icon, null, "ui-icon-check ui-state-highlight", checked ) ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); } if ( this.type === "radio" ) { this._getRadioGroup() .each( function() { var instance = $( this ).checkboxradio( "instance" ); if ( instance ) { instance._removeClass( instance.label, "ui-checkboxradio-checked", "ui-state-active" ); } } ); } }, _destroy: function() { var formCount = this.formParent.data( "uiCheckboxradioCount" ) - 1; this.formParent.data( "uiCheckboxradioCount", formCount ); if ( formCount === 0 ) { this.formParent.off( "reset." + this.widgetFullName, formResetHandler ); } if ( this.icon ) { this.icon.remove(); this.iconSpace.remove(); } }, _setOption: function( key, value ) { // We don't alow the value to be set to nothing if ( key === "label" && !value ) { return; } this._super( key, value ); if ( key === "disabled" ) { this._toggleClass( this.label, null, "ui-state-disabled", value ); this.element[ 0 ].disabled = value; // Don't refresh if disabled return; } this.refresh(); }, _updateIcon: function( checked ) { var toAdd = "ui-icon ui-icon-background "; if ( this.options.icon ) { if ( !this.icon ) { this.icon = $( "" ); this.iconSpace = $( " " ); this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); } if ( this.type === "checkbox" ) { toAdd += checked ? "ui-icon-check" : "ui-icon-blank"; this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); } else { toAdd += "ui-icon-blank"; } this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); if ( !checked ) { this._removeClass( this.icon, null, "ui-icon-check" ); } this.icon.prependTo( this.label ).after( this.iconSpace ); } else if ( this.icon !== undefined ) { this.icon.remove(); this.iconSpace.remove(); delete this.icon; } }, _updateLabel: function() { // Remove the contents of the label ( minus the icon, icon space, and input ) this.label.contents().not( this.element.add( this.icon ).add( this.iconSpace ) ).remove(); this.label.append( this.options.label ); }, refresh: function() { var checked = this.element[ 0 ].checked, isDisabled = this.element[ 0 ].disabled; this._updateIcon( checked ); this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); if ( this.options.label !== null ) { this._updateLabel(); } if ( isDisabled !== this.options.disabled ) { this._setOptions( { "disabled": isDisabled } ); } } } ); return $.ui.checkboxradio; } ) );