Passed
Branchmaster (16a7a6)
by Plamen
01:26
created

table.js ➔ TableHelperSetVisability   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 14
rs 9.8
1
var TableHelperRequestSort = function(rq, strDesc){
2
    function sortBySpan(span, i){
3
        var order = span.innerHTML;
4
        if(order.length === 1){
5
            rq.colNo = i;
6
            rq.colOrd = order === strDesc ? "desc" : "asc";
7
        }
8
        return rq.colNo === i;
9
    }
10
    
11
    var thTags = document.getElementById(rq.tableId)
12
            .getElementsByTagName("thead")[0]
13
            .getElementsByTagName("th");
14
    var length = thTags.length;
15
    for(var i = 0; i < length; i++){
16
        var link = thTags[i].getElementsByTagName("a")[0];
17
        if(link){
18
            var span = link.getElementsByTagName("span")[0];
19
            if(span && sortBySpan(span, i)){
20
                break;
21
            }
22
        }
23
    }
24
};
25
var TableHelperRequestFilter = function(rq){
26
    function getFilterFieldsByTableID(tableID){
27
        var fields = {filterBy: null, filter: null};
28
        var filterDiv = getFilterDivByTableIDOrNull(tableID);
29
        if(filterDiv !== null){
30
            setFilterBy(fields, filterDiv);
31
            setFilterValue(fields, filterDiv);
32
        }
33
        return fields;
34
    }
35
    function getFilterDivByTableIDOrNull(tableID){
36
        var res = null;
37
        if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
38
            for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
39
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
40
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
41
                }
42
            }
43
44
        }
45
        return res;
46
    }
47
    function setFilterBy(fields, filterDiv){
48
        var slctObj = filterDiv.getElementsByTagName("select")[0];
49
        if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
50
            fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
51
        }
52
    }
53
    function setFilterValue(fields, filterDiv){
54
        var textObj = filterDiv.getElementsByTagName("input")[0];
55
        if(textObj && textObj.value && textObj.value.length !== 0){
56
            fields.filter = encodeURIComponent(textObj.value.trim());
57
        }
58
    }
59
60
    var r = getFilterFieldsByTableID(rq.tableId);
61
    if(r.filter !== null){
62
        rq.filter = r.filter;
63
    }
64
    if(r.filterBy !== null){
65
        rq.filterBy = r.filterBy;
66
    }
