form_field.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. },
  17. // the constructor
  18. _create: function()
  19. {
  20. var me = this;
  21. this.element
  22. .addClass('form_field');
  23. this.element
  24. .bind('set_validators', function(event, data){
  25. me.options.validators = data;
  26. });
  27. this.element
  28. .bind('validate get_current_value', function(event, data){
  29. var callback = me.options[event.type+'_callback'];
  30. if(typeof callback === 'string')
  31. {
  32. return me[callback]();
  33. }
  34. else if(typeof callback === 'function')
  35. {
  36. return callback(me);
  37. }
  38. else
  39. {
  40. console.log('Form field : callback type must be a function or a existing function name of the widget');
  41. return false;
  42. }
  43. });
  44. },
  45. // called when created, and later when changing options
  46. _refresh: function()
  47. {
  48. },
  49. // events bound via _bind are removed automatically
  50. // revert other modifications here
  51. _destroy: function()
  52. {
  53. this.element
  54. .removeClass('form_field');
  55. },
  56. // _setOptions is called with a hash of all options that are changing
  57. // always refresh when changing options
  58. _setOptions: function()
  59. {
  60. this._superApply(arguments);
  61. },
  62. // _setOption is called for each individual option that is changing
  63. _setOption: function( key, value )
  64. {
  65. this._super( key, value );
  66. },
  67. getCurrentValue: function()
  68. {
  69. var value = {};
  70. this.element.find(':input').each(function(index, elem){
  71. if($(elem).is(':hidden') || $(elem).is(':text') || $(elem).is('textarea'))
  72. {
  73. value[$(elem).attr('name')] = $(elem).val();
  74. }
  75. else if($(elem).is('select'))
  76. {
  77. value[$(elem).attr('name')] = [];
  78. $(elem).find('option:selected').each(function(){
  79. value[$(elem).attr('name')].push($(this).val());
  80. });
  81. }
  82. else if($(elem).is(':checkbox') || $(elem).is(':radio'))
  83. {
  84. if(value[$(elem).attr('name')] === undefined)
  85. {
  86. value[$(elem).attr('name')] = [];
  87. }
  88. if($(elem).is(':checked'))
  89. {
  90. value[$(elem).attr('name')].push($(elem).val());
  91. }
  92. }
  93. else
  94. {
  95. console.log('Form field : Input type not handle yet.');
  96. }
  97. });
  98. return value;
  99. },
  100. validate: function()
  101. {
  102. var oResult = { is_valid: true, error_messages: [] };
  103. // Doing data validation
  104. if(this.options.validators !== null)
  105. {
  106. var bMandatory = (this.options.validators.mandatory !== undefined);
  107. // Extracting value for the field
  108. var oValue = this.getCurrentValue();
  109. var aValueKeys = Object.keys(oValue);
  110. // 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...
  111. // ... But this should never happen.
  112. if( (aValueKeys.length === 0) && bMandatory )
  113. {
  114. oResult.is_valid = false;
  115. oResult.error_messages.push(this.options.validators.mandatory.message);
  116. }
  117. // ... Otherwise, we check every validators
  118. else if(aValueKeys.length > 0)
  119. {
  120. var value = oValue[aValueKeys[0]];
  121. for(var sValidatorType in this.options.validators)
  122. {
  123. var oValidator = this.options.validators[sValidatorType];
  124. if(sValidatorType === 'mandatory')
  125. {
  126. // Works for string, array, object
  127. if($.isEmptyObject(value))
  128. {
  129. oResult.is_valid = false;
  130. oResult.error_messages.push(oValidator.message);
  131. }
  132. // ... In case of none empty array, we have to check is the value is not null
  133. else if($.isArray(value))
  134. {
  135. for(var i in value)
  136. {
  137. if(typeof value[i] === 'string')
  138. {
  139. if($.isEmptyObject(value[i]))
  140. {
  141. oResult.is_valid = false;
  142. oResult.error_messages.push(oValidator.message);
  143. }
  144. }
  145. else
  146. {
  147. console.log('Form field: mandatory validation not supported yet for the type "' + (typeof value[i]) +'"');
  148. }
  149. }
  150. }
  151. }
  152. else
  153. {
  154. var oRegExp = new RegExp(oValidator.reg_exp, "g");
  155. if(typeof value === 'string')
  156. {
  157. if(!oRegExp.test(value))
  158. {
  159. oResult.is_valid = false;
  160. oResult.error_messages.push(oValidator.message);
  161. }
  162. }
  163. else if($.isArray(value))
  164. {
  165. for(var i in value)
  166. {
  167. if(value[i] === 'string' && !oRegExp.test(value))
  168. {
  169. oResult.is_valid = false;
  170. oResult.error_messages.push(oValidator.message);
  171. }
  172. }
  173. }
  174. else
  175. {
  176. console.log('Form field: validation not supported yet for the type "' + (typeof value) +'"');
  177. }
  178. }
  179. }
  180. }
  181. }
  182. this.options.on_validation_callback();
  183. return oResult;
  184. },
  185. showOptions: function()
  186. {
  187. return this.options;
  188. }
  189. });
  190. });