Total Pageviews

Showing posts with label AngularJS. Show all posts
Showing posts with label AngularJS. Show all posts

2018/05/11

[Angular] How to add serial number in ng-grid

Problem
If I would like to add serial number in ng-grid, how to do it?
I would like to implement in client side instead of server side.

The column configuration in ng-grid is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  $scope.tab4.synonymCols  = [{
            field : 'value',
            displayName : 'value',
            cellClass : 'text-left',
            width : '25%'
        }, {
            field : 'synonyms',
            displayName : 'synonyms',
            cellClass : 'text-left',
            width : '70%'
        } ];


How-To
The updated column configuration in ng-grid is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
       $scope.tab4.synonymCols  = [{
            field : 'seq',
            displayName : 'no',
            cellClass : 'text-left',
            width : '5%',
            cellTemplate: '<div class="ngCellText ng-scope col1 colt1" ng-class="col.colIndex()"><span ng-cell-text="">{{row.rowIndex + 1}}</span></div>'
        }, {
            field : 'value',
            displayName : 'value',
            cellClass : 'text-left',
            width : '25%'
        }, {
            field : 'synonyms',
            displayName : 'synonyms',
            cellClass : 'text-left',
            width : '70%'
        } ];





2018/05/05

[Angular] How to show data via ng-repeat in horizontal ?

Problem
Assume I have an String array.
    $scope.names = ['朴道京', '吳海英', '李振尚', '朴秀京', '朴勳'];

I would like to show these names in HTML page via ng-repeat, here has the code snippet:

    <div class="row">
      <div class="col-sm-offset-1 col-sm-4">
         <div data-ng-repeat="name in names">
               <span>{{name}}</span>
         </div>
      </div>
    </div>

But it display in vertical way, how to display in horizontal way?


How-To
Use span instead of div, the updated code snippet are as bellows:
   <div class="row">
     <div class="col-sm-offset-1 col-sm-4">
        <span data-ng-repeat="name in names">
              <span>{{name}}</span>
        </span>
     </div>
   </div>

Here has the screenshot:




2018/04/08

[Angular] [Bootbox] File Upload Example

Problem
How to implement file upload function via Angular and Bootbox?

How-To

Here has sample code.
Code snippet in JavaScript:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    $scope.importJson = function() {
     $scope.attachment = undefined;
     
     bootbox.dialog({
      message: "<input class='form-control' type='file' id='jsonFile' name='jsonFile' /> ",
      title: '匯入 JSON',
      buttons: {
       upload: {
           label: '上傳',
           callback: function() {
               cResource().uploadFile({
                   url: '/api/projects/' + $scope.project.id + '/importJSON',
                   file: $scope.attachment
               }).success(function(res, status, headers, config) {
                   cAlerter.success('上傳成功');
               }).error(function(res, status, headers, config) {
               });
           }
       },
       cancel: {
             label: '取消'
       }
      }
     });
     var jsonFile = document.getElementById("jsonFile");
     jsonFile.addEventListener("change", function (e) {
         $scope.attachment = this.files[0];
     }, false);
    };


Code snippet in controller class:

1
2
3
4
5
6
    @Transactional
    @PostMapping(value = "/{projectId}/importJSON", produces = MediaType.APPLICATION_JSON_VALUE)
    public void importJSON(@PathVariable Integer projectId,
      @RequestParam(value = "file") MultipartFile jsonFile) throws IOException {
  
    }





2017/11/06

[Angular] How to implement pagination in ng-grid

Problem
How to implement pagination in ng-grid?

How-to

Here has code snippet:

1. enable pagination function, and set pagingOptions & totalServerItems in ng-grid

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    $scope.gridCols  = [ 
        {  field : 'no',              displayName : '序號',         width : '5%',   cellClass : 'text-right' }, 
        {  field : 'exceptionGroup',  displayName : '異常類別',     width : '15%',  cellClass : 'text-left' }, 
        {  field : 'exceptionDesc',   displayName : '異常類別說明', width : '25%',  cellClass : 'text-left' }, 
        {  field : 'deptName',        displayName : '部門別',       width : '15%',  cellClass : 'text-left' }, 
        {  field : 'userName',        displayName : '通報人員姓名',  width : '10%',  cellClass : 'text-left' }, 
        {  field : 'emailAddr',       displayName : '收件Email',    width : '30%',  cellClass : 'text-left' } 
    ];
        
    $scope.dataGrid = {
        multiSelect : false,
        data : 'itemData',
        columnDefs : 'gridCols',
        enableColumnResize : true,
        keepLastSelected : false,
        enablePaging : true,
        showFooter : true,
        pagingOptions : $scope.pagingOptions,
        totalServerItems : "totalServerItems"
    };


