Passed
Push — master ( 20ce20...b43941 )
by Plamen
01:39
created

TableHelper.IePrior   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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