form_field.js 7.6 KB

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