Monday, November 7, 2016

ngTable - CRUD operation in Table/Grid

To demonstrate CRUD operations in ngTable I will be using an example of the Employee portal in all my posts. This Employee portal has capabilities of adding, viewing, editing and deleting employee skill details. 



In this section we will be looking into the editable view of the employee page. This page has following functionalities:



- Option to add the new skill row(s) in the employee skill grid. (Add New Skill button below the grid)

- Option to remove exiting skill row. (Delete button in each row)

- Option to save employee skill data. (Save button below the grid)



- Filter skill name list based on skill type selected.

When skill type is Technical, the Skill name cell gets filtered with data of type 'Technical'











- When skill type is 'Domain', skill name cell gets filtered with data of type 'Domain'.



- When skill type is 'Personal', skill name cell gets filtered with the data of type 'Personal'.





- Rating column has the option to select ratings from 1 to 5.

- Is Primary is the check-box column to say if the skill is primary or secondary. 







I will be dividing employee edit page in two parts. 
  • The first part talks bout the basic requirements of the editable view of the employee page and will cover the UI part of it along with basic functionalities like drop-down box data filtering and dependency between the controls. 
  • The second part is going to cover the core functionalities (add, remove, save) of the employee edit page.
In the previous post we had seen the employee and skill models. In this section I am providing the skeleton of  the web APIs and service to get the required data from the database. (As stated in the previous post the full source code of this application will be provided at the end of the series).

 [Route("api/[controller]")]
    public class EmployeeController : BaseController
    {
        private readonly JsonSerializerSettings _serializerSettings;

        IEmployeeServices _service;

        public EmployeeController(IEmployeeServices service)
        {
            _service = service;
            _serializerSettings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
        }

        // GET api/values
        [HttpGet]      
        public IEnumerable<Employee> Get()
        {
            return _service.GetAll();
        }

        // GET api/values/1
        [HttpGet("{id}")]
        public Employee Get(int id)
        {
            return _service.Get(id);
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody]Employee Employee)
        {
            _service.Add(Employee);
        }

        [HttpPut]
        public void Put([FromBody]Employee Employee)
        {
            _service.Update(Employee);
        }

        // DELETE api/values/1
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
            _service.Delete(id);
        }

    }

  [Route("api/[controller]")]
    public class SkillController : BaseController
    {
        private readonly JsonSerializerSettings _serializerSettings;

        ISkillServices _service;

        public SkillController(ISkillServices service)
        {
            _service = service;
            _serializerSettings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
        }

        // GET api/values
        [HttpGet]
        //[Authorize(Policy = "Admin")]
        public IEnumerable<Skill> Get()
        {
            return _service.GetAll();
        }

        // GET api/values/1
        [HttpGet("{id}")]
        public Skill Get(int id)
        {
            return _service.Get(id);
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody]Skill skill)
        {
            _service.Add(skill);
        }

        [HttpPut]
        public void Put([FromBody]Skill skill)
        {
            _service.Update(skill);
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
            _service.Delete(id);
        }
    }

Now lets build a view to display the employee details in AngularJS application. Below are the steps you need to follow:
  • Add ngTable module to where the app module is being declared.
                 var myApp = angular.module("myApp", ["ngTable"])
  • In the HTML file (partial view) add the following code where you want your employee skill table to appear. We have used Text boxes, drop-down boxes and the checkbox controls in the view to make the screen editable.  
            <div>
               <table ng-table="employeeSkills">
                  <tr ng-repeat="skill in $data">
                    <td data-title="'#'">{{$index + 1}}</td>
                    <td data-title="'Skill Type'" >
         <select name="skillType_{{$index +1}}" id="skillType_{{$index +1}}" ng-model="skill.skill.type" 
                                    ng-options="type.name for type in skillTypes track by type.id" 
                                    required ng-change="skillTypeChanged(skill.skill, $index)"></select>
                     </td>
                     <td data-title="'Skill Name'" >
