Ext.ux.form.LovCombo.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // vim: ts=4:sw=4:nu:fdc=4:nospell
  2. /**
  3. * Ext.ux.form.LovCombo, List of Values Combo
  4. *
  5. * @author Ing.
  6. * @copyright (c) 2008, by Ing.
  7. * @date 16. April 2008
  8. * @version $Id: Ext.ux.form.LovCombo.js 291 2008-07-03 07:46:49Z jozo $
  9. *
  10. * @license Ext.ux.form.LovCombo.js is licensed under the terms of the Open
  11. * Source LGPL 3.0 license. Commercial use is permitted to the extent
  12. * that the code/component(s) do NOT become part of another Open Source
  13. * or Commercially licensed development library or toolkit without
  14. * explicit permission.
  15. *
  16. * License details: http://www.gnu.org/licenses/lgpl.html
  17. */
  18. /* global Ext */
  19. // add RegExp.escape if it has not been already added
  20. if ('function' !== typeof RegExp.escape) {
  21. RegExp.escape = function(s) {
  22. if ('string' !== typeof s) {
  23. return s;
  24. }
  25. // Note: if pasting from forum, precede ]/\ with backslash manually
  26. return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
  27. }; // eo function escape
  28. }
  29. // create namespace
  30. Ext.ns('Ext.ux.form');
  31. /**
  32. *
  33. * @class Ext.ux.form.LovCombo
  34. * @extends Ext.form.ComboBox
  35. */
  36. Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {
  37. // {{{
  38. // configuration options
  39. /**
  40. * @cfg {String} checkField name of field used to store checked
  41. * state. It is automatically added to existing fields. Change
  42. * it only if it collides with your normal field.
  43. */
  44. checkField : 'checked'
  45. /**
  46. * @cfg {String} separator separator to use between values and texts
  47. */
  48. ,
  49. separator : ','
  50. /**
  51. * @cfg {String/Array} tpl Template for items. Change it only if you
  52. * know what you are doing.
  53. */
  54. // }}}
  55. // {{{
  56. ,
  57. initComponent : function() {
  58. // template with checkbox
  59. if (!this.tpl) {
  60. this.tpl = '<tpl for=".">'
  61. + '<div class="x-combo-list-item">' + '<img src="'
  62. + Ext.BLANK_IMAGE_URL + '" '
  63. + 'class="ux-lovcombo-icon ux-lovcombo-icon-'
  64. + '{[values.' + this.checkField
  65. + '?"checked":"unchecked"' + ']}">'
  66. + '<div class="ux-lovcombo-item-text">{'
  67. + (this.displayField || 'text') + '}</div>'
  68. + '</div>' + '</tpl>';
  69. }
  70. // call parent
  71. Ext.ux.form.LovCombo.superclass.initComponent.apply(this,
  72. arguments);
  73. // install internal event handlers
  74. this.on({
  75. scope : this,
  76. beforequery : this.onBeforeQuery,
  77. blur : this.onRealBlur
  78. });
  79. // remove selection from input field
  80. this.onLoad = this.onLoad.createSequence(function() {
  81. if (this.el) {
  82. var v = this.el.dom.value;
  83. this.el.dom.value = '';
  84. this.el.dom.value = v;
  85. }
  86. });
  87. } // e/o function initComponent
  88. // }}}
  89. // {{{
  90. /**
  91. * Disables default tab key bahavior
  92. *
  93. * @private
  94. */
  95. ,
  96. initEvents : function() {
  97. Ext.ux.form.LovCombo.superclass.initEvents.apply(this,
  98. arguments);
  99. // disable default tab handling - does no good
  100. this.keyNav.tab = false;
  101. }, // eo function initEvents
  102. // }}}
  103. // {{{
  104. /**
  105. * clears value
  106. */
  107. onRender : function() {
  108. Ext.ux.form.LovCombo.superclass.onRender.apply(this, arguments);
  109. },
  110. clearValue : function() {
  111. this.value = '';
  112. this.setRawValue(this.value);
  113. this.store.clearFilter();
  114. this.store.each(function(r) {
  115. r.set(this.checkField, false);
  116. }, this);
  117. if (this.hiddenField) {
  118. this.hiddenField.value = '';
  119. }
  120. this.applyEmptyText();
  121. } // eo function clearValue
  122. // }}}
  123. // {{{
  124. /**
  125. * @return {String} separator (plus space) separated list of
  126. * selected displayFields
  127. * @private
  128. */
  129. ,
  130. getCheckedDisplay : function() {
  131. var re = new RegExp(this.separator, "g");
  132. return this.getCheckedValue(this.displayField).replace(re,
  133. this.separator + ' ');
  134. } // eo function getCheckedDisplay
  135. // }}}
  136. // {{{
  137. /**
  138. * @return {String} separator separated list of selected valueFields
  139. * @private
  140. */
  141. ,
  142. getCheckedValue : function(field) {
  143. field = field || this.valueField;
  144. var c = [];
  145. // store may be filtered so get all records
  146. var snapshot = this.store.snapshot || this.store.data;
  147. snapshot.each(function(r) {
  148. if (r.get(this.checkField)) {
  149. c.push(r.get(field));
  150. }
  151. }, this);
  152. return c.join(this.separator);
  153. } // eo function getCheckedValue
  154. // }}}
  155. // {{{
  156. /**
  157. * beforequery event handler - handles multiple selections
  158. *
  159. * @param {Object}
  160. * qe query event
  161. * @private
  162. */
  163. ,
  164. onBeforeQuery : function(qe) {
  165. qe.query = qe.query.replace(new RegExp(RegExp.escape(this
  166. .getCheckedDisplay())
  167. + '[ ' + this.separator + ']*'), '');
  168. } // eo function onBeforeQuery
  169. // }}}
  170. // {{{
  171. /**
  172. * blur event handler - runs only when real blur event is fired
  173. */
  174. ,
  175. onRealBlur : function() {
  176. this.list.hide();
  177. var rv = this.getRawValue();
  178. var rva = rv.split(new RegExp(RegExp.escape(this.separator)
  179. + ' *'));
  180. var va = [];
  181. var snapshot = this.store.snapshot || this.store.data;
  182. // iterate through raw values and records and check/uncheck
  183. // items
  184. Ext.each(rva, function(v) {
  185. snapshot.each(function(r) {
  186. if (v === r.get(this.displayField)) {
  187. va.push(r.get(this.valueField));
  188. }
  189. }, this);
  190. }, this);
  191. //this.setValue(va.join(this.separator));
  192. //this.store.clearFilter();
  193. }
  194. // ***********************************/
  195. // eo function onRealBlur
  196. // }}}
  197. // {{{
  198. /**
  199. * Combo's onSelect override
  200. *
  201. * @private
  202. * @param {Ext.data.Record}
  203. * record record that has been selected in the list
  204. * @param {Number}
  205. * index index of selected (clicked) record
  206. */
  207. ,
  208. onSelect : function(record, index) {
  209. if (this.fireEvent('beforeselect', this, record, index) !== false) {
  210. // toggle checked field
  211. record.set(this.checkField, !record.get(this.checkField));
  212. // display full list
  213. if (this.store.isFiltered()) {
  214. this.doQuery(this.allQuery);
  215. }
  216. // set (update) value and fire event
  217. this.setValue(this.getCheckedValue());
  218. this.fireEvent('select', this, record, index);
  219. }
  220. } // eo function onSelect
  221. // }}}
  222. // {{{
  223. /**
  224. * Sets the value of the LovCombo
  225. *
  226. * @param {Mixed}
  227. * v value
  228. */
  229. ,
  230. setValue : function(v) {
  231. if (v) {
  232. v = '' + v;
  233. if (this.valueField) {
  234. this.store.clearFilter();
  235. this.store.each(function(r) {
  236. var checked = !(!v
  237. .match( '(^|'
  238. + this.separator
  239. + ')'
  240. + RegExp
  241. .escape(r
  242. .get(this.valueField))
  243. + '('
  244. + this.separator
  245. + '|$)'));
  246. r.set(this.checkField, checked);
  247. }, this);
  248. this.value = this.getCheckedValue();
  249. this.setRawValue(this.getCheckedDisplay());
  250. if (this.hiddenField) {
  251. this.hiddenField.value = this.value;
  252. }
  253. } else {
  254. this.value = v;
  255. this.setRawValue(v);
  256. if (this.hiddenField) {
  257. this.hiddenField.value = v;
  258. }
  259. }
  260. if (this.el) {
  261. this.el.removeClass(this.emptyClass);
  262. }
  263. } else {
  264. this.clearValue();
  265. }
  266. } // eo function setValue
  267. // }}}
  268. // {{{
  269. /**
  270. * Selects all items
  271. */
  272. ,
  273. selectAll : function() {
  274. this.store.each(function(record) {
  275. // toggle checked field
  276. record.set(this.checkField, true);
  277. }, this);
  278. // display full list
  279. this.doQuery(this.allQuery);
  280. this.setValue(this.getCheckedValue());
  281. } // eo full selectAll
  282. // }}}
  283. // {{{
  284. /**
  285. * Deselects all items. Synonym for clearValue
  286. */
  287. ,
  288. deselectAll : function() {
  289. this.clearValue();
  290. }, // eo full deselectAll
  291. // }}}
  292. beforeBlur : Ext.emptyFn
  293. }); // eo extend
  294. // register xtype
  295. Ext.reg('lovcombo', Ext.ux.form.LovCombo);
  296. // eof