angularjsmaskingangular-grid

Using NgMask in a AngularGrid table dynamically


I'd like to use NgMask in an angularGrid table to edit fields, but I don't know how.
The information from table cames from PHP and fields change depending on the search.
How could I implement it?
Link to NgMask: http://candreoliveira.github.io/bower_components/angular-mask/examples/index.html#/

The angularGrid code with a example:

var module = angular.module("example", ["angularGrid"]);
module.controller("exampleCtrl", function($scope, $timeout) {

var columnDefs = [
    {displayName: "Default String", field: "defaultString", width: 150,     editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler:     numberNewValueHandler},
    {displayName: "Upper Case Only", field: "upperCaseOnly", width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
    {displayName: "Number", field: 'number', width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
    {displayName: "Custom With Angular", field: "setAngular", width: 175, editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
    {displayName: "Custom No Angular", field: "setNoAngular", width: 175, cellRenderer: cellRendererLink, cellTemplate: '<a href="#">{{row.entity[col.field]}}</a>'

}];

var data = [
    {ID:111, defaultString: 'APPLE', upperCaseOnly: 'APPLE', number: 11, setAngular: 'AAA', setNoAngular: 'AAA'},
    {ID:222, defaultString: 'ORANGE', upperCaseOnly: 'ORANGE', number: 22, setAngular: 'BBB', setNoAngular: 'BBB'},
    {ID:333, defaultString: 'BANANA', upperCaseOnly: 'BANANA', number: 33, setAngular: 'CCC', setNoAngular: 'CCC'},
    {ID:444, defaultString: 'PEAR', upperCaseOnly: 'PEAR', number: 44, setAngular: 'DDD', setNoAngular: 'DDD'}
];

$scope.gridOptions = {
    columnDefs: columnDefs,
    rowData: data,
    enableCellEditOnFocus: true,
    enableSorting: true,
    enableFilter: true,
};

});

I dont want to use ui-grid or something, just angularGrid and some mask.


Solution

  • You could dynamically create the columnsDef and specify in the editableCellTemplate your required mask.

    The code works like this:

    1. Get the data from server
    2. Create fields from data keys
    3. Extend the keys with the mappingObj.
    4. Set mappedData to the scope, so ngGrid updates.

    You could probably also add a validation property to your data and use this to create the column definition.

    The uppercase mask is not working properly. I don't know what's wrong. If you enter some uppercase chars and then quickly a lowercase char it will be possible to enter.

    Please have a look at the demo below or in this plunkr.

    // main.js
    var app = angular.module('myApp', ['ngGrid', 'ngMask']);
    app.controller('MyCtrl', function($scope, $http) {
        /*$scope.myData = [{name: "Moroni", age: 50, personalId: '123-234-445'},
                         {name: "Tiancum", age: 43, personalId: '223-234-445'},
                         {name: "Jacob", age: 27,personalId: '323-234-445'},
                         {name: "Nephi", age: 29, personalId: '423-234-445'},
                         {name: "Enos", age: 34, personalId: '523-234-445'}];
        */
        $scope.myData = [];
        $scope.colDef = [];
        /*
        var columnDef = [{ field: 'name', displayName: 'First Name', width: 90 },
                         { field: 'age', width:50, cellClass: 'ageCell', headerClass: 'ageHeader', 
                           editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />' },
                           { field: 'personalId', displayName: 'ID', width: 150, editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'}];
          
        */        
        $http.jsonp('http://www.mocky.io/v2/559304993c82b23c10eea6a6?callback=JSON_CALLBACK').then(function(response){
          //'http://www.mocky.io/v2/5592fc513c82b22510eea699?callback=JSON_CALLBACK').then(function (response){      
          //$scope.colDef=response.data;//["ColumnName":data.something]    
          var data = response.data,
              keys = [],
              curKeys = '',
              mappedData,
              mappingObject = {
                /*
                  name: {
                  displayName: 'First Name',
                  width: 90
                },*/
                age: {
                  width: 50,
                  cellClass: 'ageCell',
                  headerClass: 'ageHeader',
                  editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />'
                },
                personalId: {
                  displayName: 'ID', 
                  width: 150, 
                  editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'
                },
                upperCaseOnly: {
                  displayName: 'uper case only property',
                  width: 100,
                  editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="A" repeat="10" limit="false" restrict="reject"/>'
                }
              };
              
          $scope.myData = data;
          
          data.forEach(function(row, index) {
            curKeys = Object.keys(row);
            console.log(curKeys);
            curKeys.forEach(function(key) {
              if (keys.indexOf(key) == -1)
                keys.push(key);  
            });
          });
          
          mappedData = keys.map(function(key){
            return angular.extend({field: key}, mappingObject[key]);
          });
          console.log(mappedData);
          $scope.colDef = mappedData;
        });
        
        $scope.filter = {filterText:''};
        $scope.gridOptions = {
          data: 'myData',
          enableFiltering: true,
        filterOptions: $scope.filter,
        showFilter: true,
        enableCellEditOnFocus: true, //enables the editor on a single click, if you use enableCellEdit: true you would have to doubleclick
            columnDefs: 'colDef'//columnDef
    
      };
      
      $scope.showRowCount = function() {
        console.log($scope.gridOptions.ngGrid.filteredRows.length);
      }
    });
    /*style.css*/
    .gridStyle {
        border: 1px solid rgb(212,212,212);
        width: 400px; 
        height: 300px
    }
    <!DOCTYPE html>
    <html ng-app="myApp">
        <head lang="en">
            <meta charset="utf-8">
            <title>Custom Plunker</title>  
            <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
            <link rel="stylesheet" type="text/css" href="style.css" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js"></script>
            <script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
            <script type="text/javascript" src="https://cdn.rawgit.com/candreoliveira/ngMask/master/dist/ngMask.js"></script>
            <script type="text/javascript" src="main.js"></script>
        </head>
        <body ng-controller="MyCtrl">
          <input ng-model="filter.filterText"/>
          <div class="gridStyle" ng-grid="gridOptions"></div>
            currently visible items: {{gridOptions.ngGrid.filteredRows.length}}
        </body>
    </html>