You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
8.4 KiB

1 year ago
  1. /*!
  2. * jQuery UI Controlgroup 1.13.2
  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: Controlgroup
  10. //>>group: Widgets
  11. //>>description: Visually groups form control widgets
  12. //>>docs: http://api.jqueryui.com/controlgroup/
  13. //>>demos: http://jqueryui.com/controlgroup/
  14. //>>css.structure: ../../themes/base/core.css
  15. //>>css.structure: ../../themes/base/controlgroup.css
  16. //>>css.theme: ../../themes/base/theme.css
  17. ( function( factory ) {
  18. "use strict";
  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. "use strict";
  31. var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
  32. $.widget( "ui.controlgroup", {
  33. version: "1.13.2",
  34. defaultElement: "<div>",
  35. options: {
  36. direction: "horizontal",
  37. disabled: null,
  38. onlyVisible: true,
  39. items: {
  40. "button": "input[type=button], input[type=submit], input[type=reset], button, a",
  41. "controlgroupLabel": ".ui-controlgroup-label",
  42. "checkboxradio": "input[type='checkbox'], input[type='radio']",
  43. "selectmenu": "select",
  44. "spinner": ".ui-spinner-input"
  45. }
  46. },
  47. _create: function() {
  48. this._enhance();
  49. },
  50. // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
  51. _enhance: function() {
  52. this.element.attr( "role", "toolbar" );
  53. this.refresh();
  54. },
  55. _destroy: function() {
  56. this._callChildMethod( "destroy" );
  57. this.childWidgets.removeData( "ui-controlgroup-data" );
  58. this.element.removeAttr( "role" );
  59. if ( this.options.items.controlgroupLabel ) {
  60. this.element
  61. .find( this.options.items.controlgroupLabel )
  62. .find( ".ui-controlgroup-label-contents" )
  63. .contents().unwrap();
  64. }
  65. },
  66. _initWidgets: function() {
  67. var that = this,
  68. childWidgets = [];
  69. // First we iterate over each of the items options
  70. $.each( this.options.items, function( widget, selector ) {
  71. var labels;
  72. var options = {};
  73. // Make sure the widget has a selector set
  74. if ( !selector ) {
  75. return;
  76. }
  77. if ( widget === "controlgroupLabel" ) {
  78. labels = that.element.find( selector );
  79. labels.each( function() {
  80. var element = $( this );
  81. if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
  82. return;
  83. }
  84. element.contents()
  85. .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
  86. } );
  87. that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
  88. childWidgets = childWidgets.concat( labels.get() );
  89. return;
  90. }
  91. // Make sure the widget actually exists
  92. if ( !$.fn[ widget ] ) {
  93. return;
  94. }
  95. // We assume everything is in the middle to start because we can't determine
  96. // first / last elements until all enhancments are done.
  97. if ( that[ "_" + widget + "Options" ] ) {
  98. options = that[ "_" + widget + "Options" ]( "middle" );
  99. } else {
  100. options = { classes: {} };
  101. }
  102. // Find instances of this widget inside controlgroup and init them
  103. that.element
  104. .find( selector )
  105. .each( function() {
  106. var element = $( this );
  107. var instance = element[ widget ]( "instance" );
  108. // We need to clone the default options for this type of widget to avoid
  109. // polluting the variable options which has a wider scope than a single widget.
  110. var instanceOptions = $.widget.extend( {}, options );
  111. // If the button is the child of a spinner ignore it
  112. // TODO: Find a more generic solution
  113. if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
  114. return;
  115. }
  116. // Create the widget if it doesn't exist
  117. if ( !instance ) {
  118. instance = element[ widget ]()[ widget ]( "instance" );
  119. }
  120. if ( instance ) {
  121. instanceOptions.classes =
  122. that._resolveClassesValues( instanceOptions.classes, instance );
  123. }
  124. element[ widget ]( instanceOptions );
  125. // Store an instance of the controlgroup to be able to reference
  126. // from the outermost element for changing options and refresh
  127. var widgetElement = element[ widget ]( "widget" );
  128. $.data( widgetElement[ 0 ], "ui-controlgroup-data",
  129. instance ? instance : element[ widget ]( "instance" ) );
  130. childWidgets.push( widgetElement[ 0 ] );
  131. } );
  132. } );
  133. this.childWidgets = $( $.uniqueSort( childWidgets ) );
  134. this._addClass( this.childWidgets, "ui-controlgroup-item" );
  135. },
  136. _callChildMethod: function( method ) {
  137. this.childWidgets.each( function() {
  138. var element = $( this ),
  139. data = element.data( "ui-controlgroup-data" );
  140. if ( data && data[ method ] ) {
  141. data[ method ]();
  142. }
  143. } );
  144. },
  145. _updateCornerClass: function( element, position ) {
  146. var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
  147. var add = this._buildSimpleOptions( position, "label" ).classes.label;
  148. this._removeClass( element, null, remove );
  149. this._addClass( element, null, add );
  150. },
  151. _buildSimpleOptions: function( position, key ) {
  152. var direction = this.options.direction === "vertical";
  153. var result = {
  154. classes: {}
  155. };
  156. result.classes[ key ] = {
  157. "middle": "",
  158. "first": "ui-corner-" + ( direction ? "top" : "left" ),
  159. "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
  160. "only": "ui-corner-all"
  161. }[ position ];
  162. return result;
  163. },
  164. _spinnerOptions: function( position ) {
  165. var options = this._buildSimpleOptions( position, "ui-spinner" );
  166. options.classes[ "ui-spinner-up" ] = "";
  167. options.classes[ "ui-spinner-down" ] = "";
  168. return options;
  169. },
  170. _buttonOptions: function( position ) {
  171. return this._buildSimpleOptions( position, "ui-button" );
  172. },
  173. _checkboxradioOptions: function( position ) {
  174. return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
  175. },
  176. _selectmenuOptions: function( position ) {
  177. var direction = this.options.direction === "vertical";
  178. return {
  179. width: direction ? "auto" : false,
  180. classes: {
  181. middle: {
  182. "ui-selectmenu-button-open": "",
  183. "ui-selectmenu-button-closed": ""
  184. },
  185. first: {
  186. "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
  187. "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
  188. },
  189. last: {
  190. "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
  191. "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
  192. },
  193. only: {
  194. "ui-selectmenu-button-open": "ui-corner-top",
  195. "ui-selectmenu-button-closed": "ui-corner-all"
  196. }
  197. }[ position ]
  198. };
  199. },
  200. _resolveClassesValues: function( classes, instance ) {
  201. var result = {};
  202. $.each( classes, function( key ) {
  203. var current = instance.options.classes[ key ] || "";
  204. current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
  205. result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
  206. } );
  207. return result;
  208. },
  209. _setOption: function( key, value ) {
  210. if ( key === "direction" ) {
  211. this._removeClass( "ui-controlgroup-" + this.options.direction );
  212. }
  213. this._super( key, value );
  214. if ( key === "disabled" ) {
  215. this._callChildMethod( value ? "disable" : "enable" );
  216. return;
  217. }
  218. this.refresh();
  219. },
  220. refresh: function() {
  221. var children,
  222. that = this;
  223. this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
  224. if ( this.options.direction === "horizontal" ) {
  225. this._addClass( null, "ui-helper-clearfix" );
  226. }
  227. this._initWidgets();
  228. children = this.childWidgets;
  229. // We filter here because we need to track all childWidgets not just the visible ones
  230. if ( this.options.onlyVisible ) {
  231. children = children.filter( ":visible" );
  232. }
  233. if ( children.length ) {
  234. // We do this last because we need to make sure all enhancment is done
  235. // before determining first and last
  236. $.each( [ "first", "last" ], function( index, value ) {
  237. var instance = children[ value ]().data( "ui-controlgroup-data" );
  238. if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
  239. var options = that[ "_" + instance.widgetName + "Options" ](
  240. children.length === 1 ? "only" : value
  241. );
  242. options.classes = that._resolveClassesValues( options.classes, instance );
  243. instance.element[ instance.widgetName ]( options );
  244. } else {
  245. that._updateCornerClass( children[ value ](), value );
  246. }
  247. } );
  248. // Finally call the refresh method on each of the child widgets.
  249. this._callChildMethod( "refresh" );
  250. }
  251. }
  252. } );
  253. } );