Passed
Branchmaster (c8ea1a)
by Plamen
01:22
created

table.js ➔ ... ➔ DrawSection   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 3
nop 3
dl 0
loc 18
rs 9.75
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
var TableHelperProcessPaginationLinks = function(tfoot){
103
    var pLinks = tfoot.querySelectorAll(".paging a");
104
    if(pLinks.length > 0){
105
        for(var j = 0; j < pLinks.length; j++){
106
            pLinks[j].setAttribute("href", "javascript:void(0);");
107
            pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
108
        }
109
    }
110
};
111
var TableHelperIfPrior = function(v){
112
    var rv = false;
113
    if(window.navigator.appName === 'Microsoft Internet Explorer'){
114
        var ua = window.navigator.userAgent;
115
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
116
        if(re.exec(ua) !== null){
117
            rv = parseFloat(RegExp.$1);
118
        }
119
        rv = rv < v ? true : false;
120
    }
121
    return rv;
122
};
123
var TableHelperRequestToUrl = function(rq){
124
    var url = location.pathname + ".json" + location.search;
125
    if(typeof rq === "object"){
126
        var getUrlVarName = {
127
            colNo: "col", colOrd: "ord", filter: "filter",
128
            filterBy: "filter-by", pageNo: "pg", exportType: "export",
129
            tableId: "table-id"
130
        };
131
        var flagFirst = location.search.length < 1 ? true : false;
132
        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...
133
            var clue = flagFirst === true ? "?" : "&";
134
            url += clue + getUrlVarName[r] + "=" + rq[r];
135
            flagFirst = false;
136
        }
137
    }
138
    return url;
139
};
140
var TableHelperGetParent = function(obj, objType){
141
    while(obj && obj.tagName !== objType.toUpperCase()){
142
        obj = obj.parentNode;
143
    }
144
    return obj;
145
};
146
var TableHelperFilterGetTableId = function(field){
147
    if(field.tagName.toLowerCase() !== "select"){
148
        return field.getAttribute("data-table-id");
149
    }
150
    var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
151
    return '' === f.value ? null : f.getAttribute("data-table-id");
152
};
153
var TableHelperClearSection = function(tSection, iePrior9){
154
    if(iePrior9){
155
        if(tSection.firstChild){
156
            while(tSection.firstChild){
157
                tSection.removeChild(tSection.firstChild);
158
            }
159
        }
160
    }else{
161
        tSection.innerHTML = "";
162
    }
163
};
164
var TableHelperDrawCellFromObject = function(row, cell, tCell){
165
    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...
166
        if(typeof row[cell][attr] === "string"){
167
            tCell.innerHTML = row[cell][attr];
168
        }else if(typeof row[cell][attr] === "object"){
169
            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...
170
                tCell.setAttribute(v, row[cell][attr][v]);
171
            }
172
        }
173
    }
174
};
175
var TableHelperDrawRow = function(row, tRow){
176
    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...
177
        var tCell = document.createElement("td");
178
        if(typeof row[cell] === "string" || typeof row[cell] === "number"){
179
            tCell.innerHTML = row[cell];
180
        }else if(typeof row[cell] === "object"){
181
            TableHelperDrawCellFromObject(row, cell, tCell);
182
        }
183
        tRow.appendChild(tCell);
184
    }
185
};
186
187
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
188
var TableSingleton = (function(){
189
    // Instance stores a reference to the Singleton
190
    var instance;
191
    function initInstance(){
192
        // Singleton
193
        // Private methods and variables
194
        function BuildRequest(rq, crntTableId){
195
            rq.tableId = crntTableId;
196
            TableHelperRequestSort(rq, instance.strDesc);
197
            TableHelperRequestFilter(rq);
198
        }
199
        var tail = [];
200
        function LoadData(tableContainer, rq){
201
            SetVisability(tableContainer, false);
202
            if(window.XMLHttpRequest){
203
                var xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
204
            }else{ 
205
                xmlhttp = new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
206
            }
207
            for(var i = 0; i < tail.length; i++){
208
                var ex_xmlhttp = tail.shift();
209
                ex_xmlhttp.abort();
210
            }
211
            xmlhttp.onreadystatechange = function(){
212
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
213
                    var d = JSON.parse(xmlhttp.responseText);
214
                    instance.rq = rq;
215
                    instance.Draw(tableContainer, d);
216
                }
217
            };
218
            xmlhttp.open("GET", RequestToUrl(rq), true);
219
            xmlhttp.send();
220
            tail.push(xmlhttp); //put at tail to can abort later any previous
221
        }
222
        function SetTheTableColumnsHoverEffect(tContainer, tableId){
223
            var tHcells = tContainer.rows[0].cells;
224
            for(var i = 0; i < tHcells.length; i++){
225
                if(tHcells[i].firstChild.tagName === "A"){
226
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableId + "'," + i + ");");
227
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableId + "');");
228
                }
229
            }
230
        }
231
        function Init(tableId){
232
            var tContainer = document.getElementById(tableId);
233
            if(iePrior(9)){
234
                SetTheTableColumnsHoverEffect(tContainer, tableId);
235
            }
236
            var tfoot = tContainer.getElementsByTagName("tfoot")[0];
237
            ProcessPaginationLinks(tfoot);
238
        }