2. set initial values when page loaded
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    // query result (current page)
    $scope.itemData = [];
    // query result (complete data)
    $scope.resultData = [];     
        
    // set page sizes, page size and current page
    $scope.pagingOptions = {
        pageSizes : [ 25, 50, 100 ],
        pageSize : 25,
        currentPage : 1
    };
    // total items are on the server (initial value)
    $scope.totalServerItems = 0;        

3. set data to current page
1
2
3
4
5
6
7
8
9
    // set paging data
    $scope.setPagingData = function(data, page, pageSize) {
        var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
        $scope.itemData = pagedData;
        $scope.totalServerItems = data.length;
        if (!$scope.$$phase) {
            $scope.$apply();
        }
    };


4. Registers a listener callback to be executed whenever the pagingOptions changes.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    // Registers a listener callback to be executed whenever the pagingOptions changes.
    $scope.$watch('pagingOptions', function(newVal, oldVal) {
        // if page size change, then set current page to 1 and set paging data
        if(newVal.pageSize !== oldVal.pageSize) {
            $scope.pagingOptions.currentPage = 1;
            $scope.setPagingData($scope.resultData, $scope.pagingOptions.currentPage, newVal.pageSize);
        }
   
        // if current page change, then set paging data
        if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
            $scope.setPagingData($scope.resultData, newVal.currentPage, newVal.pageSize);
        }
    }, true);     


Screenshot is as bellows:



Reference

[1] https://angular-ui.github.io/ui-grid/

2017/10/09

[AngularJS] How to resize text width on demand ?

Problem
I am using AngularJS to implement web application. 

You can find an URL text filed in the web page. 

The requirement is the width of the URL text field will resize based on the text length which key in by end user. 

How to do it?


How-To
You can make good use of ng-keyup and ng-style to fulfill this requirement.
Using ng-keyup to calculate the length of text and using ng-style to set width at the same time.

The HTML code snippet looks like:
1
2
3
4
5
6
7
8
    <div class="row">
      <div class="form-group col-sm-3">
       <!- ignore -->        
        <label for="url" class="control-label label-width-5">URL</label> 
        <input type="text" id="url" name="url" class="form-control" data-ng-model="model.url" 
               data-ng-keyup="keyInUrl()" data-ng-style="{'width':urlWidth}">
      </div>
    </div>


The JavaScript code snippet are the following:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
  // set the initial value for url width
  $scope.urlWidth = 200;    

  // calculate width at runtime
  $scope.keyInUrl = function() {
   var url = $scope.model.url;
   if (!isEmptyOrUndefined($scope.model.url)){
    var width = ((url.length + 1) * 9);
       console.log('width = ' + width);
       if(width > 200) {
        $scope.urlWidth = width;
       } else  {
        $scope.urlWidth = 200;
       }
   }
  }


Demo:


2017/10/06

How to prevent JavaScript cache in Chrome during development ?

Problem
I am working on a web application project, and using Google Chrome as my browser to do development and test.

I face a JavaScript cache problem during my development, the JavaScript file which I updated does not take effect. It's very annoying, how do I do?


How-To
Open "incognito window" (無痕視窗) can overcome this annoying problem. In incognito mode (無痕模式), you will retrieve up-to-date JavaScript file after page reloaded.


2016/06/08

[AngularJS] How to add tooltips in ng-grid

Problem
I implemented a data grid by ng-grid as bellows:


The problem is if the length of data is larger than the width of column, it will show ... then ignore the rest of information. Our customer requests to show complete information in tooltips as he/she move cursor on it.

