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