67
};
68
var TableHelperColumnHover = function(tableContainer, index){
69
    var rows = document.getElementById(tableContainer).rows;
70
    var upto = rows.length - 1;
71
    if(typeof index === "undefined"){
72
        TableHelperColumnHoverRelease(rows, upto);
73
    } else {
74
        for(var i = 0; i < upto; i++){
75
            rows[i].cells[index].setAttribute("lang", "col-hover");
76
        }
77
    }
78
};
79
var TableHelperColumnHoverRelease = function(rows, upto){
80
    for(var i = 0; i < upto; i++){
81
        for(var j = 0; j < rows[i].cells.length; j++){
82
            if(rows[i].cells[j].lang){
83
                rows[i].cells[j].removeAttribute("lang");
84
            }
85
        }
86
    }
87
};
88
var TableHelperSetVisability = function(tableContainer, flag){
89
    var tbl = document.getElementById(tableContainer);
90
    if(flag === true){
91
        tbl.style.filter = "none";
92
        tbl.style.opacity = "1";
93
        tbl.style.cursor = "auto";
94
    }else if(flag === false){
95
        tbl.style.filter = "blur(1px)";
96
        tbl.style.opacity = "0.8";
97
        tbl.style.cursor = "wait";
98
    }else{
99
        console.error("table error in the flag value");
100
    }
101
};
102
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
103
var TableSingleton = (function(){
104
    // Instance stores a reference to the Singleton
105
    var instance;
106
    function initInstance(){
107
        // Singleton
108
        // Private methods and variables
109
        function BuildRequest(rq, crntTableId){
110
            rq.tableId = crntTableId;
111
            TableHelperRequestSort(rq, instance.strDesc);
112
            TableHelperRequestFilter(rq);
113
        }
114
        function getParent(obj, objType){
115
            while(obj && obj.tagName !== objType.toUpperCase()){
116
                obj = obj.parentNode;
117
            }
118
            return obj;
119
        }
120
        function FilterGetTableId(field){
121
            if(field.tagName.toLowerCase() !== "select"){
122
                return field.getAttribute("data-table-id");
123
            }
124
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
125
            return '' === f.value ? null : f.getAttribute("data-table-id");
126
        }
127
        var tail = [];
128
        function LoadData(tableContainer, rq){
129
            SetVisability(tableContainer, false);
130
            if(window.XMLHttpRequest){
131
                var xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
132
            }else{ 
133
                xmlhttp = new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
134
            }
135
            for(var i = 0; i < tail.length; i++){
136
                var ex_xmlhttp = tail.shift();
137
                ex_xmlhttp.abort();
138
            }
139
            xmlhttp.onreadystatechange = function(){
140
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
141
                    var d = JSON.parse(xmlhttp.responseText);
142
                    instance.rq = rq;
143
                    instance.Draw(tableContainer, d);
144
                }
145
            };
146
            xmlhttp.open("GET", RequestToUrl(rq), true);
147
            xmlhttp.send();
148
            tail.push(xmlhttp); //put at tail to can abort later any previous
149
        }
150
        function RequestToUrl(rq){
151
            var url = location.pathname + ".json" + location.search;
152
            if(typeof rq === "object"){
153
                var getUrlVarName = {
154
                    colNo: "col", colOrd: "ord", filter: "filter",
155
                    filterBy: "filter-by", pageNo: "pg", exportType: "export",
156
                    tableId: "table-id"
157
                };
158
                var flagFirst = location.search.length < 1 ? true : false;
159
                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...
160
                    var clue = flagFirst === true ? "?" : "&";
161
                    url += clue + getUrlVarName[r] + "=" + rq[r];
162
                    flagFirst = false;
163
                }
164
            }
165
            return url;
166
        }
167
        function clearSection(tSection){
168
            if(iePrior(9)){
169
                if(tSection.firstChild){
170
                    while(tSection.firstChild){
171
                        tSection.removeChild(tSection.firstChild);
172
                    }
173
                }
174
            }else{
175
                tSection.innerHTML = "";
176
            }
177
        }
178
        function iePrior(v){
179
            var rv = false;
180
            if(window.navigator.appName === 'Microsoft Internet Explorer'){
181
                var ua = window.navigator.userAgent;
182
                var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
183
                if(re.exec(ua) !== null){
184
                    rv = parseFloat(RegExp.$1);
185
                }
186
                rv = rv < v ? true : false;
187
            }
188
            return rv;
189
        }
190
        function setPagingLinksSetActions(tContainer){
191
            var pLinks = tContainer.querySelectorAll("tfoot .paging a");
192
            if(pLinks.length > 0){
193
                for(var j = 0; j < pLinks.length; j++){
194
                    pLinks[j].setAttribute("href", "javascript:void(0);");
195
                    pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
196
                }
197
            }
198
        }
199
        function footerProcessPaginationLinks(tSection){
200
            var pLinks = tSection.querySelectorAll(".paging a");
201
            if(pLinks.length > 0){
202
                for(var j = 0; j < pLinks.length; j++){
203
                    pLinks[j].setAttribute("href", "javascript:void(0);");
204
                    pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
205
                }
206
            }
207
        }
208
        function SetTheTableColumnsHoverEffect(tableContainer){
209
            if(iePrior(9)){
210
                return;
211
            }
212
            var tContainer = document.getElementById(tableContainer);
213
            var tHcells = tContainer.rows[0].cells;
214
            for(var i = 0; i < tHcells.length; i++){
215
                if(tHcells[i].firstChild.tagName === "A"){
216
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
217
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
218
                }
219
            }
220
            setPagingLinksSetActions(tContainer);
221
        }
222
        var SetVisability = TableHelperSetVisability.bind(this);
223
        return {
224
            rq: null,
225
            strAsc: String.fromCharCode(9650), //&#9650;
226
            strDesc: String.fromCharCode(9660),//&#9660; 
227
            ReloadData: function(tableId){
228
                var request = {};
229
                BuildRequest(request, tableId);
230
                LoadData(tableId, request);
231
            },
232
            Filter: function(field){
233
                var crntTableId = FilterGetTableId(field);
234
                if(crntTableId !== null){
235
                    var request = {};
236
                    var exRq = this.rq;
237
                    BuildRequest(request, crntTableId);
238
                    if(exRq === null ||
239
                        request.filter !== exRq.filter ||
240
                        request.filterBy !== exRq.filterBy
241
                    ){
242
                        LoadData(crntTableId, request);
243
                    }
244
                }
245
            },
246
            GoPage: function(lnk){
247
                var request = {};
248
                var table = getParent(lnk, "table");
249
                var crntTableId = table.getAttribute("id");
250
                BuildRequest(request, crntTableId);
251
                //check & serve pagination jump links
252
                var jumpDir = lnk.innerHTML.trim().substr(0, 1);
253
                if(jumpDir === "+" || jumpDir === "-"){
254
                    var current = table.querySelector("tfoot .paging .a").innerHTML;
255
                    var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
256
                    var jumpPage = (parseInt(current) + parseInt(jump));
257
                    lnk.parentNode.setAttribute("data-page", jumpPage);
258
                    lnk.style.transform = "none";
259
                }
260
                request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
261
                                    lnk.parentNode.getAttribute("data-page") :
262
                                    lnk.innerHTML;
263
                LoadData(crntTableId, request);
264
                return false;
265
            },
266
            Export: function(lnk, eType){
267
                var request = {};
268
                var crntTableId = getParent(lnk, "table").getAttribute("id");
269
                BuildRequest(request, crntTableId);
270
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
271
                                        eType : 
272
                                        "csv";
273
                window.open(RequestToUrl(request));
274
                return false;
275
            },
276
            Sort: function(colNo, lnk){
277
                var request = {};
278
                var crntTableId = getParent(lnk, "table").getAttribute("id");
279
                BuildRequest(request, crntTableId);
280
                if(Math.round(colNo) === request.colNo){
281
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
282
                }else{
283
                    request.colNo = Math.round(colNo);
284
                    request.colOrd = "asc";
285
                }
286
                LoadData(crntTableId, request);
287
                /* Clear and add new sort arrow */
288
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
289
                var length = headSpans.length;
290
                for(var i = 0; i < length; i++){
291
                    headSpans[i].innerHTML = "";
292
                }
293
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
294
            },
295
            DrawSection: function(tableContainer, dt, tSection){
296
                var section = tSection === "tfoot" ? "tfoot" : "tbody";
297
                tSection = document.getElementById(tableContainer).
298
                            getElementsByTagName(section)[0];
299
                clearSection(tSection);
300
                for(var i = 0; i < dt.length; i++){
301
                    var row = dt[i];
302
                    var tRow = document.createElement("tr");
303
304
                    this.DrawRow(row, tRow);
305
306
                    tSection.appendChild(tRow);
307
                    if(section === "tfoot"){
308
                        footerProcessPaginationLinks(tSection);
309
                    }
310
                    this.AppendRowCalback(tableContainer);
311
                }
312
            },
313
            DrawRow: function(row, tRow){
314
                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...
315
                    var tCell = document.createElement("td");
316
                    if(typeof row[cell] === "string" || typeof row[cell] === "number"){
317
                        tCell.innerHTML = row[cell];
318
                    }else if(typeof row[cell] === "object"){
319
                        this.DrawCellFromObject(row, cell, tCell);
320
                    }
321
                    tRow.appendChild(tCell);
322
                }
323
            },
324
            DrawCellFromObject: function(row, cell, tCell){
325
                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...
326
                    if(typeof row[cell][attr] === "string"){
327
                        tCell.innerHTML = row[cell][attr];
328
                    }else if(typeof row[cell][attr] === "object"){
329
                        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...
330
                            tCell.setAttribute(v, row[cell][attr][v]);
331
                        }
332
                    }
333
                }
