/hippo/src/main/webapp/ext/src/widgets/form/CheckboxGroup.js

http://hdbc.googlecode.com/ · JavaScript · 419 lines · 244 code · 39 blank · 136 comment · 49 complexity · e142d432b624d7b449b76eb5f9c18e94 MD5 · raw file

  1. /*!
  2. * Ext JS Library 3.0.0
  3. * Copyright(c) 2006-2009 Ext JS, LLC
  4. * licensing@extjs.com
  5. * http://www.extjs.com/license
  6. */
  7. /**
  8. * @class Ext.form.CheckboxGroup
  9. * @extends Ext.form.Field
  10. * <p>A grouping container for {@link Ext.form.Checkbox} controls.</p>
  11. * <p>Sample usage:</p>
  12. * <pre><code>
  13. var myCheckboxGroup = new Ext.form.CheckboxGroup({
  14. id:'myGroup',
  15. xtype: 'checkboxgroup',
  16. fieldLabel: 'Single Column',
  17. itemCls: 'x-check-group-alt',
  18. // Put all controls in a single column with width 100%
  19. columns: 1,
  20. items: [
  21. {boxLabel: 'Item 1', name: 'cb-col-1'},
  22. {boxLabel: 'Item 2', name: 'cb-col-2', checked: true},
  23. {boxLabel: 'Item 3', name: 'cb-col-3'}
  24. ]
  25. });
  26. * </code></pre>
  27. * @constructor
  28. * Creates a new CheckboxGroup
  29. * @param {Object} config Configuration options
  30. * @xtype checkboxgroup
  31. */
  32. Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
  33. /**
  34. * @cfg {Array} items An Array of {@link Ext.form.Checkbox Checkbox}es or Checkbox config objects
  35. * to arrange in the group.
  36. */
  37. /**
  38. * @cfg {String/Number/Array} columns Specifies the number of columns to use when displaying grouped
  39. * checkbox/radio controls using automatic layout. This config can take several types of values:
  40. * <ul><li><b>'auto'</b> : <p class="sub-desc">The controls will be rendered one per column on one row and the width
  41. * of each column will be evenly distributed based on the width of the overall field container. This is the default.</p></li>
  42. * <li><b>Number</b> : <p class="sub-desc">If you specific a number (e.g., 3) that number of columns will be
  43. * created and the contained controls will be automatically distributed based on the value of {@link #vertical}.</p></li>
  44. * <li><b>Array</b> : Object<p class="sub-desc">You can also specify an array of column widths, mixing integer
  45. * (fixed width) and float (percentage width) values as needed (e.g., [100, .25, .75]). Any integer values will
  46. * be rendered first, then any float values will be calculated as a percentage of the remaining space. Float
  47. * values do not have to add up to 1 (100%) although if you want the controls to take up the entire field
  48. * container you should do so.</p></li></ul>
  49. */
  50. columns : 'auto',
  51. /**
  52. * @cfg {Boolean} vertical True to distribute contained controls across columns, completely filling each column
  53. * top to bottom before starting on the next column. The number of controls in each column will be automatically
  54. * calculated to keep columns as even as possible. The default value is false, so that controls will be added
  55. * to columns one at a time, completely filling each row left to right before starting on the next row.
  56. */
  57. vertical : false,
  58. /**
  59. * @cfg {Boolean} allowBlank False to validate that at least one item in the group is checked (defaults to true).
  60. * If no items are selected at validation time, {@link @blankText} will be used as the error text.
  61. */
  62. allowBlank : true,
  63. /**
  64. * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails (defaults to "You must
  65. * select at least one item in this group")
  66. */
  67. blankText : "You must select at least one item in this group",
  68. // private
  69. defaultType : 'checkbox',
  70. // private
  71. groupCls : 'x-form-check-group',
  72. // private
  73. initComponent: function(){
  74. this.addEvents(
  75. /**
  76. * @event change
  77. * Fires when the state of a child checkbox changes.
  78. * @param {Ext.form.CheckboxGroup} this
  79. * @param {Array} checked An array containing the checked boxes.
  80. */
  81. 'change'
  82. );
  83. Ext.form.CheckboxGroup.superclass.initComponent.call(this);
  84. },
  85. // private
  86. onRender : function(ct, position){
  87. if(!this.el){
  88. var panelCfg = {
  89. cls: this.groupCls,
  90. layout: 'column',
  91. border: false,
  92. renderTo: ct
  93. };
  94. var colCfg = {
  95. defaultType: this.defaultType,
  96. layout: 'form',
  97. border: false,
  98. defaults: {
  99. hideLabel: true,
  100. anchor: '100%'
  101. }
  102. };
  103. if(this.items[0].items){
  104. // The container has standard ColumnLayout configs, so pass them in directly
  105. Ext.apply(panelCfg, {
  106. layoutConfig: {columns: this.items.length},
  107. defaults: this.defaults,
  108. items: this.items
  109. });
  110. for(var i=0, len=this.items.length; i<len; i++){
  111. Ext.applyIf(this.items[i], colCfg);
  112. }
  113. }else{
  114. // The container has field item configs, so we have to generate the column
  115. // panels first then move the items into the columns as needed.
  116. var numCols, cols = [];
  117. if(typeof this.columns == 'string'){ // 'auto' so create a col per item
  118. this.columns = this.items.length;
  119. }
  120. if(!Ext.isArray(this.columns)){
  121. var cs = [];
  122. for(var i=0; i<this.columns; i++){
  123. cs.push((100/this.columns)*.01); // distribute by even %
  124. }
  125. this.columns = cs;
  126. }
  127. numCols = this.columns.length;
  128. // Generate the column configs with the correct width setting
  129. for(var i=0; i<numCols; i++){
  130. var cc = Ext.apply({items:[]}, colCfg);
  131. cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
  132. if(this.defaults){
  133. cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
  134. }
  135. cols.push(cc);
  136. };
  137. // Distribute the original items into the columns
  138. if(this.vertical){
  139. var rows = Math.ceil(this.items.length / numCols), ri = 0;
  140. for(var i=0, len=this.items.length; i<len; i++){
  141. if(i>0 && i%rows==0){
  142. ri++;
  143. }
  144. if(this.items[i].fieldLabel){
  145. this.items[i].hideLabel = false;
  146. }
  147. cols[ri].items.push(this.items[i]);
  148. };
  149. }else{
  150. for(var i=0, len=this.items.length; i<len; i++){
  151. var ci = i % numCols;
  152. if(this.items[i].fieldLabel){
  153. this.items[i].hideLabel = false;
  154. }
  155. cols[ci].items.push(this.items[i]);
  156. };
  157. }
  158. Ext.apply(panelCfg, {
  159. layoutConfig: {columns: numCols},
  160. items: cols
  161. });
  162. }
  163. this.panel = new Ext.Panel(panelCfg);
  164. this.panel.ownerCt = this;
  165. this.el = this.panel.getEl();
  166. if(this.forId && this.itemCls){
  167. var l = this.el.up(this.itemCls).child('label', true);
  168. if(l){
  169. l.setAttribute('htmlFor', this.forId);
  170. }
  171. }
  172. var fields = this.panel.findBy(function(c){
  173. return c.isFormField;
  174. }, this);
  175. this.items = new Ext.util.MixedCollection();
  176. this.items.addAll(fields);
  177. }
  178. Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
  179. },
  180. afterRender : function(){
  181. Ext.form.CheckboxGroup.superclass.afterRender.call(this);
  182. if(this.values){
  183. this.setValue.apply(this, this.values);
  184. delete this.values;
  185. }
  186. this.eachItem(function(item){
  187. item.on('check', this.fireChecked, this);
  188. item.inGroup = true;
  189. });
  190. },
  191. // private
  192. doLayout: function(){
  193. //ugly method required to layout hidden items
  194. if(this.rendered){
  195. this.panel.forceLayout = this.ownerCt.forceLayout;
  196. this.panel.doLayout();
  197. }
  198. },
  199. // private
  200. fireChecked: function(){
  201. var arr = [];
  202. this.eachItem(function(item){
  203. if(item.checked){
  204. arr.push(item);
  205. }
  206. });
  207. this.fireEvent('change', this, arr);
  208. },
  209. // private
  210. validateValue : function(value){
  211. if(!this.allowBlank){
  212. var blank = true;
  213. this.eachItem(function(f){
  214. if(f.checked){
  215. return (blank = false);
  216. }
  217. });
  218. if(blank){
  219. this.markInvalid(this.blankText);
  220. return false;
  221. }
  222. }
  223. return true;
  224. },
  225. // private
  226. onDisable : function(){
  227. this.eachItem(function(item){
  228. item.disable();
  229. });
  230. },
  231. // private
  232. onEnable : function(){
  233. this.eachItem(function(item){
  234. item.enable();
  235. });
  236. },
  237. // private
  238. doLayout: function(){
  239. if(this.rendered){
  240. this.panel.forceLayout = this.ownerCt.forceLayout;
  241. this.panel.doLayout();
  242. }
  243. },
  244. // private
  245. onResize : function(w, h){
  246. this.panel.setSize(w, h);
  247. this.panel.doLayout();
  248. },
  249. // inherit docs from Field
  250. reset : function(){
  251. Ext.form.CheckboxGroup.superclass.reset.call(this);
  252. this.eachItem(function(c){
  253. if(c.reset){
  254. c.reset();
  255. }
  256. });
  257. },
  258. /**
  259. * {@link Ext.form.Checkbox#setValue Set the value(s)} of an item or items
  260. * in the group. Examples illustrating how this method may be called:
  261. * <pre><code>
  262. // call with name and value
  263. myCheckboxGroup.setValue('cb-col-1', true);
  264. // call with an array of boolean values
  265. myCheckboxGroup.setValue([true, false, false]);
  266. // call with an object literal specifying item:value pairs
  267. myCheckboxGroup.setValue({
  268. 'cb-col-2': false,
  269. 'cb-col-3': true
  270. });
  271. // use comma separated string to set items with name to true (checked)
  272. myCheckboxGroup.setValue('cb-col-1,cb-col-3');
  273. * </code></pre>
  274. * See {@link Ext.form.Checkbox#setValue} for additional information.
  275. * @param {Mixed} id The checkbox to check, or as described by example shown.
  276. * @param {Boolean} value (optional) The value to set the item.
  277. * @return {Ext.form.CheckboxGroup} this
  278. */
  279. setValue : function(id, value){
  280. if(this.rendered){
  281. if(arguments.length == 1){
  282. if(Ext.isArray(id)){
  283. //an array of boolean values
  284. Ext.each(id, function(val, idx){
  285. var item = this.items.itemAt(idx);
  286. if(item){
  287. item.setValue(val);
  288. }
  289. }, this);
  290. }else if(Ext.isObject(id)){
  291. //set of name/value pairs
  292. for(var i in id){
  293. var f = this.getBox(i);
  294. if(f){
  295. f.setValue(id[i]);
  296. }
  297. }
  298. }else{
  299. this.setValueForItem(id);
  300. }
  301. }else{
  302. var f = this.getBox(id);
  303. if(f){
  304. f.setValue(value);
  305. }
  306. }
  307. }else{
  308. this.values = arguments;
  309. }
  310. return this;
  311. },
  312. // private
  313. onDestroy: function(){
  314. Ext.destroy(this.panel);
  315. Ext.form.CheckboxGroup.superclass.onDestroy.call(this);
  316. },
  317. setValueForItem : function(val){
  318. val = String(val).split(',');
  319. this.eachItem(function(item){
  320. if(val.indexOf(item.inputValue)> -1){
  321. item.setValue(true);
  322. }
  323. });
  324. },
  325. // private
  326. getBox : function(id){
  327. var box = null;
  328. this.eachItem(function(f){
  329. if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
  330. box = f;
  331. return false;
  332. }
  333. });
  334. return box;
  335. },
  336. /**
  337. * Gets an array of the selected {@link Ext.form.Checkbox} in the group.
  338. * @return {Array} An array of the selected checkboxes.
  339. */
  340. getValue : function(){
  341. var out = [];
  342. this.eachItem(function(item){
  343. if(item.checked){
  344. out.push(item);
  345. }
  346. });
  347. return out;
  348. },
  349. // private
  350. eachItem: function(fn){
  351. if(this.items && this.items.each){
  352. this.items.each(fn, this);
  353. }
  354. },
  355. /**
  356. * @cfg {String} name
  357. * @hide
  358. */
  359. /**
  360. * @method initValue
  361. * @hide
  362. */
  363. initValue : Ext.emptyFn,
  364. /**
  365. * @method getValue
  366. * @hide
  367. */
  368. getValue : Ext.emptyFn,
  369. /**
  370. * @method getRawValue
  371. * @hide
  372. */
  373. getRawValue : Ext.emptyFn,
  374. /**
  375. * @method setRawValue
  376. * @hide
  377. */
  378. setRawValue : Ext.emptyFn
  379. });
  380. Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);