GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( c4a44c...98b464 )
by Keith
19:51
created

js/directive.editbox.js   F

Complexity

Total Complexity 61
Complexity/F 2.54

Size

Lines of Code 303
Function Count 24

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
eloc 182
nc 16
dl 0
loc 303
rs 3.52
c 0
b 0
f 0
wmc 61
mnd 3
bc 46
fnc 24
bpm 1.9166
cpm 2.5416
noi 17

How to fix   Complexity   

Complexity

Complex classes like js/directive.editbox.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * <editbox> auto generate a invisible <pageview> element, Popup a modal and the pageview when the user click the edit button
3
 * <editbox
4
    ng-model=""
5
    program-id=""
6
    >
7
 * @param {Object} ng-model - store the user selected record from the pageview, to display the record details on the UI.
8
 * @param {String} program-id - the pageview will display the records regarding to this program id
9
 */
10
app.directive('editbox', ['Core', 'Security', '$rootScope', '$compile', 'ThemeService', 'TableManager', 'DataAdapter', 'config', function(Core, Security, $rootScope, $compile, ThemeService, TableManager, DataAdapter, config) {
11
    function EditboxConstructor($scope, $element, $attrs) {
12
		if(Core.GetConfig().debugLog.DirectiveFlow)
13
			console.log("1 Edotbox - EditboxConstructor()");
14
        var constructor = this;
15
        var $ctrl = $scope.editboxCtrl;
16
17
    	function InitializeEditBox() {
18
            $scope.editboxDataList = [];
19
            if(typeof($ctrl.ngModel) == "undefined" || $ctrl.ngModel == null)
20
                $ctrl.ngModel = {};
21
22
		    // check attribute programId
23
            var isProgramIdFound = false;
24
            if(typeof($attrs.programId) != undefined){
25
            	if($attrs.programId != null && $attrs.programId !=""){
26
            		isProgramIdFound = true;
27
            	}
28
            }
29
            if(isProgramIdFound){
30
            	$scope.programId = $attrs.programId;
31
            }
32
            else
33
            	alert("<editbox> Must declare a attribute of program-id");
34
35
		    // check attribute screenId
36
            var isScreenIdFound = false;
37
            if(typeof($attrs.screenId) != undefined){
38
            	if($attrs.screenId != null && $attrs.screenId !=""){
39
            		isScreenIdFound = true;
40
            	}
41
            }
42
            if(isScreenIdFound){
43
            	$scope.screenId = $attrs.screenId;
44
            }else{
45
                $scope.screenId = "";
46
                if(typeof($scope.programId) != "undefined")
47
                    $scope.screenId = $scope.programId;
48
            }
49
50
            var isInRange = IsParentInRange();
51
            if(isInRange){
52
                var isRangeProperty = false;
53
                if(typeof($attrs.range) != undefined){
54
                    if($attrs.range != null && $attrs.range !=""){
55
                        isRangeProperty = true;
56
                    }
57
                }
58
                if(isRangeProperty){
59
                    $scope.range = $attrs.range;
60
                }
61
                else{
62
                    console.warn("<editbox> Should declare a attribute of range, since it is under <range>");
63
                }
64
65
                var isRangeValuePropery = false;
66
                if(typeof($attrs.rangeValue) != undefined){
67
                    if($attrs.rangeValue != null){
68
                        isRangeValuePropery = true;
69
                    }
70
                }
71
                if(isRangeValuePropery){
72
                    // cannot assign ALL to $attrs.rangeValue, it will break the binding between $attrs.rangeValue <--> expression
73
                    // the ALL should assign in the range directive
74
                    $attrs.$observe('rangeValue', function(interpolatedValue){
75
                        $scope.rangeValue = interpolatedValue;
76
                        if(typeof ($scope.$parent.SetRange) == "function"){
77
                            $scope.$parent.SetRange($scope.range, interpolatedValue)
78
                        }
79
                    })
80
                }
81
                else{
82
                    console.warn("<editbox> Should declare a attribute of rangeValue, since it is under <range>");
83
                }
84
            }
85
    	}
86
87
        function IsParentInRange(){
88
89
            var isParentScopeFromRange = false;
90
            if(typeof ($scope.$parent.IsRange) == "function"){
91
                isParentScopeFromRange = true;
92
                isParentScopeFromRange = $scope.$parent.IsRange();
93
            }
94
95
            return isParentScopeFromRange;
96
        }
97
98
        
99
		$scope.SetNgModel = function(dataRecord){
100
            if(dataRecord.length > 0)
101
			    SetNgModel(dataRecord[0]);
102
		}
103
104
        function SetNgModel(dataJson){
105
            var dataColumns = $scope.tableStructure.DataColumns;
106
            var keyColumns = $scope.tableStructure.KeyColumns;
107
108
            // var dataRecord = dataJson.ActionResult.data[0];
109
            var dataRecord = dataJson;
110
111
        	for(var columnName in dataColumns){
112
        		var column = dataColumns[columnName];
113
        		var colDataType = column.type;
114
115
                var isSystemField = Core.IsSystemField(columnName);
116
                if(isSystemField)
117
                    continue;
118
119
                var newColumn = dataRecord[columnName];
120
                var dataValue = dataRecord[columnName];
121
122
//        		// is column exists in ngModel
123
        		if(typeof(dataValue) == "undefined" || !dataValue){
124
        			if(colDataType == "string"){
125
        				dataValue = "";
126
        			}
127
        			else if (colDataType == "date" || colDataType == "datetime"){
128
        				dataValue = new Date(0, 0, 0);
129
        			}
130
        			else if (colDataType == "double"){
131
        				dataValue = 0.0;
132
        			}
133
                }
134
135
        		if (colDataType == "date"){
136
                    if(typeof dataValue == "string"){
137
                        var dateArray = dataValue.split("-");
138
                        var year = dateArray[0]; var month = dateArray[1]; var day = dateArray[2];
139
                        year = parseInt(year);
140
                        month = parseInt(month);
141
                        day = parseInt(day);
142
                        newColumn = new Date(year, month, day);
143
                    }else{
144
                        newColumn = dataValue;
145
                    }
146
                }
147
                else if (colDataType == "datetime"){
148
                    if(typeof dataValue == "string"){
149
                        newColumn = getDateFromFormat(dataValue, "yyyy-MM-dd HH:mm:ss");
150
                    }else{
151
                        newColumn = dataValue;
152
                    }
153
    			}
154
    			else if (colDataType == "double"){
155
    				newColumn = parseFloat(dataValue);
156
    			}
157
//    			else{
158
//    				newColumn = items[colIndex];
159
//    			}
160
161
                $ctrl.ngModel[columnName] = newColumn;
162
        	}
163
164
        }
165
166
        function GetTableStructure(){
167
        	var programId = $scope.programId.toLowerCase();
168
			var submitData = {
169
				"Table": programId
170
			};
171
172
            var tbResult = TableManager.GetTableStructure(submitData);
173
            tbResult.then(function(responseObj) {
174
                if(Core.GetConfig().debugLog.DirectiveFlow)
175
                    console.log("ProgramID: "+programId+", Table structure obtained.")
176
                SetTableStructure(responseObj);
177
            }, function(reason) {
178
179
            }).finally(function() {
180
                // Always execute this on both error and success
181
            });
182
183
            return tbResult;
184
        }
185
        function SetTableStructure(dataJson){
186
            // console.dir("editbox SetTableStructure")
187
            // console.dir($scope.tableStructure)
188
            $scope.tableStructure.DataColumns = dataJson.DataColumns;
189
            $scope.tableStructure.KeyColumns = dataJson.KeyColumns;
190
            $scope.tableSchema = dataJson.TableSchema;
191
            var itemsColumn = $scope.tableStructure.DataColumns;
192
            
193
            // console.dir(dataJson)
194
            // console.dir($scope.tableStructure)
195
196
            if($ctrl.ngModel == null)
197
                $ctrl.ngModel = {};
198
199
        	for(var colIndex in itemsColumn){
200
        		var columnName = colIndex;
201
                var colDataType = itemsColumn[columnName].type;
202
203
        		var isSystemField = Core.IsSystemField(columnName);
204
205
        		if(isSystemField)
206
        			continue;
207
208
        		var isScopeColExists = true;
209
        		var colObj;
210
211
        		// scope did not defined this column
212
        		if($ctrl.ngModel == null){
213
        			isScopeColExists = false;
214
        		}
215
        		else if(typeof($ctrl.ngModel[columnName]) == "undefined")
216
        		{
217
        			isScopeColExists = false;
218
        		}
219
220
    			if(colDataType == "string"){
221
    				colObj = "";
222
    			}
223
    			else if (colDataType == "date" || colDataType == "datetime"){
224
    				colObj = new Date(0, 0, 0);
225
    			}
226
    			else if (colDataType == "double"){
227
    				colObj = 0.0;
228
    			}
229
230
    			if(!isScopeColExists){
231
232
    			}else{
233
234
    				// if the data type equal
235
    				if(typeof($ctrl.ngModel[columnName]) === typeof(colObj)){
236
                        // if the scope already per-defined some value before GetTableStructure() and SetDefaultValue()
237
                        if($ctrl.ngModel[columnName] != colObj)
238
    					   colObj = $ctrl.ngModel[columnName];
239
    				}else{
240
    					console.warn("The pre-defined default value data type not match of the table structure");
241
    					console.warn("ProgramID: "+$scope.programId +
242
    						", colName:"+columnName+
243
    						", colDataType:"+colDataType+
244
    						", $ctrl.ngModel:"+$ctrl.ngModel[columnName]);
245
    				}
246
    			}
247
248
    			//$scope[columnName] = colObj;
249
250
    			$ctrl.ngModel[columnName] = colObj;
251
        	}
252
        }
253
254
        function ConvertKeyFieldToUppercase(recordObj, isRemoveNonKeyField){
255
            var isKeyValid = true;
256
            var upperRecordObj = {};
257
258
            var tbStructure = $scope.tableStructure;
259
            var itemsColumn = tbStructure.DataColumns;
260
261
            if(typeof(itemsColumn) == "undefined"){
262
                return recordObj;
263
            }
264
265
            if(typeof(isRemoveNonKeyField) == "undefined" || isRemoveNonKeyField == null)
266
                var isRemoveNonKeyField = false;
267
268
            var keyColumnList = tbStructure.KeyColumns;
269
270
            for(var keyIndex in keyColumnList){
271
                var colName = keyColumnList[keyIndex];
272
                var keyColIndex = 0;
273
                var colDataType = "";
274
275
                // key column in table structure not match with param
276
                if(!recordObj.hasOwnProperty(colName)){
277
                    isKeyValid = false;
278
                    break;
279
                }else{
280
                    upperRecordObj[colName] = recordObj[colName];
281
                }
282
283
                // find the key column data type
284
                for(var colNameIndex in itemsColumn){
285
                    if(colName == itemsColumn[colNameIndex])
286
                    {
287
                        keyColIndex = colNameIndex
288
                        break;
289
                    }
290
                }
291
                colDataType = itemsColumn[colName].type;
292
293
                // convert to upper case if the key column is a string data type
294
                if(colDataType == "string"){
295
                    upperRecordObj[colName] = upperRecordObj[colName].toUpperCase();
296
                }
297
            }
298
299
            // if(!isKeyValid){
300
            //     console.log("Avoid to FindData(), upperRecordObj was incomplete.");
301
            //     return;
302
            // }
303
304
            if(!isRemoveNonKeyField){
305
                for(var colName in recordObj){
306
                    if(!upperRecordObj.hasOwnProperty(colName)){
307
                        upperRecordObj[colName] = recordObj[colName];
308
                    }
309
                }
310
            }
311
312
            return upperRecordObj;
313
        }
314
315
        function TryToCallInitDirective(){
316
            $ctrl.programId = $scope.programId;
317
            // $ctrl.screenId = $scope.screenId;
318
319
            if(typeof $scope.InitDirective == "function"){
320
                $scope.InitDirective($scope, $element, $attrs, $ctrl);
321
            }else{
322
                $scope.DefaultInitDirective();
323
            }
324
        }
325
326
        $scope.DefaultInitDirective = function(){
327
            if(Core.GetConfig().debugLog.DirectiveFlow)
328
            console.log("scope.$id:"+$scope.$id+", may implement $scope.InitDirective() function in webapge");
329
330
            var getTableStructurePromiseResult = GetTableStructure();
331
            getTableStructurePromiseResult.then(function(){
332
            });
333
        }
334
335
        $scope.FindData = function(){
336
            var clientID = Security.GetSessionID();
337
            var programId = $scope.programId.toLowerCase();
338
339
            var tempKeyObj = $ctrl.ngModel;
340
341
            var isAllKeyExists = IsKeyInDataRow(tempKeyObj);
342
            if(!isAllKeyExists){
343
                return;
344
            }
345
346
            var isKeyValid = true;
347
            var keyObj = {};
348
            keyObj = ConvertKeyFieldToUppercase(tempKeyObj, true);
349
350
            if(!keyObj)
351
                isKeyValid = false;
352
353
            if(!isKeyValid){
354
                console.log("Avoid to FindData(), keyObj was incomplete.");
355
                return;
356
            }
357
358
        	var findObj = {
359
        		"Header":{}
360
        	}
361
        	findObj.Header[1] = {};
362
            findObj.Header[1] = keyObj;
363
364
			var submitData = {
365
				"Table": programId,
366
				"Data": findObj
367
			};
368
369
            var request = DataAdapter.FindData(submitData);
370
            request.then(function(responseObj) {
371
                var data_or_JqXHR = responseObj.data;
372
                // need to handle if record not found.
373
				$scope.SetNgModel(data_or_JqXHR);
374
				
375
                if(typeof $scope.CustomGetDataResult == "function"){
376
                    $scope.CustomGetDataResult(responseObj,
377
                        responseObj.status,
378
                        $scope,
379
                        $element,
380
                        $attrs,
381
                        $ctrl);
382
                }
383
            }, function(reason) {
384
              console.error("Fail in FindData() - "+tagName + ":"+$scope.programId)
385
              Security.HttpPromiseFail(reason);
386
            }).finally(function() {
387
            });
388
            return request;
389
        }
390
391
        function EventListener(){
392
            if(Core.GetConfig().debugLog.DirectiveFlow)
393
            console.log("$scope.$id:"+$scope.$id+", must implement $scope.EventListener() function in webapge");
394
        }
395
    	function PopupModal(){
396
            var modal = $element.find(".pageview-modal");
397
            var themeCode = config.uiTheme.toUpperCase();
398
            var themeName;
399
            switch(themeCode){
400
                case "D":
401
                    themeName = "default";
402
                    break;
403
                case "B":
404
                    themeName = "bootstrap";
405
                    modal.addClass("fade in");
406
                    break;
407
                case "U":
408
                    themeName = "uikit";
409
                    modal.addClass("uk-modal uk-open");
410
                    break;
411
                case "W":
412
                    themeName = "w3css";
413
                    break;
414
                case "M":
415
                    themeName = "material_ng";
416
                    break;
417
                case "J":
418
                    themeName = "jqueryui";
419
                    break;
420
                case "S":
421
                    themeName = "semantic";
422
                    break;
423
                default:
424
                    themeName = "default";
425
                    break;
426
            }
427
            modal.show();
428
429
    		modal.click(function( event ) {
430
			  $scope.ClosePageView();
431
			});
432
433
    	}
434
435
        $scope.Initialize = function(){
436
			if(Core.GetConfig().debugLog.DirectiveFlow)
437
				console.log("2 Edotbox - Initialize()");
438
            InitializeEditBox();
439
        }
440
441
442
    	$scope.PopupPageview = function(){
443
            var modalContainer = angular.element($element).find(".pageview-modal");
444
            var pageview = angular.element($element).find("pageview");
445
446
            // hide the body scroll bar when showing modal dialog
447
            $("body").css("overflow", "hidden");
448
449
            // var winHeight = jQuery(window).height();
450
            // var winWidth = jQuery(window).width();
451
452
            // var pageviewHeight = pageview.height();
453
            // var pageviewWidth = pageview.width();
454
            // var scrollTop = jQuery(window).scrollTop();
455
            // var scrollLeft = jQuery(window).scrollLeft();
456
457
            // var modalContainerHeight = modalContainer.height();
458
            // var modalContainerWidth = modalContainer.width();
459
460
            // console.log(winHeight);
461
            // console.log(winWidth);
462
            // console.log(pageviewHeight);
463
            // console.log(pageviewWidth);
464
            // console.log(scrollTop);
465
            // console.log(scrollLeft);
466
467
            // popup at center of the screen
468
            pageview.css("top", ( jQuery(window).height() - pageview.height() ) / 2 + "px");
469
            // should not specify the width in number, otherwise break the RWD
470
            //pageview.css("left", ( jQuery(window).width() - pageview.width() ) / 2 + "px");
471
472
    		pageview.show();
473
    	}
474
475
    	$scope.OpenPageView = function(){
476
    		PopupModal();
477
    		$scope.PopupPageview();
478
    	}
479
480
    	$scope.ClosePageView = function(){
481
            $("body").css("overflow", "scroll");
482
483
            var pageviewModal = $element.find(".pageview-modal");
484
            pageviewModal.hide();
485
486
            var pageview = $element.find("pageview");
487
            pageview.hide();
488
    	}
489
490
        // function call from pageview, set editbox ngModel by selected record from pageview
491
        $scope.SetEditboxNgModel = function(selectedRecord){
492
            $ctrl.ngModel = selectedRecord;
493
        }
494
        $scope.ClearEditboxNgModel = function(editboxNgModel){
495
            $ctrl.ngModel = {};
496
        }
497
498
        function IsKeyInDataRow(recordObj){
499
            var tbStructure = $scope.tableStructure;
500
            var itemsColumn = tbStructure.DataColumns;
501
            var keyColumn = tbStructure.KeyColumns;
502
503
            var isAllKeyExists = true;
504
            // if PHP check, do not check if do not use PHP, because we don't is the key allow auto gen
505
            if(!Core.IsMySQLServer())
506
                return isAllKeyExists;
507
508
            for(var keyIndex in keyColumn){
509
                var keyColName = keyColumn[keyIndex];
510
                if(typeof(recordObj[keyColName]) == "undefined"){
511
                    isAllKeyExists = false;
512
                    continue;
513
                }
514
                // find the data type
515
                var dataTypeFound = false;
516
                var keyColDataType = "";
517
                for (var colIndex in itemsColumn) {
518
                    var colName = colIndex;
519
                    var colValue = recordObj[colName];
520
                    if(keyColName == colName){
521
                        dataTypeFound = true;
522
                        keyColDataType = itemsColumn[colIndex].type;
523
                        break;
524
                    }
525
                }
526
527
                if(keyColDataType == "string"){
528
                    if(recordObj[keyColName] == null || recordObj[keyColName] == "")
529
                    {
530
                        isAllKeyExists = false;
531
                        continue;
532
                    }
533
                }
534
535
            }
536
537
            return isAllKeyExists;
538
        }
539
540
        //process flow
541
        $scope.Initialize();
542
        if(typeof $scope.EventListener == "function"){
543
            $scope.EventListener($scope, $element, $attrs, $ctrl);
544
        }else{
545
            EventListener();
546
        }
547
        TryToCallInitDirective();
548
    }
549
    function templateFunctionOLD(tElement, tAttrs, ThemeService) {
550
        var directiveName = tElement[0].tagName;
551
        directiveName = directiveName.toLowerCase();
552
553
        var templateUrl = ThemeService.GetTemplateURL(directiveName);
554
        return templateUrl;
555
    }
556
    function templateUrlFunction(tElement, tAttrs) {
557
        console.log("0 Edotbox - templateUrlFunction()");
558
        var directiveName = tElement[0].tagName;
559
560
        directiveName = directiveName.toLowerCase();
561
        var templateURL = ThemeService.GetTemplateURL(directiveName);
562
        return templateURL;
563
    }
564
    function templateFunction(tElement, tAttrs) {
565
        var directiveName = tElement[0].tagName;
566
567
        directiveName = directiveName.toLowerCase();
568
        var tempate = "<div class='custom-transclude'></div>";
569
570
        return tempate;
571
    }
572
573
	return {
574
		require: ['?range', 'ngModel'],
575
		restrict: 'EA', //'EA', //Default in 1.3+
576
        transclude: true,
577
578
		// scope: [false | true | {...}]
579
		// false = use parent scope
580
		// true =  A new child scope that prototypically inherits from its parent
581
		// {} = create a isolate scope
582
		scope: true,
583
584
		controller: EditboxConstructor,
585
		controllerAs: 'editboxCtrl',
586
587
		//If both bindToController and scope are defined and have object hashes, bindToController overrides scope.
588
		 bindToController: {
589
		 	ngModel: '=',
590
			programId: '=',
591
			screenId: '=',
592
            SelectedToRecord: '='
593
		 },
594
       //templateUrl: templateUrlFunction,
595
		template: templateFunction,
596
		compile: function compile(tElement, tAttrs, transclude) {
597
		    return {
598
		        pre: function preLink(scope, iElement, iAttrs, controller) {
599
					if(Core.GetConfig().debugLog.DirectiveFlow)
600
						console.log("3 Edotbox - compile preLink()");
601
		        },
602
		        post: function postLink(scope, iElement, iAttrs, controller) {
603
					if(Core.GetConfig().debugLog.DirectiveFlow)
604
						console.log("4 Edotbox - compile postLink()");
605
606
607
                    transclude(scope, function(clone, scope) {
608
                        var programId = scope.programId;
609
                        var screenId = scope.screenId;
610
                        var pageviewTemplate = ''+
611
                        '<div class="modal pageview-modal">' +
612
                        '</div>' +
613
                        '<pageview class="pageview-popup-list-win" ng-model="editboxDataList" program-id="'+programId+'">'+
614
                                '<screen program-id="'+screenId+'"></screen>' +
615
                        '</pageview>';
616
617
                        var linkFn = $compile(pageviewTemplate);
618
                        var pageviewElement = linkFn(scope, function(e_pageview, s_pageview){
619
                        });
620
621
                        iElement.find('.custom-transclude').append(clone);
622
                        iElement.find('.custom-transclude').append(pageviewElement);  
623
                        iElement.find('div[data-confrim-btn-group]').show();
624
625
                    });
626
627
                    scope.ClosePageView();
628
		        }
629
		    }
630
		},
631
	};
632
}]);