The code snippet of ng-grid looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$scope.gridCols  = [ 
 {
     field : 'sourceName',
     width : '10%',
     displayName : '來源系統',
     cellClass : 'text-left'
 }, {
     field : 'policyNumber',
     width : '10%',
     displayName : '保單號碼',
     cellClass : 'text-left'
 },{
     field : 'exeMsg',
     width : '65%',
     displayName : '執行訊息',
     cellClass : 'text-left'
 },{
     field : 'exeTime',
     width : '15%',
     displayName : '執行時間',
     cellFilter : "date:'yyyy-MM-dd HH:mm:ss'",
     cellClass : 'text-left'
 }];
 
 $scope.dataGrid = {
     multiSelect : false,
     data : 'itemData',
     columnDefs : 'gridCols',
     enableColumnResize: true,
     enableRowSelection: true,
     rowHeight : 40
 };


How-to
There has two steps to fulfill this requirement.
Step 1. add css in HTML page
1
2
3
4
5
6
7
   <style type="text/css">
    .tooltip-inner {
      text-align: left;
      white-space: pre-wrap;
      max-width: none;
    }
    </style>

Step 2. Modify the ng-grid, and add cellTemplate to show complete information
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 var exeMsgCellTemplate='<span tooltip="{{row.entity.exeMsg}}" tooltip-append-to-body="true" tooltip-trigger:"focus"><div style="vertical-align : middle;"  class="ngCellText">{{row.entity.exeMsg}}</div></span>';
 var exeTimeCellTemplate='<span tooltip="{{row.entity.exeTime|date:\'yyyy-MM-dd HH:mm:ss\'}}" tooltip-append-to-body="true" tooltip-trigger:"focus"><div style="vertical-align : middle;"  class="ngCellText">{{row.entity.exeTime|date:\'yyyy-MM-dd HH:mm:ss\'}}</div></span>';
               
 $scope.gridCols  = [ 
 {
     field : 'sourceName',
     width : '10%',
     displayName : '來源系統',
     cellClass : 'text-left'
 }, {
     field : 'policyNumber',
     width : '10%',
     displayName : '保單號碼',
     cellClass : 'text-left'
 },{
     field : 'exeMsg',
     width : '65%',
     displayName : '執行訊息',
     cellClass : 'text-left',
     cellTemplate : exeMsgCellTemplate
 },{
     field : 'exeTime',
     width : '15%',
     displayName : '執行時間',
     cellFilter : "date:'yyyy-MM-dd HH:mm:ss'",
     cellClass : 'text-left',
     cellTemplate : exeTimeCellTemplate
 }];
 
 $scope.dataGrid = {
     multiSelect : false,
     data : 'itemData',
     columnDefs : 'gridCols',
     enableColumnResize: true,
     enableRowSelection: true,
     rowHeight : 40
 };



Check the result:





Reference
[1] http://www.w3schools.com/cssref/pr_text_white-space.asp



2016/05/09

[AngularJS] How to implement ng-grid with dynamic cell height

Problem
I implement a data grid by means of AngularJs ng-grid.
But if the data will not be display completely if its too long.
The screenshot looks like this:


JavaScript code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
       $scope.gridCols  = [ 
        {
            field : 'serviceType',
            width : '10%',
            displayName : '整合服務別',
            cellClass : 'text-left',
            cellFilter : 'serviceTypeFilter'
        },{
            field : 'sourceName',
            width : '9%',
            displayName : '來源系統',
            cellClass : 'text-left'
        }, {
            field : 'userId',
            width : '7%',
            displayName : '執行人',
            cellClass : 'text-left'
        }, {
            field : 'exeResult',
            width : '7%',
            displayName : '執行結果',
            cellClass : 'text-left',
            cellFilter : 'exeResultFilter'
        }, {
            field : 'policyNumber',
            width : '10%',
            displayName : '保單號碼',
            cellClass : 'text-left'
        },{
            field : 'exeMsg',
            width : '40%',
            displayName : '執行訊息',
            cellClass : 'text-left'
        },{
            field : 'exeTime',
            width : '16%',
            displayName : '執行時間',
            cellFilter : "date:'yyyy-MM-dd HH:mm:ss'",
            cellClass : 'text-left'
        }];
        
        $scope.dataGrid = {
            multiSelect : false,
            data : 'itemData',
            columnDefs : 'gridCols',
            enableColumnResize: true,
            enableRowSelection: false,
            rowHeight : 40
        };
        
    });

HTML code snippet:
1
2
3
4
  <div class="row">
    <div class="grid-style text-center" data-ng-grid="dataGrid"
         style="display: inline-block; height: 300px; width: 100%;"></div>
  </div>