<select name="skillName_{{$index +1}}" id="skillName_{{$index +1}}" ng-model="skill.skill"                                                                
                                ng-options="skillName.skillName for skillName in (availableSkills | filter:{type: {id: skill.skill.type.id}})
                                 track by skillName.id"   ></select>
                     </td>

                     <td data-title="'Rating '" >
                         <span>{{skill.rating }}</span>
                     </td>

                    <td data-title="'Is Primary'" >

                   <input type="checkbox" ng-model="skill.isPrimary" value="{{skill.isPrimary}}" />

                   </td>
                  <td>
                        <button  ng-click="removeSkill(skill)">   Delete  </button>

                    </td>

                </tr>

             </table>
        <table class="table">            
            <tr>
                <td>
                   <button  ng-click="addNewSkill()">Add New Skill</button>                   
                </td>
                <td>
                    <button  ng-click="save()" >Save</button>
                </td>              
            </tr>

        </table>

          </div
  • In the controller JavaScript file add the below code: (The employeeSkills are being hard coded here but in actual scenario a service call need to be made to get the details from database, I will be uploading the full source code at the end of the series so till then please bear with the hard coded values) .The object count of the object ngTableParams is set to empty array to make sure that pagination is disabled. The object dataset of the object ngTableParams is set with the employee skill data.  
           myApp.controller('editEmployeeSkillController', ['ngTableParams', '$scope', 
                  function (ngTableParams, $scope) {
                     $scope.skillTypes =  [{id: 1, name: 'Technical'},
                                                        {id: 2, name: 'Domain'},
                                                        {id: 3, name: 'Personal'}];
                                                   
                    var skills = [{type: {id: 1, name: 'Technical'}, name: 'Java', id: 1},
                       {type: {id: 1, name: 'Technical'}, name: '.NET', id: 2},
                       {type: {id: 1, name: 'Technical'}, name: 'AngularJS', id: 3},
                       {type: {id: 1, name: 'Domain'}, name: 'LifeScience', id: 4},
                       {type: {id: 2, name: 'Domain'}, name: 'Media', id: 5},
                       {type: {id: 3, name: 'Personal'}, name: 'Communication', id: 6}];
            
        //These two lines are needed to create the dependency between skilltype and skill drop-down boxes          
        $scope.availableSkills = angular.copy(skills);
        $scope.originalSkills angular.copy(skills);

                        var employee = {id: 1, firstName: 'Pratibha', lastName: 'Hyanki', employeeId:'xxx',
                              skills: [{skill: {type: {id: 1, name: 'Technical'}, name: '.Net', id: 2} isPrimary: true rating:5 id:1},
                                   { skill: {type: {id: 2, name: 'Domain'}, name: Media, id: 5} isPrimary:false, rating:3 id:2},          
                     { skill: {type: {id: 3, name: 'Personal'}, name: 'Communication', id: 6} isPrimary:true rating:1 id:3},
                                   { skill: {type: {id: 1, name: 'Technical'}, name: 'AngularJS', id: 3}, isPrimary: trye rating:2  id:4}
                                  ]}; 

                       $scope.employeeSkills= new ngTableParams({}, {
                           dataset: employee.skills,
                           counts: []
                   });

          $scope.skillTypeChanged = function (skill, index) {
              $scope.availableSkills = angular.copy($scope.originalSkills );
              for (var i = 0; i < $scope.availableSkills.length; i++) {
                     if (skill.type.id == $scope.availableSkills[i].type.id) {
                         $scope.employeeSkills[index].skill = angular.copy($scope.availableSkills[i]);
                              break;
                     }
               }              
               $scope.availableSkills = angular.copy($scope.originalSkills );
          };  

       $scope.removeSkill = function (row) {
              var test = row;
              for (var i = 0; i < $scope.employeeSkills.length; i++) {
                  if (row === $scope.employeeSkills[i]) {
                        $scope.employeeSkills.splice(i, 1);
                           return;
                   }
               }
          };

      $scope.addNewSkill = function () {
           var row = { skill: "" id: "" isPrimary: false, rating: "" };
           $scope.employeeSkills.push(row);
      };

      $scope.save = function () {
           // code to save employee skill data
       };
         }]);

No comments:

Post a Comment