epic-s6ts
[kivitendo-erp.git] / js / kivi.Validator.js
1 namespace("kivi.Validator", function(ns) {
2   "use strict";
3
4   // Performs various validation steps on the descendants of
5   // 'selector'. Elements that should be validated must have an
6   // attribute named "data-validate" which is set to a space-separated
7   // list of tests to perform. Additionally, the attribute
8   // "data-title" can be set to a human-readable name of the field
9   // that can be shown in front of an error message.
10   //
11   // Supported validation tests are:
12   // - "required": the field must be set (its .val() must not be empty)
13   // - "number": the field must be in number format (its .val() must in the right format)
14   // - "date": the field must be in date format (its .val() must in the right format)
15   // - "time": the field must be in time format (its .val() must in the right format)
16   //
17   // The validation will abort and return "false" as soon as
18   // validation routine fails.
19   //
20   // The function returns "true" if all validations succeed for all
21   // elements.
22   ns.validate_all = function(selector) {
23     selector = selector || '#form';
24     var to_check = $(selector + ' [data-validate]').toArray();
25
26     for (var to_check_idx in to_check)
27       if (!ns.validate($(to_check[to_check_idx]))) {
28         $(to_check[to_check_idx]).focus();
29         return false;
30       }
31
32     return true;
33   };
34
35   ns.validate = function($e) {
36     var $e_annotate;
37     if ($e.data('ckeditorInstance')) {
38       $e_annotate = $($e.data('ckeditorInstance').editable().$);
39       if ($e.data('title'))
40         $e_annotate.data('title', $e.data('title'));
41     }
42     var tests = $e.data('validate').split(/ +/);
43
44     for (var test_idx in tests) {
45       var test = tests[test_idx];
46       if (!ns.checks[test])
47         continue;
48
49       if (ns.checks[test]) {
50         if (!ns.checks[test]($e, $e_annotate))
51           return false;
52       } else {
53         var error = "kivi.validate_form: unknown test '" + test + "' for element ID '" + $e.prop('id') + "'";
54         console.error(error);
55         alert(error);
56         return false;
57       }
58     }
59
60     return true;
61   }
62
63   ns.checks = {
64     required: function($e, $e_annotate) {
65       $e_annotate = $e_annotate || $e;
66
67       if ($e.val() === '') {
68         ns.annotate($e_annotate, kivi.t8("This field must not be empty."));
69         return false;
70       } else {
71         ns.annotate($e_annotate);
72         return true;
73       }
74     },
75     number: function($e, $e_annotate) {
76       $e_annotate = $e_annotate || $e;
77
78       var number_string = $e.val();
79
80       var parsed_number = kivi.parse_amount(number_string);
81
82       if (parsed_number === null) {
83         $e.val('');
84         ns.annotate($e_annotate);
85         return true;
86       } else
87       if (parsed_number === undefined) {
88         ns.annotate($e_annotate, kivi.t8('Wrong number format (#1)', [ kivi.myconfig.numberformat ]));
89         return false;
90       } else
91       {
92         var formatted_number = kivi.format_amount(parsed_number);
93         if (formatted_number != number_string)
94           $e.val(formatted_number);
95         ns.annotate($e_annotate);
96         return true;
97       }
98     },
99     date: function($e, $e_annotate) {
100       $e_annotate = $e_annotate || $e;
101
102       var date_string = $e.val();
103
104       var parsed_date = kivi.parse_date(date_string);
105
106       if (parsed_date === null) {
107         $e.val('');
108         ns.annotate($e_annotate);
109         return true;
110       } else
111       if (parsed_date === undefined) {
112         ns.annotate($e_annotate, kivi.t8('Wrong date format (#1)', [ kivi.myconfig.dateformat ]));
113         return false;
114       } else
115       {
116         var formatted_date = kivi.format_date(parsed_date);
117         if (formatted_date != date_string)
118           $e.val(formatted_date);
119         ns.annotate($e_annotate);
120         return true;
121       }
122     },
123     time: function($e, $e_annotate) {
124       $e_annotate = $e_annotate || $e;
125
126       var time_string = $e.val();
127
128       var parsed_time = kivi.parse_time(time_string);
129       if (parsed_time === null) {
130         $e.val('');
131         ns.annotate($e_annotate);
132         return true;
133       } else
134       if (parsed_time === undefined) {
135         ns.annotate($e_annotate, kivi.t8('Wrong time format (#1)', [ kivi.myconfig.timeformat ]));
136         return false;
137       } else
138       {
139         var formatted_time = kivi.format_time(parsed_time);
140         if (formatted_time != time_string)
141           $e.val(formatted_time);
142         ns.annotate($e_annotate);
143         return true;
144       }
145     },
146     trimmed_whitespaces: function($e, $e_annotate) {
147       $e_annotate = $e_annotate || $e;
148
149       var string = $e.val();
150
151       if ($e.hasClass('tooltipstered'))
152         $e.tooltipster('destroy');
153
154       if (string.match(/^\s|\s$/)) {
155         $e.val(string.trim());
156
157         $e.tooltipster({
158           content: kivi.t8("Leading and trailing whitespaces have been removed."),
159           contentAsHTML: true,
160           theme: 'tooltipster-light',
161         });
162         $e.tooltipster('show');
163       }
164       return true;
165     }
166   };
167
168   ns.annotate = function($e, error) {
169     if (error) {
170       $e.addClass('kivi-validator-invalid');
171       if ($e.hasClass('tooltipstered'))
172         $e.tooltipster('destroy');
173
174       if ($e.data('title'))
175         error = $e.data('title') + ': ' + error;
176
177       $e.tooltipster({
178         content: error,
179         theme: 'tooltipster-light',
180       });
181       $e.tooltipster('show');
182     } else {
183       $e.removeClass('kivi-validator-invalid');
184       if ($e.hasClass('tooltipstered'))
185         $e.tooltipster('destroy');
186     }
187   };
188
189   ns.reinit_widgets = function() {
190     kivi.run_once_for('[data-validate]', 'data-validate', function(elt) {
191       $(elt).change(function(event){ ns.validate($(elt), event) });
192     });
193   }
194
195   ns.init = ns.reinit_widgets;
196
197   $(ns.init);
198 });