Passed
Branchmaster (d1850b)
by Plamen
01:31
created

TableHelper.Draw   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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