334
            },
335
            ColumnHover: function(tableContainer, index){
336
                if(!iePrior(9)){
337
                    TableHelperColumnHover.call(this, tableContainer, index);
338
                }
339
            },
340
            Draw: function(tableContainer, d){
341
                this.DrawSection(tableContainer, d.body);
342
                this.DrawSection(tableContainer, d.footer, "tfoot");
343
                this.LoadEndCalback(tableContainer);
344
                SetVisability(tableContainer, true);
345
                if(this.rq !== null){
346
                    console.log(this.rq);
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...
347
                    var hover = document.getElementById(this.rq.tableId)
348
                                .getElementsByTagName("th")[this.rq.colNo].lang;
349
                    if(hover){
350
                        this.ColumnHover(tableContainer, this.rq.colNo);
351
                    }
352
                }
353
                
354
            },
355
            init: function(tableId){
356
                SetTheTableColumnsHoverEffect(tableId);
357
            },
358
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
359
            AppendRowCalback:  function(){}/*Allows override: function(tableId){if(tableId){...}}*/
360
        };
361
    }
362
    return {
363
        //Get the Singleton instance if one exists, or create one if it doesn't
364
        getInstance: function(){
365
            if(!instance){
366
                instance = initInstance();
367
            }
368
            return instance;
369
        }
370
    };
371
})();
372
var table = TableSingleton.getInstance();
373