Passed
Push — master ( 788bee...5c5f2e )
by Plamen
01:25
created

table.js ➔ ... ➔ Init   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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