Passed
Branchmaster (bb7c45)
by Plamen
01:37
created

TableHelper.LoadData.Run   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 6
c 1
b 0
f 1
nc 2
nop 0
dl 0
loc 8
rs 10
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
        tail: null,
196
        Run: function(tableContainer, rq, instance){
197
            if(tail!==null){ tail.abort();}
0 ignored issues
show
Bug introduced by
The variable tail seems to be never declared. If this is a global, consider adding a /** global: tail */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
198
            SetVisability(tableContainer, false);
199
            var xmlhttp = window.XMLHttpRequest ? 
200
                            new XMLHttpRequest() : //IE7+, Firefox, Chrome, Opera, Safari
201
                            new window.ActiveXObject("Microsoft.XMLHTTP");//IE6, IE5
202
            xmlhttp.onreadystatechange = function(){
203
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
204
                    var d = JSON.parse(xmlhttp.responseText);
205
                    Draw.Run(tableContainer, d, instance);
0 ignored issues
show
Bug introduced by
The variable Draw seems to be never declared. If this is a global, consider adding a /** global: Draw */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
206
                    SetVisability(tableContainer, true);
207
                    instance.LoadEndCalback(tableContainer);
208
                }
209
            };
210
            xmlhttp.open("GET", RequestToUrl(rq), true);
211
            xmlhttp.send();
212
            tail = xmlhttp; //put at tail to can abort later previous request
0 ignored issues
show
Bug introduced by
The variable tail seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.tail.
Loading history...
213
        },
214
        SetVisability: function(tableContainer, flag){
215
            var tbl = document.getElementById(tableContainer);
216
            if(flag === true){
217
                tbl.style.filter = "none";
218
                tbl.style.opacity = "1";
219
                tbl.style.cursor = "auto";
220
            }else if(flag === false){
221
                tbl.style.filter = "blur(1px)";
222
                tbl.style.opacity = "0.8";
223
                tbl.style.cursor = "wait";
224
            }else{
225
                console.error("table error in the flag value");
226
            }
227
        }
228
    },
229
230
    IePrior: function(v){
231
        var rv = false;
232
        if(window.navigator.appName === 'Microsoft Internet Explorer'){
233
            var ua = window.navigator.userAgent;
234
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
235
            if(re.exec(ua) !== null){
236
                rv = parseFloat(RegExp.$1);
237
            }
238
            rv = rv < v ? true : false;
239
        }
240
        return rv;
241
    },
242
    GetParent: function(obj, objType){
243
        while(obj && obj.tagName !== objType.toUpperCase()){
244
            obj = obj.parentNode;
245
        }
246
        return obj;
247
    },
248
    ProcessPaginationLinks: function(tfoot){
249
        var pLinks = tfoot.querySelectorAll(".paging a");
250
        if(pLinks.length > 0){
251
            for(var j = 0; j < pLinks.length; j++){
252
                pLinks[j].setAttribute("href", "javascript:void(0);");
253
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
254
            }
255
        }
256
    },
257
    RequestToUrl: function(rq){
258
        var url = location.pathname + ".json" + location.search;
259
        if(typeof rq === "object"){
260
            var getUrlVarName = {
261
                colNo: "col", colOrd: "ord", filter: "filter",
262
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
263
                tableId: "table-id"
264
            };
265
            var flagFirst = location.search.length < 1 ? true : false;
266
            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...
267
                var clue = flagFirst === true ? "?" : "&";
268
                url += clue + getUrlVarName[r] + "=" + rq[r];
269
                flagFirst = false;
270
            }
271
        }
272
        return url;
273
    }
274
};
275
276
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
277
var TableSingleton = (function(){
278
    // Instance stores a reference to the Singleton
279
    var instance;
280
    function initInstance(){
281
        // Singleton
282
        // Private methods and variables
283
        var BuildRequest = TableHelper.BuildRequest.Run;
284
        var LoadData = TableHelper.LoadData.Run;
285
        function ReloadData(tableId){
286
            var request = {};
287
            BuildRequest(request, tableId, this.strDesc);
288
            LoadData(tableId, request, instance);
289
        }
290
        var GoPageGetNo = TableHelper.GoPage.GetNo;
291
        var getParent = TableHelper.GetParent;
292
        var RequestToUrl = TableHelper.RequestToUrl;
293
294
        return {
295
            rq: null,
296
            strAsc: String.fromCharCode(9650), //&#9650;
297
            strDesc: String.fromCharCode(9660),//&#9660; 
298
            ColumnHover: TableHelper.ColumnHover, //function(tableContainer, index)
299
            Export: function(lnk, eType){
300
                var request = {};
301
                var crntTableId = getParent(lnk, "table").getAttribute("id");
302
                BuildRequest(request, crntTableId, this.strDesc);
303
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
304
                                        eType : 
305
                                        "csv";
306
                window.open(RequestToUrl(request));
307
                return false;
308
            },
309
            Filter: function(field){
310
                var crntTableId = TableHelper.Filter.GetTableId(field);
311
                if(crntTableId !== null){
312
                    var request = {};
313
                    var exRq = this.rq;
314
                    BuildRequest(request, crntTableId, this.strDesc);
315
                    if(exRq === null ||
316
                        request.filter !== exRq.filter ||
317
                        request.filterBy !== exRq.filterBy
318
                    ){
319
                        LoadData(crntTableId, request, instance);
320
                    }
321
                }
322
            },
323
            GoPage: function(lnk){
324
                var request = {};
325
                var crntTableId = getParent(lnk, "table").getAttribute("id");
326
                BuildRequest(request, crntTableId, this.strDesc);
327
                request.pageNo = GoPageGetNo(lnk, crntTableId);
328
                LoadData(crntTableId, request, instance);
329
                return false;
330
            },
331
            init: function (tableId){
332
                var tContainer = document.getElementById(tableId);
333
                if(!TableHelper.IePrior(9)){
334
                    TableHelper.Init.SetColumnsHoverEffect(tContainer, tableId);
335
                }
336
                var tfoot = tContainer.getElementsByTagName("tfoot")[0];
337
                TableHelper.ProcessPaginationLinks(tfoot);
338
            },
339
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
340
            ReloadData: ReloadData,
341
            Sort: function(colNo, lnk){
342
                var request = {};
343
                var crntTableId = getParent(lnk, "table").getAttribute("id");
344
                BuildRequest(request, crntTableId, this.strDesc);
345
                if(Math.round(colNo) === request.colNo){
346
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
347
                }else{
348
                    request.colNo = Math.round(colNo);
349
                    request.colOrd = "asc";
350
                }
351
                LoadData(crntTableId, request, instance);
352
                /* Clear and add new sort arrow */
353
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
354
                var length = headSpans.length;
355
                for(var i = 0; i < length; i++){
356
                    headSpans[i].innerHTML = "";
357
                }
358
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
359
            }
360
        };
361
    }
362
    return {
363
        //Get the Singleton instance if one exists, or create one if it doesn't
364
        getInstance: function(){
365
            if(!instance){
366
                instance = initInstance();
367
            }
368
            return instance;
369
        }
370
    };
371
})();
372
var table = TableSingleton.getInstance();
373