239
        
240
        function DrawSection(tableContainer, dt, tSection){
241
            var section = tSection === "tfoot" ? "tfoot" : "tbody";
242
            var tSec = document.getElementById(tableContainer)
243
                        .getElementsByTagName(section)[0];
244
            ClearSection(tSec, iePrior(9));
245
            for(var i = 0; i < dt.length; i++){
246
                var row = dt[i];
247
                var tRow = document.createElement("tr");
248
249
                DrawRow(row, tRow);
250
251
                tSec.appendChild(tRow);
252
                if(section === "tfoot"){
253
                    ProcessPaginationLinks(tSec);
254
                }
255
                instance.AppendRowCalback(tableContainer);
256
            }
257
        }
258
        
259
        var ClearSection = TableHelperClearSection;
260
        var DrawRow = TableHelperDrawRow;
261
        var FilterGetTableId = TableHelperFilterGetTableId;
262
        var getParent = TableHelperGetParent;
263
        var iePrior = TableHelperIfPrior;
264
        var ProcessPaginationLinks = TableHelperProcessPaginationLinks;
265
        var RequestToUrl = TableHelperRequestToUrl;
266
        var SetVisability = TableHelperSetVisability;
267
        
268
        return {
269
            rq: null,
270
            strAsc: String.fromCharCode(9650), //&#9650;
271
            strDesc: String.fromCharCode(9660),//&#9660; 
272
            ReloadData: function(tableId){
273
                var request = {};
274
                BuildRequest(request, tableId);
275
                LoadData(tableId, request);
276
            },
277
            Filter: function(field){
278
                var crntTableId = FilterGetTableId(field);
279
                if(crntTableId !== null){
280
                    var request = {};
281
                    var exRq = this.rq;
282
                    BuildRequest(request, crntTableId);
283
                    if(exRq === null ||
284
                        request.filter !== exRq.filter ||
285
                        request.filterBy !== exRq.filterBy
286
                    ){
287
                        LoadData(crntTableId, request);
288
                    }
289
                }
290
            },
291
            GoPage: function(lnk){
292
                var request = {};
293
                var table = getParent(lnk, "table");
294
                var crntTableId = table.getAttribute("id");
295
                BuildRequest(request, crntTableId);
296
                //check & serve pagination jump links
297
                var jumpDir = lnk.innerHTML.trim().substr(0, 1);
298
                if(jumpDir === "+" || jumpDir === "-"){
299
                    var current = table.querySelector("tfoot .paging .a").innerHTML;
300
                    var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
301
                    var jumpPage = (parseInt(current) + parseInt(jump));
302
                    lnk.parentNode.setAttribute("data-page", jumpPage);
303
                    lnk.style.transform = "none";
304
                }
305
                request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
306
                                    lnk.parentNode.getAttribute("data-page") :
307
                                    lnk.innerHTML;
308
                LoadData(crntTableId, request);
309
                return false;
310
            },
311
            Export: function(lnk, eType){
312
                var request = {};
313
                var crntTableId = getParent(lnk, "table").getAttribute("id");
314
                BuildRequest(request, crntTableId);
315
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
316
                                        eType : 
317
                                        "csv";
318
                window.open(RequestToUrl(request));
319
                return false;
320
            },
321
            Sort: function(colNo, lnk){
322
                var request = {};
323
                var crntTableId = getParent(lnk, "table").getAttribute("id");
324
                BuildRequest(request, crntTableId);
325
                if(Math.round(colNo) === request.colNo){
326
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
327
                }else{
328
                    request.colNo = Math.round(colNo);
329
                    request.colOrd = "asc";
330
                }
331
                LoadData(crntTableId, request);
332
                /* Clear and add new sort arrow */
333
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
334
                var length = headSpans.length;
335
                for(var i = 0; i < length; i++){
336
                    headSpans[i].innerHTML = "";
337
                }
338
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
339
            },
340
341
            ColumnHover: function(tableContainer, index){
342
                if(!iePrior(9)){
343
                    TableHelperColumnHover.call(this, tableContainer, index);
344
                }
345
            },
346
            Draw: function(tableContainer, d){
347
                DrawSection(tableContainer, d.body);
348
                DrawSection(tableContainer, d.footer, "tfoot");
349
                this.LoadEndCalback(tableContainer);
350
                SetVisability(tableContainer, true);
351
                if(this.rq !== null){
352
                    var hover = document.getElementById(this.rq.tableId)
353
                                .getElementsByTagName("th")[this.rq.colNo].lang;
354
                    if(hover){
355
                        this.ColumnHover(tableContainer, this.rq.colNo);
356
                    }
357
                }
358
                
359
            },
360
            init: Init,
361
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
362
            AppendRowCalback:  function(){}/*Allows override: function(tableId){if(tableId){...}}*/
363
        };
364
    }
365
    return {
366
        //Get the Singleton instance if one exists, or create one if it doesn't
367
        getInstance: function(){
368
            if(!instance){
369
                instance = initInstance();
370
            }
371
            return instance;
372
        }
373
    };
374
})();
375
var table = TableSingleton.getInstance();
376