Passed
Push — master ( ea04ca...951b06 )
by Plamen
01:36
created

add/table.js   A

Complexity

Total Complexity 10
Complexity/F 1.11

Size

Lines of Code 54
Function Count 9

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 74
Bugs 5 Features 3
Metric Value
cc 0
eloc 36
c 74
b 5
f 3
nc 1
dl 0
loc 54
rs 10
wmc 10
mnd 1
bc 10
fnc 9
bpm 1.1111
cpm 1.1111
noi 0

2 Functions

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