form_field.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //iTop Form field
  2. ;
  3. $(function()
  4. {
  5. // the widget definition, where 'itop' is the namespace,
  6. // 'form_field' the widget name
  7. $.widget( 'itop.form_field',
  8. {
  9. // default options
  10. options:
  11. {
  12. validators: null,
  13. validate_callback: 'validate', // When using an anonymous function, use the 'me' parameter to acces the current widget : function(me){ return me.validate(); },
  14. on_validation_callback: function(data){ },
  15. get_current_value_callback: 'getCurrentValue',
  16. set_current_value_callback: function(me, oEvent, oData){ console.log('Form field: set_current_value_callback must be overloaded, this is the default callback.'); }
  17. },
  18. // the constructor
  19. _create: function()
  20. {
  21. var me = this;
  22. this.element
  23. .addClass('form_field');
  24. this.element
  25. .bind('set_validators', function(oEvent, oData){
  26. oEvent.stopPropagation();
  27. me.options.validators = oData;
  28. });
  29. this.element
  30. .bind('validate get_current_value set_current_value', function(oEvent, oData){
  31. oEvent.stopPropagation();
  32. var callback = me.options[oEvent.type+'_callback'];
  33. if(typeof callback === 'string')
  34. {
  35. return me[callback](oEvent, oData);
  36. }
  37. else if(typeof callback === 'function')
  38. {
  39. return callback(me, oEvent, oData);
  40. }
  41. else
  42. {
  43. console.log('Form field : callback type must be a function or a existing function name of the widget');
  44. return false;
  45. }
  46. });
  47. },
  48. // called when created, and later when changing options
  49. _refresh: function()
  50. {
  51. },
  52. // events bound via _bind are removed automatically
  53. // revert other modifications here
  54. _destroy: function()
  55. {
  56. this.element
  57. .removeClass('form_field');
  58. },
  59. // _setOptions is called with a hash of all options that are changing
  60. // always refresh when changing options
  61. _setOptions: function()
  62. {
  63. this._superApply(arguments);
  64. },
  65. // _setOption is called for each individual option that is changing
  66. _setOption: function( key, value )
  67. {
  68. this._super( key, value );
  69. },
  70. getCurrentValue: function()
  71. {
  72. var value = null;
  73. this.element.find(':input').each(function(iIndex, oElem){
  74. if($(oElem).is(':hidden') || $(oElem).is(':text') || $(oElem).is(':password') || $(oElem).is('textarea'))
  75. {
  76. value = $(oElem).val();
  77. }
  78. else if($(oElem).is('select'))
  79. {
  80. if($(oElem).is('select[multiple]'))
  81. {
  82. value = [];
  83. $(oElem).find('option:selected').each(function(){
  84. value.push($(this).val());
  85. });
  86. }
  87. else
  88. {
  89. value = $(oElem).val();
  90. }
  91. }
  92. else if($(oElem).is(':checkbox') || $(oElem).is(':radio'))
  93. {
  94. if(value === null)
  95. {
  96. value = [];
  97. }
  98. if($(oElem).is(':checked'))
  99. {
  100. value.push($(oElem).val());
  101. }
  102. }
  103. else
  104. {
  105. console.log('Form field : Input type not handle yet.');
  106. }
  107. });
  108. return value;
  109. },
  110. validate: function(oEvent, oData)
  111. {
  112. var oResult = { is_valid: true, error_messages: [] };
  113. // Doing data validation
  114. if(this.options.validators !== null)
  115. {
  116. // Extracting value for the field
  117. var oValue = this.element.triggerHandler('get_current_value');
  118. if(oValue === null)
  119. {
  120. console.log('Form field : Warning, there was no value for "'+this.element.attr('data-field-id')+'"');
  121. return oResult;
  122. }
  123. var bMandatory = (this.options.validators.mandatory !== undefined);
  124. var bEmpty = ($.isArray(oValue)) ? (oValue.length === 0) : (oValue === '' || oValue === undefined);
  125. var value = oValue;
  126. // This is just a safety check in case a field doesn't always return an object when no value assigned, so we have to check the mandatory validator here...
  127. // ... But this should never happen.
  128. //if( (aValueKeys.length === 0) && bMandatory )
  129. if( bEmpty && bMandatory )
  130. {
  131. oResult.is_valid = false;
  132. oResult.error_messages.push(this.options.validators.mandatory.message);
  133. }
  134. // ... Field empty but not mandatory, no need to validate
  135. else if( bEmpty && !bMandatory )
  136. {
  137. // It's okay, no need to validate
  138. }
  139. // ... Otherwise, we check every validators
  140. else
  141. {
  142. for(var sValidatorType in this.options.validators)
  143. {
  144. var oValidator = this.options.validators[sValidatorType];
  145. if(sValidatorType === 'mandatory')
  146. {
  147. // Works for string, array, object
  148. if($.isEmptyObject(value))
  149. {
  150. oResult.is_valid = false;
  151. oResult.error_messages.push(oValidator.message);
  152. }
  153. // ... In case of non empty array, we have to check if the value is not null
  154. else if($.isArray(value))
  155. {
  156. for(var i in value)
  157. {
  158. if(typeof value[i] === 'string')
  159. {
  160. if($.isEmptyObject(value[i]))
  161. {
  162. oResult.is_valid = false;
  163. oResult.error_messages.push(oValidator.message);
  164. }
  165. }
  166. else
  167. {
  168. console.log('Form field: mandatory validation not supported yet for the type "' + (typeof value[i]) +'"');
  169. }
  170. }
  171. }
  172. }
  173. else
  174. {
  175. var oRegExp = new RegExp(oValidator.reg_exp, "g");
  176. if(typeof value === 'string')
  177. {
  178. if(!oRegExp.test(value))
  179. {
  180. oResult.is_valid = false;
  181. oResult.error_messages.push(oValidator.message);
  182. }
  183. }
  184. else if($.isArray(value))
  185. {
  186. for(var i in value)
  187. {
  188. if(value[i] === 'string' && !oRegExp.test(value))
  189. {
  190. oResult.is_valid = false;
  191. oResult.error_messages.push(oValidator.message);
  192. }
  193. }
  194. }
  195. else
  196. {
  197. console.log('Form field: validation not supported yet for the type "' + (typeof value) +'"');
  198. }
  199. }
  200. }
  201. }
  202. }
  203. this.options.on_validation_callback(this, oResult);
  204. return oResult;
  205. },
  206. // Debug helper
  207. showOptions: function()
  208. {
  209. return this.options;
  210. }
  211. });
  212. });