Passed
Branchmaster (78ba7c)
by Plamen
01:28
created

➔ this.SetTheTableColumnsHoverEffect   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 4
eloc 10
c 3
b 1
f 0
nc 4
nop 1
dl 0
loc 14
rs 9.9
1
var strAsc = String.fromCharCode(9650); //▲
2
var strDesc = String.fromCharCode(9660);//▼
3
var xmlhttp;
4
var d;
5
6
var table = new function(){
7
    this.rq = null;
8
    this.tail = [];
9
10
    this.ReloadData = function(tableId){
11
        var request = {};
12
        this.BuildRequest(request, tableId);
13
        this.LoadData(tableId, request);
14
    };
15
16
    this.BuildRequest = function(request, crntTableId, skipPropertyArray){
17
        this.rq = request;
18
        this.checkSkip = function(skipProperty){
19
            var result = false;
20
            if(skipPropertyArray && Object.prototype.toString
21
                    .call(skipPropertyArray) === '[object Array]'
22
                    ){
23
                if(skipPropertyArray.indexOf(skipProperty) >= 0){
24
                    result = true;
25
                }
26
            }
27
            return result;
28
        };
29
        this.getSort = function(){
30
            var thTags = document.getElementById(crntTableId)
31
                    .getElementsByTagName("thead")[0]
32
                    .getElementsByTagName("th");
33
            var length = thTags.length;
34
            for(var i = 0; i < length; i++){
35
                var link = thTags[i].getElementsByTagName("a")[0];
36
                if(link && link.getElementsByTagName("span").length === 1){
37
                    var order = link.getElementsByTagName("span")[0].innerHTML;
38
                    if(order.length === 1){
39
                        this.rq.colNo = i;
40
                        this.rq.colOrd = (order === window.strDesc) ?
41
                                "desc" : "asc";
42
                    }
43
                }
44
            }
45
        };
46
        this.getFilter = function(){
47
            var r = this.getFilterFieldsByTbaleID(crntTableId);
48
            if(r.filter !== null){
49
                this.rq.filter = r.filter;
50
            }
51
            if(r.filterBy !== null){
52
                this.rq.filterBy = r.filterBy;
53
            }
54
        };
55
56
        /* Build request object */
57
        if(!this.checkSkip("sort")){
58
            this.getSort();
59
        }
60
        if(!this.checkSkip("filter")){
61
            this.getFilter();
62
        }
63
64
        this.rq.tableId = crntTableId;
65
        return this.rq;
66
    };
67
68
    this.RequestToUrl = function(rq){
69
        var url = location.pathname + ".json" + location.search;
70
        if(typeof rq === "object"){
71
            var getUrlVarName = {
72
                colNo: "col", colOrd: "ord", filter: "filter",
73
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
74
                tableId: "table-id"
75
            };
76
            var flagFirst = location.search.length < 1 ? true : false;
77
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
78
                var clue = flagFirst === true ? "?" : "&";
79
                url += clue + getUrlVarName[r] + "=" + rq[r];
80
                flagFirst = false;
81
            }
82
        }
83
        return url;
84
    };
85
86
    this.Filter = function(field){
87
        var crntTableId = this.FilterGetTableId(field);
88
        if(crntTableId !== null){
89
            var request = {};
90
            var exRq = this.rq;
91
            this.BuildRequest(request, crntTableId);
92
            if(exRq === null ||
93
                    request.filter !== exRq.filter ||
94
                    request.filterBy !== exRq.filterBy
95
                    ){
96
                this.LoadData(crntTableId, request);
97
            }
98
        }
99
    };
100
101
    this.FilterGetTableId = function(field){
102
        if(field.tagName.toLowerCase() !== "select"){
103
            return field.getAttribute("data-table-id");
104
        } else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
105
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
106
            return '' === f.value ? null : f.getAttribute("data-table-id");
107
        }
108
    };
