Passed
Push — master ( 41aee4...b0c0be )
by Plamen
01:25
created

TableHelper.Draw.Section   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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