Passed
Branch main (7cbcd8)
by Stefan
02:57
created

script/FormDataValidator.js   D

Complexity

Total Complexity 59
Complexity/F 4.54

Size

Lines of Code 303
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 59
eloc 178
mnd 46
bc 46
fnc 13
dl 0
loc 303
rs 4.08
bpm 3.5384
cpm 4.5384
noi 22
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like script/FormDataValidator.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
function FormDataValidator(aMand, aDate, aTime, aInt, aCur)
2
{
3
    this.aMand = aMand;
4
    this.aDate = aDate;
5
    this.aTime = aTime;
6
    this.aInt = aInt;
7
    this.aCur = aCur;
8
    
9
    this.focusItem = null;
10
    this.focusTabIndex = null;
11
    this.errors = 0;
12
}
13
    
14
FormDataValidator.prototype.validate = function()
15
{
16
    var item;
0 ignored issues
show
Unused Code introduced by
The variable item seems to be never used. Consider removing it.
Loading history...
17
    var i;
18
    
19
    // check mandatory fields
20
    if (this.aMand != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.aMand to null using the != operator is not safe. Consider using !== instead.
Loading history...
21
        for (i = 0; i < this.aMand.length; i++) {
22
            this.checkMandatory(document.getElementById(this.aMand[i]));
23
        }
24
    }
25
    // validate date input
26
    if (this.aDate != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.aDate to null using the != operator is not safe. Consider using !== instead.
Loading history...
27
        for (i = 0; i < this.aDate.length; i++) {
28
            this.checkDate(document.getElementById(this.aDate[i]));
29
        }
30
    }
31
    // validate time input
32
    if (this.aTime != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.aTime to null using the != operator is not safe. Consider using !== instead.
Loading history...
33
        for (i = 0; i < this.aTime.length; i++) {
34
            this.checkTime(document.getElementById(this.aTime[i]));
35
        }
36
    }
37
    // validate integer input
38
    if (this.aInt != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.aInt to null using the != operator is not safe. Consider using !== instead.
Loading history...
39
        for (i = 0; i < this.aInt.length; i++) {
40
            this.checkInteger(document.getElementById(this.aInt[i]));
41
        }
42
    }
43
    // validate currency/float input
44
    if (this.aCur != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.aCur to null using the != operator is not safe. Consider using !== instead.
Loading history...
45
        for (i = 0; i < this.aCur.length; i++) {
46
            this.checkCurrency(document.getElementById(this.aCur[i]));
47
        }
48
    }
49
    
50
    // if errors found, dispplay message and set focus to last input
51
    if (this.errors > 0) {
52
        var strMsg;
53
        // TODO: language
54
        if (this.errors == 1) {
0 ignored issues
show
Best Practice introduced by
Comparing this.errors to 1 using the == operator is not safe. Consider using === instead.
Loading history...
55
            strMsg = unescape("Das rot gekennzeichnete Feld wurde nicht korrekt ausgef%FCllt\n\n");
56
        } else {
57
            strMsg = unescape("Die rot gekennzeichneten Felder wurden nicht korrekt ausgef%FCllt\n\n");
58
        }
59
        strMsg += unescape("Korrigieren oder vervollst%E4ndigen Sie bitte Ihre Angaben.");
60
        alert( strMsg );
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
61
        if (this.focusItem != null) {
0 ignored issues
show
Best Practice introduced by
Comparing this.focusItem to null using the != operator is not safe. Consider using !== instead.
Loading history...
62
            this.focusItem.focus();
63
        }
64
        return false;
65
    }
66
    return true;
67
}
68
    