109
110
    this.GoPage = function(lnk){
111
        var request = {};
112
        var table = this.getParent(lnk, "table");
113
        var crntTableId = table.getAttribute("id");
114
        this.BuildRequest(request, crntTableId);
115
        //check & serve pagination jump links
116
        var jumpDir = lnk.innerHTML.trim().substr(0, 1);
117
        if(jumpDir === "+" || jumpDir === "-"){
118
            var current = table.querySelector("tfoot .paging .a").innerHTML;
119
            var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
120
            var jumpPage = (parseInt(current) + parseInt(jump));
121
            lnk.parentNode.setAttribute("data-page", jumpPage);
122
            lnk.style.transform = "none";
123
        }
124
        request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
125
                lnk.parentNode.getAttribute("data-page") :
126
                lnk.innerHTML;
127
        this.LoadData(crntTableId, request);
128
        return false;
129
    };
130
131
    this.Export = function(lnk, eType){
132
        var request = {};
133
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
134
        this.BuildRequest(request, crntTableId);
135
        request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ? eType : "csv";
136
        window.open(this.RequestToUrl(request));
137
        return false;
138
    };
139
140
    this.Sort = function(colNo, lnk){
141
        var request = {};
142
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
143
        this.BuildRequest(request, crntTableId);
144
        if(Math.round(colNo) === request.colNo){
145
            request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
146
        } else{
147
            request.colNo = Math.round(colNo);
148
            request.colOrd = "asc";
149
        }
150
        this.LoadData(crntTableId, request);
151
        /* Clear and add new sort arrow */
152
        var headSpans = this.getParent(lnk, "thead").getElementsByTagName("span");
153
        var length = headSpans.length;
154
        for(var i = 0; i < length; i++){
155
            headSpans[i].innerHTML = "";
156
        }
157
        lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
158
    };
159
160
    this.DrawSection = function(tableContainer, dt, tSection){
161
        var section = tSection === "tfoot" ? "tfoot" : "tbody";
162
        tSection = document.getElementById(tableContainer).
163
                getElementsByTagName(section)[0];
164
        this.clearSection(tSection);
165
        for(var i = 0; i < dt.length; i++){
166
            var row = dt[i];
167
            var tRow = document.createElement("tr");
168
169
            this.DrawRow(row, tRow);
170
171
            tSection.appendChild(tRow);
172
            if(section === "tfoot"){
173
                this.footerProcessPaginationLinks(tSection);
174
            }
175
            this.AppendRowCalback(tableContainer);
176
        }
177
    };
178
179
    this.DrawRow = function(row, tRow){
180
        for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
181
            var tCell = document.createElement("td");
182
            if(typeof row[cell] === "string" || typeof row[cell] === "number"){
183
                tCell.innerHTML = row[cell];
184
            } else if(typeof row[cell] === "object"){
185
                this.DrawCellFromObject(row, cell, tCell);
186
            }
187
            tRow.appendChild(tCell);
188
        }
189
    };
190
191
    this.DrawCellFromObject = function(row, cell, tCell){
192
        for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
193
            if(typeof row[cell][attr] === "string"){
194
                tCell.innerHTML = row[cell][attr];
195
            } else if(typeof row[cell][attr] === "object"){
196
                for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
197
                    tCell.setAttribute(v, row[cell][attr][v]);
198
                }
199
            }
200
        }
201
    };
202
203
    this.footerProcessPaginationLinks = function(tSection){
204
        var pLinks = tSection.querySelectorAll(".paging a");
205
        if(pLinks.length > 0){
206
            for(var j = 0; j < pLinks.length; j++){
207
                pLinks[j].setAttribute("href", "javascript:void(0);");
208
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
209
            }
210
        }
211
    };
212
213
    this.clearSection = function(tSection){
214
        if(this.iePrior(9)){
215
            if(tSection.firstChild){
216
                while(tSection.firstChild){
217
                    tSection.removeChild(tSection.firstChild);
218
                }
219
            }
220
        } else{
221
            tSection.innerHTML = "";
222
        }
223
    };
