Passed
Push — master ( 22dcc1...0ad226 )
by Plamen
01:27
created

table.js ➔ ... ➔ BuildRequest   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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