How-to
The solution is pretty simple. You just need to overwrite CSS, 
It looks like this:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  <style type="text/css">
    .ngCell  {
      display : table-cell;
      height: auto !important;
      overflow:visible;
      position: static;
    }
    .ngRow {
      display : table-row;
      height: auto !important;
      position: static;
    }
    .ngCellText{
      height: auto !important;
      white-space: normal;
      overflow:visible;
    }
  </style>

Check the result:

Reference
[1] https://github.com/angular-ui/ui-grid/issues/1523

2016/01/27

[AngularJS] How to set selected row and set highlight in ng-gird pragmatically?

Requirement
After I create a new record, the program should refresh the data grid and set selected item and highlighted the selected item.


After I update an existing record, the program should refresh the data grid and set selected item and highlighted the selected item.


Here has the code snippet regarding ng-grid:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
        $scope.itemGridCols  = [ 
            {
               field : 'accountYr',
               displayName : '年度',
               cellClass: 'text-left',
               width: '150px'
            }, 
            {
               field : 'orgType',
               displayName : 'orgType',
               cellClass: 'text-left',
               visible : false
            },
            {
                field : 'orgTypeName',
                displayName : '機關類別',
                cellClass: 'text-left',
                width: '250px'
             },
             {
                field : 'masterAge',
                displayName : 'masterAge',
                cellClass: 'text-left',
                visible : false
             },
             {
                field : 'masterAgeName',
                displayName : '主管機關名稱',
                cellClass: 'text-left',
                width: '250px'
             },
             {
                field : 'ageName',
                displayName : '機關名稱',
                cellClass: 'text-left',
                width: '250px'
              },
             {
                field : 'age',
                displayName : '機關代號',
                cellClass: 'text-left',
                width: '250px'
             }
          ];
        
        $scope.itemGrid = {
                keepLastSelected: false,
                selectedItems: $scope.selectedItem,
                multiSelect : false,
                data : 'itemData',
                columnDefs : 'itemGridCols',
                enableColumnResize: true,
                afterSelectionChange : function(rowItem){ 
                    if (rowItem.selected) {
                        $scope.model.accountYr = rowItem.entity.accountYr;
                        $scope.model.orgType   = rowItem.entity.orgType;
                        $scope.model.masterAge = rowItem.entity.masterAge;
                        $scope.model.ageNm     = rowItem.entity.ageName;
                        $scope.model.age       = rowItem.entity.age;
                    }else{
                        $scope.model = {};
                        
                        $scope.model.accountYr = getCurrentYear()-1;
                    }
                }
        };

create and update button code snippet is as following:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
        $scope.createBtn = function(){
            // 驗證表單
               if (!$scope.validate(this.dbm039eForm)) {
                   return;
               }
               
               dbmService.execute("rest/create", $scope.model)
                   .then(function(response) { 
                       $scope.itemData = response;
                       cAlerter.info('新增成功');
                   }
               );
          };
          
          $scope.saveBtn = function(){
              dbmService.execute("rest/save", $scope.model)
                  .then(function(response) { 
                      $scope.itemData = response;                    
                      cAlerter.info('修改成功');
                  }
              );
          };

How To
Utilize $scope.itemGrid.selectRow(index, true); to fulfill this requirement, and remember to move this code in $timeout:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
         $scope.setSelectedRow = function(itemData, selectedItem){
              var index = 0;
              var keepGoing = true;

              angular.forEach(itemData, function(value, key) {
                  if(keepGoing){
                      if(value.accountYr == selectedItem.accountYr && 
                         value.orgType == selectedItem.orgType  && 
                         value.age == selectedItem.age){
                           index = key;
                           keepGoing = false;
                      }
                  }
              });
              
              // remember to set select row in $timeout, or it will NOT work
              $timeout(function () {
                  $scope.itemGrid.selectRow(index, true);
              },1 );
              
          };
    
        $scope.createBtn = function(){
            // 驗證表單
               if (!$scope.validate(this.dbm039eForm)) {
                   return;
               }
               
               dbmService.execute("rest/create", $scope.model)
                   .then(function(response) { 
                       $scope.itemData = response;
                       
                       //set model to selectedItem
                       $scope.selectedItem[0] = $scope.model;
                       //set selected row
                       $scope.setSelectedRow($scope.itemData, $scope.selectedItem[0]);
                       
                       cAlerter.info('新增成功');
                   }
               );
          };
          
          $scope.saveBtn = function(){
              if($scope.selectedItem.length == 0){
                  cAlerter.fatal('請選擇要修改的資料');
                  return;
              }
              
              dbmService.execute("rest/save", $scope.model)
                  .then(function(response) { 
                      $scope.itemData = response;
                      
                      // set selected row
                      $scope.setSelectedRow($scope.itemData, $scope.selectedItem[0]);
                      
                      cAlerter.info('修改成功');
                  }
              );
          };
          
         


