Passed
Push — master ( d3127e...8c35a9 )
by Plamen
01:42
created

TableHelper.Init.Run   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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