224
225
    this.SetTheTableColumnsHoverEffect = function(tableContainer){
226
        if(this.iePrior(9)){
227
            return;
228
        }
229
        var tContainer = document.getElementById(tableContainer);
230
        var tHcells = tContainer.rows[0].cells;
231
        for(var i = 0; i < tHcells.length; i++){
232
            if(tHcells[i].firstChild.tagName === "A"){
233
                tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
234
                tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
235
            }
236
        }
237
        this.setPagingLinksSetActions(tContainer);
238
    };
239
    
240
    this.setPagingLinksSetActions = function(tContainer){
241
        var pLinks = tContainer.querySelectorAll("tfoot .paging a");
242
        if(pLinks.length > 0){
243
            for(var j = 0; j < pLinks.length; j++){
244
                pLinks[j].setAttribute("href", "javascript:void(0);");
245
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
246
            }
247
        }        
248
    };
249
250
    this.ColumnHover = function(tableContainer, index){
251
        if(this.iePrior(9)){
252
            return;
253
        }
254
        var tRow = document.getElementById(tableContainer).rows;
255
        index = Math.round(index);
256
        for(var i = 0; i < (tRow.length - 1); i++){
257
            if(index >= 0){
258
                tRow[i].cells[index].setAttribute("lang", "col-hover");
259
            } else{
260
                for(var j = 0; j < tRow[i].cells.length; j++){
261
                    if(tRow[i].cells[j].lang){
262
                        tRow[i].cells[j].removeAttribute("lang");
263
                    }
264
                }
265
            }
266
        }
267
    };
268
269
    this.getFilterFieldsByTbaleID = function(tableID){
270
        var fields = {filterBy: null, filter: null};
271
        var filterDiv = this.getFilterDivByTableIDOrNull(tableID);
272
        if(filterDiv !== null){
273
            var selectObj = filterDiv.getElementsByTagName("select")[0];
274
            var textObj = filterDiv.getElementsByTagName("input")[0];
275
            fields.filterBy = (selectObj === null || selectObj.options[selectObj.selectedIndex].value === "all") ? null : selectObj.options[selectObj.selectedIndex].value;
276
            fields.filter = (textObj === null || textObj.value.length === 0) ? null : encodeURIComponent(textObj.value.trim());
277
        }
278
        return fields;
279
    };
280
281
    this.getFilterDivByTableIDOrNull = function(tableID){
282
        var res = null;
283
        if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
284
            for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
285
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
286
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
287
                }
288
            }
289
290
        }
291
        return res;
292
    };
293
294
    this.LoadData = function(tableContainer, rq){
295
        this.setVisability(tableContainer, false);
296
        if(window.XMLHttpRequest){
297
            xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
298
        } else{ /** global: ActiveXObject */
299
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
0 ignored issues
show
Bug introduced by
The variable ActiveXObject seems to be never declared. If this is a global, consider adding a /** global: ActiveXObject */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
300
        }
301
        for(var i = 0; i < this.tail.length; i++){
302
            var ex_xmlhttp = this.tail.shift();
303
            ex_xmlhttp.abort();
304
        }
305
        xmlhttp.onreadystatechange = function(){
306
            if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
307
                d = JSON.parse(xmlhttp.responseText);
308
                table.DrawSection(tableContainer, d.body);
309
                table.DrawSection(tableContainer, d.footer, "tfoot");
310
                table.LoadEndCalback(tableContainer);
311
                table.setVisability(tableContainer, true);
312
                if(typeof rq === "object"){
313
                    table.ColumnHover(tableContainer, rq.colNo);
314
                }
315
            }
316
        };
317
        xmlhttp.open("GET", this.RequestToUrl(rq), true);
318
        xmlhttp.send();
319
        this.tail.push(xmlhttp); //put in tail to may later abort any previous
320
    };
321
322
    this.setVisability = function(tableContainer, rq){
323
        var tbl = document.getElementById(tableContainer);
324
        if(rq === true){
325
            tbl.style.filter = "none";
326
            tbl.style.opacity = "1";
327
            tbl.style.cursor = "auto";
328
        } else if(rq === false){
329
            tbl.style.filter = "blur(1px)";
330
            tbl.style.opacity = "0.8";
331
            tbl.style.cursor = "wait";
332
        } else{
333
            console.log("table error in the rq value"); /*Shows error*/
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
334
        }
335
    };
