field.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. // ---------------------------------------------------------------------------------
  2. // Field object
  3. // ---------------------------------------------------------------------------------
  4. Field = function(field) {
  5. check(field, FIELD_PAT);
  6. _.defaults(this, field);
  7. this.validating = new ReactiveVar(false);
  8. this.status = new ReactiveVar(null);
  9. };
  10. if (Meteor.isClient) {
  11. Field.prototype.clearStatus = function() {
  12. return this.status.set(null);
  13. };
  14. }
  15. if (Meteor.isServer) {
  16. Field.prototype.clearStatus = function() {
  17. // Nothing to do server-side
  18. return;
  19. };
  20. }
  21. Field.prototype.fixValue = function(value) {
  22. if (this.type === "checkbox") {
  23. return !!value;
  24. }
  25. if (this.type === "select") {
  26. // TODO: something working...
  27. return value;
  28. }
  29. if (this.type === "radio") {
  30. // TODO: something working...
  31. return value;
  32. }
  33. // Possibly applies required transformations to the input value
  34. if (this.trim) {
  35. value = value.trim();
  36. }
  37. if (this.lowercase) {
  38. value = value.toLowerCase();
  39. }
  40. if (this.uppercase) {
  41. value = value.toUpperCase();
  42. }
  43. if (!!this.transform) {
  44. value = this.transform(value);
  45. }
  46. return value;
  47. };
  48. if (Meteor.isClient) {
  49. Field.prototype.getDisplayName = function(state) {
  50. var displayName = this.displayName;
  51. if (_.isFunction(displayName)) {
  52. displayName = displayName();
  53. } else if (_.isObject(displayName)) {
  54. displayName = displayName[state] || displayName["default"];
  55. }
  56. if (!displayName) {
  57. displayName = capitalize(this._id);
  58. }
  59. return displayName;
  60. };
  61. }
  62. if (Meteor.isClient) {
  63. Field.prototype.getPlaceholder = function(state) {
  64. var placeholder = this.placeholder;
  65. if (_.isObject(placeholder)) {
  66. placeholder = placeholder[state] || placeholder["default"];
  67. }
  68. if (!placeholder) {
  69. placeholder = capitalize(this._id);
  70. }
  71. return placeholder;
  72. };
  73. }
  74. Field.prototype.getStatus = function() {
  75. return this.status.get();
  76. };
  77. if (Meteor.isClient) {
  78. Field.prototype.getValue = function(templateInstance) {
  79. if (this.type === "checkbox") {
  80. return !!(templateInstance.$("#at-field-" + this._id + ":checked").val());
  81. }
  82. if (this.type === "radio") {
  83. return templateInstance.$("[name=at-field-"+ this._id + "]:checked").val();
  84. }
  85. return templateInstance.$("#at-field-" + this._id).val();
  86. };
  87. }
  88. if (Meteor.isClient) {
  89. Field.prototype.hasError = function() {
  90. return this.negativeValidation && this.status.get();
  91. };
  92. }
  93. if (Meteor.isClient) {
  94. Field.prototype.hasIcon = function() {
  95. if (this.showValidating && this.isValidating()) {
  96. return true;
  97. }
  98. if (this.negativeFeedback && this.hasError()) {
  99. return true;
  100. }
  101. if (this.positiveFeedback && this.hasSuccess()) {
  102. return true;
  103. }
  104. };
  105. }
  106. if (Meteor.isClient) {
  107. Field.prototype.hasSuccess = function() {
  108. return this.positiveValidation && this.status.get() === false;
  109. };
  110. }
  111. if (Meteor.isClient)
  112. Field.prototype.iconClass = function() {
  113. if (this.isValidating()) {
  114. return AccountsTemplates.texts.inputIcons["isValidating"];
  115. }
  116. if (this.hasError()) {
  117. return AccountsTemplates.texts.inputIcons["hasError"];
  118. }
  119. if (this.hasSuccess()) {
  120. return AccountsTemplates.texts.inputIcons["hasSuccess"];
  121. }
  122. };
  123. if (Meteor.isClient) {
  124. Field.prototype.isValidating = function() {
  125. return this.validating.get();
  126. };
  127. }
  128. if (Meteor.isClient) {
  129. Field.prototype.setError = function(err) {
  130. check(err, Match.OneOf(String, undefined, Boolean));
  131. if (err === false) {
  132. return this.status.set(false);
  133. }
  134. return this.status.set(err || true);
  135. };
  136. }
  137. if (Meteor.isServer) {
  138. Field.prototype.setError = function(err) {
  139. // Nothing to do server-side
  140. return;
  141. };
  142. }
  143. if (Meteor.isClient) {
  144. Field.prototype.setSuccess = function() {
  145. return this.status.set(false);
  146. };
  147. }
  148. if (Meteor.isServer) {
  149. Field.prototype.setSuccess = function() {
  150. // Nothing to do server-side
  151. return;
  152. };
  153. }
  154. if (Meteor.isClient) {
  155. Field.prototype.setValidating = function(state) {
  156. check(state, Boolean);
  157. return this.validating.set(state);
  158. };
  159. }
  160. if (Meteor.isServer) {
  161. Field.prototype.setValidating = function(state) {
  162. // Nothing to do server-side
  163. return;
  164. };
  165. }
  166. if (Meteor.isClient) {
  167. Field.prototype.setValue = function(templateInstance, value) {
  168. if (this.type === "checkbox") {
  169. templateInstance.$("#at-field-" + this._id).prop('checked', true);
  170. return;
  171. }
  172. if (this.type === "radio") {
  173. templateInstance.$("[name=at-field-"+ this._id + "]").prop('checked', true);
  174. return;
  175. }
  176. templateInstance.$("#at-field-" + this._id).val(value);
  177. };
  178. }
  179. Field.prototype.validate = function(value, strict) {
  180. check(value, Match.OneOf(undefined, String, Boolean));
  181. this.setValidating(true);
  182. this.clearStatus();
  183. if (_.isUndefined(value) || value === '') {
  184. if (!!strict) {
  185. if (this.required) {
  186. this.setError(AccountsTemplates.texts.requiredField);
  187. this.setValidating(false);
  188. return AccountsTemplates.texts.requiredField;
  189. } else {
  190. this.setSuccess();
  191. this.setValidating(false);
  192. return false;
  193. }
  194. } else {
  195. this.clearStatus();
  196. this.setValidating(false);
  197. return null;
  198. }
  199. }
  200. var valueLength = value.length;
  201. var minLength = this.minLength;
  202. if (minLength && valueLength < minLength) {
  203. this.setError(AccountsTemplates.texts.minRequiredLength + ": " + minLength);
  204. this.setValidating(false);
  205. return AccountsTemplates.texts.minRequiredLength + ": " + minLength;
  206. }
  207. var maxLength = this.maxLength;
  208. if (maxLength && valueLength > maxLength) {
  209. this.setError(AccountsTemplates.texts.maxAllowedLength + ": " + maxLength);
  210. this.setValidating(false);
  211. return AccountsTemplates.texts.maxAllowedLength + ": " + maxLength;
  212. }
  213. if (this.re && valueLength && !value.match(this.re)) {
  214. this.setError(this.errStr);
  215. this.setValidating(false);
  216. return this.errStr;
  217. }
  218. if (this.func) {
  219. var result = this.func(value);
  220. var err = result === true ? this.errStr || true : result;
  221. if (_.isUndefined(result)) {
  222. return err;
  223. }
  224. this.status.set(err);
  225. this.setValidating(false);
  226. return err;
  227. }
  228. this.setSuccess();
  229. this.setValidating(false);
  230. return false;
  231. };