Reference
[1] https://github.com/angular-ui/ui-grid/issues/2267

2015/11/19

[AngularJS] Round to at most 2 decimal places in ng-grid CellFilter

Problem
I utilize ng-grid to implement the grid as bellows:

The value of 利率 has 4 decimal places, customer ask to change to 2 decimal places.
The ng-grid definition is as following:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 $scope.itemGrid = {
            multiSelect : false,
   data : 'itemData',
            showFooter : false,
            keepLastSelected: false,
   enableColumnResize: true,
            columnDefs : [ {
                field : 'fundName',
                displayName : '借入基金專戶',
                width : '21%',
                cellClass : "text-left",
                cellFilter:'dbm035eFundFilter:row.entity.toFundName : row.entity.debtType=="B"'
            }, {
                field : 'toFundName',
                displayName : '借出基金專戶',
                width : '21%',
                cellClass : "text-left",
                cellFilter:'dbm035eFundFilter:row.entity.fundName : row.entity.debtType=="B"'
            }, {
                field : 'debtDateB',
                displayName : '調借起日',
                width : '10%',
                cellClass : "text-left",
                cellFilter:"dbm035eToStringFilter|dateFilter" 
            }, {
                field : "debtDateE",
                displayName : "調借迄日",
                width : '10%',
                cellClass : "text-left",
                cellFilter:"dbm035eToStringFilter|dateFilter" 
            }, {
                field : "debtAmt",
                displayName : "調借金額",
                width : '10%',
                cellClass : "text-right",
                cellFilter:"dbm035eAmountFilter | number"
            }, {
                field : "debtRate",
                displayName : "利率",
                width : '8%',
                cellClass : "text-right"
            }, {
                field : "remark",
                displayName : "備註",
                width : '20%',
                cellClass : "text-left"
            }
   //....
 }];


How-To
Step 1. Create a cellFilter to debtRate field
1
2
3
4
5
    app.filter('dbm035eRateFilter', function() {
        return function(input) {
            return null==input?null:(Math.round(input * 100)/100);
        };
    });

Step 2. Add this cellFilter to debtRate field
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 $scope.itemGrid = {
            multiSelect : false,
   data : 'itemData',
            showFooter : false,
            keepLastSelected: false,
   enableColumnResize: true,
            columnDefs : [ {
                field : 'fundName',
                displayName : '借入基金專戶',
                width : '21%',
                cellClass : "text-left",
                cellFilter:'dbm035eFundFilter:row.entity.toFundName : row.entity.debtType=="B"'
            }, {
                field : 'toFundName',
                displayName : '借出基金專戶',
                width : '21%',
                cellClass : "text-left",
                cellFilter:'dbm035eFundFilter:row.entity.fundName : row.entity.debtType=="B"'
            }, {
                field : 'debtDateB',
                displayName : '調借起日',
                width : '10%',
                cellClass : "text-left",
                cellFilter:"dbm035eToStringFilter|dateFilter" 
            }, {
                field : "debtDateE",
                displayName : "調借迄日",
                width : '10%',
                cellClass : "text-left",
                cellFilter:"dbm035eToStringFilter|dateFilter" 
            }, {
                field : "debtAmt",
                displayName : "調借金額",
                width : '10%',
                cellClass : "text-right",
                cellFilter:"dbm035eAmountFilter | number"
            }, {
                field : "debtRate",
                displayName : "利率",
                width : '8%',
                cellClass : "text-right",
                cellFilter:"dbm035eRateFilter" 
            }, {
                field : "remark",
                displayName : "備註",
                width : '20%',
                cellClass : "text-left"
            }
   //....
 }];

Check the result


Reference
[1] http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript