Passed
Push — master ( b43941...d62fdb )
by Plamen
01:47
created

TableHelper.Draw.Section   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 56
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
cc 4
eloc 39
c 5
b 1
f 1
nc 3
nop 3
dl 0
loc 56
rs 8.9439

3 Functions

Rating   Name   Duplication   Size   Complexity  
A 0 11 4
B 0 15 7
B 0 15 6

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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