336
337
    this.getParent = function(obj, objType){
338
        while(obj && obj.tagName !== objType.toUpperCase()){
339
            obj = obj.parentNode;
340
        }
341
        return obj;
342
    };
343
344
    this.init = function(tableId){
345
        this.SetTheTableColumnsHoverEffect(tableId);
346
    };
347
348
    this.iePrior = function(v){
349
        var rv = false;
350
        if(/** global: navigator */ navigator.appName === 'Microsoft Internet Explorer'){
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
351
            var ua = navigator.userAgent;
352
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
353
            if(re.exec(ua) !== null){
354
                rv = parseFloat(RegExp.$1);
355
            }
356
            rv = rv < v ? true : false;
357
        }
358
        return rv;
359
    };
360
    this.loadJS = function(src){
361
        var s = document.createElement('script');
362
        s.src = src;
363
        document.getElementsByTagName('head')[0].appendChild(s);
364
    };
365
    this.loadCSS = function(src){
366
        var s = document.createElement('link');
367
        s.href = src;
368
        s.rel = "stylesheet";
369
        document.getElementsByTagName('head')[0].appendChild(s);
370
    };
371
372
    this.LoadEndCalback = function(tableId){
373
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
374
        }
375
    };
376
    this.AppendRowCalback = function(tableId){
377
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
378
        }
379
    };
380
};
381
382
/** Moves custom created filter to the Table's filter
383
 * @param {string} filterId
384
 * @param {string} tableId
385
 * @param {boolean} delay - needed in case the table is istill not executed */
386
function moveSelectorToTheTableFilter(filterId, tableId, delay){
387
    if(delay === true){
388
        setTimeout(function(){
389
            var filterDiv = document.getElementById(tableId)
390
                    .getElementsByTagName("div")[0];
391
            filterDiv.appendChild(document.getElementById(filterId));
392
        }, 500);
393
    } else{
394
        var filterDiv = document.getElementById(tableId)
395
                .getElementsByTagName("div")[0];
396
        filterDiv.appendChild(document.getElementById(filterId));
397
    }
398
}
399
function changeListCustomFilter(selectObj){
400
    var fId = selectObj.options[selectObj.selectedIndex].value;
401
    var hasValue = fId !== "{!--Empty--!}";
402
    var varName = selectObj.getAttribute("name");
403
    var varPos = (document.URL.indexOf(varName) - (hasValue ? 0 : 1));
404
    if(varPos > 0){
405
        var url = document.URL.substring(0, varPos);
406
    } else{
407
        var separator = document.URL.indexOf("?") > 0 ? "&" : "?";
408
        url = document.URL + (hasValue ? separator : "");
409
    }
410
    var newUrl = url + (hasValue ? (varName + "=" + fId) : "");
411
    location.assign(newUrl);
412
}
413
414
415
function tablesLoadData(){
416
    var tables = document.getElementsByTagName("table");
417
    var envPrior9 = table.iePrior(9);
418
    for(var i = 0; i < tables.length; i++){
419
        var isProcessable = envPrior9 ?
420
                typeof tables[i]["data-table"] !== 'undefined' :
421
                tables[i].hasAttribute("data-table");
422
        if(isProcessable && tables[i].getAttribute("data-table") === "js"){
423
            table.LoadData(tables[i].id);
424
            table.SetTheTableColumnsHoverEffect(tables[i].id);
425
        }
426
    }
427
    if(table.iePrior(10)){
428
        table.loadJS("/add/helpers/table/add/json2.js");
429
    }
430
431
    /*if(table.iePrior(8)){ //can be used to add apropriate tables links modifications
432
     // loadCSS("/add/helpers/table/add/ie7-and-down.css");
433
     }*/
434
}
435
436
/*if(window.addEventListener){window.addEventListener('load',tablesLoadData,false);} else if(window.attachEvent){window.attachEvent('onload',tablesLoadData);}*/