Passed
Branchmaster (e91531)
by Plamen
01:41
created

table.js ➔ ... ➔ getFilter   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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