69
FormDataValidator.prototype.checkMandatory = function(item)
70
{
71
    if (item != null) {
0 ignored issues
show
Best Practice introduced by
Comparing item to null using the != operator is not safe. Consider using !== instead.
Loading history...
72
        this.setError((item.value == '' || item.value == 'null'), item);
73
    }
74
}
75
76
FormDataValidator.prototype.checkDate = function(item)
77
{
78
    if (item != null && item.value != '') {
0 ignored issues
show
Best Practice introduced by
Comparing item to null using the != operator is not safe. Consider using !== instead.
Loading history...
79
        var date = this.isValidDate(item.value);
80
        if (date !== false) {
81
            item.value = date;
82
            this.setError(false, item);
83
        } else {
84
            this.setError(true, item);
85
        }
86
    }
87
}
88
89
FormDataValidator.prototype.checkTime = function(item)
90
{
91
    if (item != null && item.value != '') {
0 ignored issues
show
Best Practice introduced by
Comparing item to null using the != operator is not safe. Consider using !== instead.
Loading history...
92
        var time = this.isValidTime(item.value); 
93
        if (time !== false) {
94
            item.value = time;
95
            this.setError(false, item);
96
        } else {
97
            this.setError(true, item);
98
        }
99
    }
100
}
101
102
FormDataValidator.prototype.checkInteger = function(item)
103
{
104
    if (item != null) {
0 ignored issues
show
Best Practice introduced by
Comparing item to null using the != operator is not safe. Consider using !== instead.
Loading history...
105
        var integer = this.isValidInteger(item.value);
106
        if (integer !== false) {
107
            item.value = integer;
108
            this.setError(false, item);
109
        } else {
110
            this.setError(true, item);
111
        }
112
    }
113
}
114
115
FormDataValidator.prototype.checkCurrency = function(item)
116
{
117
    if (item != null) {
0 ignored issues
show
Best Practice introduced by
Comparing item to null using the != operator is not safe. Consider using !== instead.
Loading history...
118
        var currency = this.isValidCurrency(item.value);
119
        if (currency !== false) {
120
            item.value = currency;
121
            this.setError(false, item);
122
        } else {
123
            this.setError(true, item);
124
        }
125
    }
126
}
127
128
FormDataValidator.prototype.setError = function(set, item)
129
{
130
    if (set) {
131
        item.className = item.className.replace( /Mand/, 'MError' );
132
        item.className = item.className.replace( /OK/, 'Error' );
133
        this.setFocusItem(item);
134
        this.errors++;
135
    } else {
136
        item.className = item.className.replace( /MError/, 'Mand' );
137
        item.className = item.className.replace( /Error/, 'OK' );
138
    }
139
}
140
141
FormDataValidator.prototype.setFocusItem = function(item)
142
{
143
    if (!this.focusTabIndex || this.focusTabIndex > item.tabIndex) {
144
        this.focusTabIndex = item.tabIndex;
145
        this.focusItem = item;
146
    }
147
}
148
149
FormDataValidator.prototype.isValidDate = function(strDate)
150
{
151
    // remove all whitespace
152
    strDate = strDate.toString().trim();
153
154
    // ',' is replaced with '.' (fast input through num-pad...)
155
    strDate = strDate.replace(/,/g, ".");
156
    // we only accept sequence D.M.Y
157
    var aSplit = strDate.split(".");
158
159
    // First there must be three parts
160
    if (aSplit.length != 3) {
161
        return false;
162
    }
163
    
164
    // Caution: remove leading '0' otherwise parseInt treats values as octal and return '0' in case of '08' and '09' !!!!
165
    var iD = parseInt(aSplit[0].replace(/^0+/,""));
166
    var iM = parseInt(aSplit[1].replace(/^0+/,""));
167
    var iY = parseInt(aSplit[2].replace(/^0+/,""));
168
    if (iD == NaN || iM == NaN || iY == NaN) {
0 ignored issues
show
Bug introduced by
Comparing a value to NaN with == is always true. Did you mean to use isNaN(iM) ?
Loading history...
Bug introduced by
Comparing a value to NaN with == is always true. Did you mean to use isNaN(iY) ?
Loading history...
Bug introduced by
Comparing a value to NaN with == is always true. Did you mean to use isNaN(iD) ?
Loading history...
169
        return false;
170
    }
171
    // values < 25 are 21'st century and 25...99 20'st Century!
172
    if (iY < 100) {
173
        if (iY < 33) {
174
            iY += 2000;
175
        } else {
176
            iY += 1900;
177
        }
178
    }
179
    if (iY < 1900) {
180
        return false;
181
    }
182
    iM--;
183
    // initializte Date-Object
184
    var date = new Date(iY, iM, iD);
185
    
186
    // and compare all parts
187
    var iD2 = date.getDate();
188
    var iM2 = date.getMonth();
189
    var iY2 = date.getFullYear();
190
    if (iD != iD2 || iM != iM2 || iY != iY2) {
191
        // alert( 'In: ' + iD + '.' + iM + '.' + iY + '\nOut: ' + iD2 + '.' + iM2 + '.' + iY2 );
192
        return false;
193
    }
194
    var strDate = '';
195
    if (iD < 10) {
196
        strDate = '0';
197
    }
198
    strDate += iD + '.';
199
    if (iM < 10) {
200
        strDate += '0';
201
    }
202
    strDate += iM + '.' + iY;
203
    return strDate;
204
}
205
206
FormDataValidator.prototype.isValidTime = function(strTime)
207
{
208
    // remove all whitespace
209
    strTime = strTime.toString().trim();
210
211
    // we only accept ':' as Delimiter and expect sequence H:i[:s]
212
    var aSplit = strTime.split(":");
213
214
    var iH = iM = iS = 0;
0 ignored issues
show
Bug introduced by
The variable iS seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.iS.
Loading history...
Bug introduced by
The variable iM seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.iM.
Loading history...
215
    switch (aSplit.length) {
216
        case 1: // no separator - interpret as minutes
217
            if (aSplit[0] != '0' && aSplit[0] != '00') {
218
                iM = parseInt(aSplit[0].replace(/^0+/,""));
219
            }
220
            break;
221
        case 2: // hour:minutes specified
222
        case 3: // hour:minutes:seconds
223
            // only handle h:m
224
            if (aSplit[0] != '0' && aSplit[0] != '00') {
225
                iH = parseInt(aSplit[0].replace(/^0+/,""));
226
            }
227
            if (aSplit[1] != '0' && aSplit[1] != '00') {
228
                iM = parseInt(aSplit[1].replace(/^0+/,""));
229
            }
230
            break;
231
        default:
232
            // all other combinations are invalid
233
            return false;
234
            break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
235
    }
236
    
237
    if ( iM == NaN || iH == NaN) {
0 ignored issues
show
Bug introduced by
Comparing a value to NaN with == is always true. Did you mean to use isNaN(iH) ?
Loading history...
Bug introduced by
Comparing a value to NaN with == is always true. Did you mean to use isNaN(iM) ?
Loading history...
238
        return false;
239
    }
240
241
    if (iM > 59) {
242
        // javascript down know an operator like DIV (integer division)
243
        iH += (iM - (iM % 60)) / 60;
244
        iM = iM % 60;
245
    }
246
    // ... 23:59 is the end
247
    if (iH > 23) {
248
        return false;
249
    }
250
251
    // initializte Date-Object
252
    var date = new Date(0, 0, 0, iH, iM, iS);
253
    
254
    // and compare relevant parts
255
    var iH2 = date.getHours();
256
    var iM2 = date.getMinutes();
257
    if (iH != iH2 || iM != iM2) {
258
        return false;
259
    }
260
    strTime = '';
261
    if (iH < 10) {
262
        strTime = '0';
263
    }
264
    strTime += iH + ':';
265
    if (iM < 10) {
266
        strTime += '0';
267
    }
268
    strTime += iM; // + ':00';
269
    return strTime;
270
}
271
272
FormDataValidator.prototype.isValidInteger = function(strInt)
273
{
274
    // remove all whitespace
275
    strInt = strInt.toString().trim();
276
    if (isNaN(strInt) || strInt.indexOf('.') !== -1) {
277
        return false;
278
    }
279
    if (strInt == '') {
280
        strInt = '0';
281
    }
282
    return strInt;
283
}
284
285
FormDataValidator.prototype.isValidCurrency = function(strCur)
286
{
287
    // remove all whitespace
288
    strCur = strCur.toString().trim();
289
    
290
    // remove thousands separator and replace comma to point
291
    strCur = strCur.replace( ".", "" );
292
    strCur = strCur.replace( ",", "." );
293
    if (isNaN(strCur)) {
294
        return false;
295
    }
296
    if (strCur == '') {
297
        strCur = '0';
298
    }
299
    strCur = Number.parseFloat(strCur).toFixed(2);
300
    strCur = strCur.replace( ".", "," );
301
    strCur = strCur.replace(/\B(?=(\d{3})+(?!\d))/g, ".");        
302
    return strCur;
303
}
304