暫無描述

checkboxradio.js 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*!
  2. * jQuery UI Checkboxradio 1.12.1
  3. * http://jqueryui.com
  4. *
  5. * Copyright jQuery Foundation and other contributors
  6. * Released under the MIT license.
  7. * http://jquery.org/license
  8. */
  9. //>>label: Checkboxradio
  10. //>>group: Widgets
  11. //>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
  12. //>>docs: http://api.jqueryui.com/checkboxradio/
  13. //>>demos: http://jqueryui.com/checkboxradio/
  14. //>>css.structure: ../../themes/base/core.css
  15. //>>css.structure: ../../themes/base/button.css
  16. //>>css.structure: ../../themes/base/checkboxradio.css
  17. //>>css.theme: ../../themes/base/theme.css
  18. ( function( factory ) {
  19. if ( typeof define === "function" && define.amd ) {
  20. // AMD. Register as an anonymous module.
  21. define( [
  22. "jquery",
  23. "./core"
  24. ], factory );
  25. } else {
  26. // Browser globals
  27. factory( jQuery );
  28. }
  29. }( function( $ ) {
  30. $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
  31. version: "1.12.1",
  32. options: {
  33. disabled: null,
  34. label: null,
  35. icon: true,
  36. classes: {
  37. "ui-checkboxradio-label": "ui-corner-all",
  38. "ui-checkboxradio-icon": "ui-corner-all"
  39. }
  40. },
  41. _getCreateOptions: function() {
  42. var disabled, labels;
  43. var that = this;
  44. var options = this._super() || {};
  45. // We read the type here, because it makes more sense to throw a element type error first,
  46. // rather then the error for lack of a label. Often if its the wrong type, it
  47. // won't have a label (e.g. calling on a div, btn, etc)
  48. this._readType();
  49. labels = this.element.labels();
  50. // If there are multiple labels, use the last one
  51. this.label = $( labels[ labels.length - 1 ] );
  52. if ( !this.label.length ) {
  53. $.error( "No label found for checkboxradio widget" );
  54. }
  55. this.originalLabel = "";
  56. // We need to get the label text but this may also need to make sure it does not contain the
  57. // input itself.
  58. this.label.contents().not( this.element[ 0 ] ).each( function() {
  59. // The label contents could be text, html, or a mix. We concat each element to get a
  60. // string representation of the label, without the input as part of it.
  61. that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
  62. } );
  63. // Set the label option if we found label text
  64. if ( this.originalLabel ) {
  65. options.label = this.originalLabel;
  66. }
  67. disabled = this.element[ 0 ].disabled;
  68. if ( disabled != null ) {
  69. options.disabled = disabled;
  70. }
  71. return options;
  72. },
  73. _create: function() {
  74. var checked = this.element[ 0 ].checked;
  75. this._bindFormResetHandler();
  76. if ( this.options.disabled == null ) {
  77. this.options.disabled = this.element[ 0 ].disabled;
  78. }
  79. this._setOption( "disabled", this.options.disabled );
  80. this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
  81. this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
  82. if ( this.type === "radio" ) {
  83. this._addClass( this.label, "ui-checkboxradio-radio-label" );
  84. }
  85. if ( this.options.label && this.options.label !== this.originalLabel ) {
  86. this._updateLabel();
  87. } else if ( this.originalLabel ) {
  88. this.options.label = this.originalLabel;
  89. }
  90. this._enhance();
  91. if ( checked ) {
  92. this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
  93. if ( this.icon ) {
  94. this._addClass( this.icon, null, "ui-state-hover" );
  95. }
  96. }
  97. this._on( {
  98. change: "_toggleClasses",
  99. focus: function() {
  100. this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
  101. },
  102. blur: function() {
  103. this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
  104. }
  105. } );
  106. },
  107. _readType: function() {
  108. var nodeName = this.element[ 0 ].nodeName.toLowerCase();
  109. this.type = this.element[ 0 ].type;
  110. if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
  111. $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
  112. " and element.type=" + this.type );
  113. }
  114. },
  115. // Support jQuery Mobile enhanced option
  116. _enhance: function() {
  117. this._updateIcon( this.element[ 0 ].checked );
  118. },
  119. widget: function() {
  120. return this.label;
  121. },
  122. _getRadioGroup: function() {
  123. var group;
  124. var name = this.element[ 0 ].name;
  125. var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
  126. if ( !name ) {
  127. return $( [] );
  128. }
  129. if ( this.form.length ) {
  130. group = $( this.form[ 0 ].elements ).filter( nameSelector );
  131. } else {
  132. // Not inside a form, check all inputs that also are not inside a form
  133. group = $( nameSelector ).filter( function() {
  134. return $( this ).form().length === 0;
  135. } );
  136. }
  137. return group.not( this.element );
  138. },
  139. _toggleClasses: function() {
  140. var checked = this.element[ 0 ].checked;
  141. this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
  142. if ( this.options.icon && this.type === "checkbox" ) {
  143. this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
  144. ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
  145. }
  146. if ( this.type === "radio" ) {
  147. this._getRadioGroup()
  148. .each( function() {
  149. var instance = $( this ).checkboxradio( "instance" );
  150. if ( instance ) {
  151. instance._removeClass( instance.label,
  152. "ui-checkboxradio-checked", "ui-state-active" );
  153. }
  154. } );
  155. }
  156. },
  157. _destroy: function() {
  158. this._unbindFormResetHandler();
  159. if ( this.icon ) {
  160. this.icon.remove();
  161. this.iconSpace.remove();
  162. }
  163. },
  164. _setOption: function( key, value ) {
  165. // We don't allow the value to be set to nothing
  166. if ( key === "label" && !value ) {
  167. return;
  168. }
  169. this._super( key, value );
  170. if ( key === "disabled" ) {
  171. this._toggleClass( this.label, null, "ui-state-disabled", value );
  172. this.element[ 0 ].disabled = value;
  173. // Don't refresh when setting disabled
  174. return;
  175. }
  176. this.refresh();
  177. },
  178. _updateIcon: function( checked ) {
  179. var toAdd = "ui-icon ui-icon-background ";
  180. if ( this.options.icon ) {
  181. if ( !this.icon ) {
  182. this.icon = $( "<span>" );
  183. this.iconSpace = $( "<span> </span>" );
  184. this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
  185. }
  186. if ( this.type === "checkbox" ) {
  187. toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
  188. this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
  189. } else {
  190. toAdd += "ui-icon-blank";
  191. }
  192. this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
  193. if ( !checked ) {
  194. this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
  195. }
  196. this.icon.prependTo( this.label ).after( this.iconSpace );
  197. } else if ( this.icon !== undefined ) {
  198. this.icon.remove();
  199. this.iconSpace.remove();
  200. delete this.icon;
  201. }
  202. },
  203. _updateLabel: function() {
  204. // Remove the contents of the label ( minus the icon, icon space, and input )
  205. var contents = this.label.contents().not( this.element[ 0 ] );
  206. if ( this.icon ) {
  207. contents = contents.not( this.icon[ 0 ] );
  208. }
  209. if ( this.iconSpace ) {
  210. contents = contents.not( this.iconSpace[ 0 ] );
  211. }
  212. contents.remove();
  213. this.label.append( this.options.label );
  214. },
  215. refresh: function() {
  216. var checked = this.element[ 0 ].checked,
  217. isDisabled = this.element[ 0 ].disabled;
  218. this._updateIcon( checked );
  219. this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
  220. if ( this.options.label !== null ) {
  221. this._updateLabel();
  222. }
  223. if ( isDisabled !== this.options.disabled ) {
  224. this._setOptions( { "disabled": isDisabled } );
  225. }
  226. }
  227. } ] );
  228. return $.ui.checkboxradio;
  229. } ) );