Click here to Skip to main content
15,114,081 members
Articles / Web Development / HTML
Article
Posted 14 Oct 2014

Stats

49.6K views
2.3K downloads
46 bookmarked

GridView Batch Editing in AngularJs

Rate me:
Please Sign up or sign in to vote.
4.81/5 (25 votes)
19 Oct 2014CPOL5 min read
This article provides you the simplified ways to implement batch editing (inline editing in gridview/repeater) using angular.js.

Introduction

Editing data in GridView is one of the common scenarios now a days. With 2 way data binding feature of AngularJs, it became extremely easy to write code for relatively, so called, complex operations like batch editing in GridView. This article provides you multiple approaches on how you can implement batch editing in GridView with just few lines of code. I have also given the sample to post the updated grid data to server using WebAPI in order to save it to database.

Please note that if you are looking for a built in AngularJs GridView tool, you will get many tools with a lot of features. This article provides a native approach with just few lines of code and will help you to fulfill your custom needs. The same approach can be applied to any kind of inline editing too. An example has also been provided for inline editing in non-tabular repeat items.

This article assumes that you know the basics of AngularJs.

Below is the screenshot of basic batch editing in the application:

Image 1

The below screenshot shows the second approach on batch editing:

Image 2

How It Works

Batch editing in AngularJs can be implemented by using 3 simple steps:

  1. Get grid data from the server using API in controller
  2. Populate data in table row a respective control instead of directly in table cell
  3. On click of submit, simply submit data to the server

Step 1

To fetch data from the server is easy. You can simply use $http/resource and assign the retrieved data to your scope variable.

Step 2

If you know about AngularJs and HTML, creating table/grid is quite easy. Just create the table element and use ng-repeat to populate all respective elements of each row. If you don’t want to use table, you can very well choose any other template.

See the below sample, where model/data is directly bound to HTML control. The beauty with AngularJs is that it updates the model automatically as soon as you change the data in your HTML control.

HTML
<table id="employeeEditTable" class="table table-bordered batch-edit">
                <colgroup>
                    <col width="60" />
                    <col width="140" />
                    <col width="300" />
                    <col width="100" />
                    <col width="100" />
                    <col width="100" />
                </colgroup>
                <tr>
                    <th>S. No.</th>
                    <th>Name</th>
                    <th>Address</th>
                    <th>Date of Birth</th>
                    <th>Salary</th>
                    <th>Country</th>
                </tr>
                <tr ng-repeat="employee in employees">
                    <td>{{$index + 1}}.</td>
                    <td><input type="text" ng-model="employee.Name" /></td>
                    <td><input type="text" ng-model="employee.Address" /></td>
                    <td>
                        <input type="text" ng-model="employee.BirthDate" 
                                           name="date" bs-datepicker />
                    </td>
                    <td class="text-right">
                        <input type="number" class="text-right" ng-model="employee.Salary" />
                    </td>
                    <td>
                        <select ng-options="c.Name for c in countries" 
                                ng-model="employee.Country" 
                            ng-init="setDropDown(employee);" 
                            ng-change="employee.CountryId = employee.Country.Id"></select>
                    </td>
                </tr>
            </table>

In some scenario, you might want the controls to be shown only while editing. This gives you flexibility to keep the display format different while displaying. To achieve this, I have set up two elements for each text in grid. One appears while displaying data and another, while editing. To achieve this, I have simply used ng-show directive and made mutually exclusive for both the controls like this:

  • Display Control: ng-show="!employee.edit.Name"
  • Edit Control: ng-show="employee.edit.Name"

The below code demonstrates this approach:

HTML
<tr ng-repeat="employee in employees">
                    <td>{{$index + 1}}.</td>
                    <td>
                        <div ng-show="!employee.edit.Name" 
                         ng-dblclick="employee.edit.Name = 
                         !employee.edit.Name">{{employee.Name}}</div>
                        <input type="text" ng-show="employee.edit.Name" 
                         ng-blur="employee.edit.Name = !employee.edit.Name" 
                         ng-model="employee.Name" />
                    </td>
                    <td>
                        <div ng-show="!employee.edit.Address" 
                         ng-dblclick="employee.edit.Address = 
                         !employee.edit.Address">{{employee.Address}}</div>
                        <input type="text" ng-show="employee.edit.Address" 
                         ng-blur="employee.edit.Address = !employee.edit.Address" 
                         ng-model="employee.Address" />
                    </td>
                    <td>
                        <div ng-show="!employee.edit.BirthDate" 
                         ng-dblclick="employee.edit.BirthDate = 
                         !employee.edit.BirthDate">{{employee.BirthDate | 
                         date:'dd MMM, yyyy'}}</div>
                        <input type="text" ng-show="employee.edit.BirthDate" 
                         ng-blur="employee.edit.BirthDate = !employee.edit.BirthDate" 
                         ng-model="employee.BirthDate" name="date" bs-datepicker />
                    </td>
                    <td class="text-right">
                        <div ng-show="!employee.edit.Salary" 
                         ng-dblclick="employee.edit.Salary = !employee.edit.Salary">
                         {{employee.Salary | currency}}</div>
                        <input type="number" ng-show="employee.edit.Salary" 
                         ng-blur="employee.edit.Salary = !employee.edit.Salary" 
                         ng-model="employee.Salary" />
                    </td>
                    <td>
                        <div ng-show="!employee.edit.Country" 
                         ng-dblclick="employee.edit.Country = 
                         !employee.edit.Country">{{employee.Country.Name}}</div>
                        <select ng-options="c.Name for c in countries" 
                         ng-show="employee.edit.Country" 
                         ng-blur="employee.edit.Country = !employee.edit.Country" 
                         ng-model="employee.Country" ng-init="setDropDown(employee);" 
                         ng-change="employee.CountryId = employee.Country.Id"></select>
                    </td>
                </tr>

You can toggle this display based on any event. In the sample, It is being toggled in double click event.

Step 3

When the data is changed in the HTML controls, the model updated automatically. So, in this step, you don’t need to worry about collecting data from the controls. Just send the model back to the server via an API. In my example, I have used $http to post the updated model back to the WebAPI.

Batch Editing in Non-Tabular Repeat Items

In many scenarios, we need to display the list of items as a block which repeats for each item. In such scenarios, gridview may not be the best fit for your batch editing needs. Below is the sample on how you can simply achieve this with a few lines of code:

HTML
<div class="rpt-item pull-left col-md-4" ng-class="{'bg-gray': $index % 2 != 0}" 
 ng-repeat="employee in employees">
    <h4>
        {{$index + 1}}.
        <span ng-show="!employee.edit.Name" ng-dblclick="employee.edit.Name = 
         !employee.edit.Name; $(this).next().focus();">{{employee.Name}}</span>
        <input type="text" ng-show="employee.edit.Name" ng-blur="employee.edit.Name = 
         !employee.edit.Name"
            ng-model="employee.Name" />
    </h4>

    <div ng-show="!employee.edit.BirthDate" ng-dblclick="employee.edit.BirthDate = 
     !employee.edit.BirthDate">
        <strong>DOB:</strong> {{employee.BirthDate | date: 'dd MMM, yyyy'}}
    </div>
    <input type="text" ng-show="employee.edit.BirthDate" 
     ng-blur="employee.edit.BirthDate = !employee.edit.BirthDate"
        ng-model="employee.BirthDate" name="date" bs-datepicker="bs-datepicker" />

    <div ng-show="!employee.edit.Salary" ng-dblclick="employee.edit.Salary = 
                                         !employee.edit.Salary">
        <strong>Salary:</strong> {{employee.Salary | currency}}
    </div>
    <input type="number" ng-show="employee.edit.Salary" 
                         ng-blur="employee.edit.Salary = !employee.edit.Salary"
        ng-model="employee.Salary" />

    <div ng-show="!employee.edit.Address" ng-dblclick="employee.edit.Address = 
                  !employee.edit.Address">
        <strong>Address:</strong> {{employee.Address}}
    </div>
    <input type="text" ng-show="employee.edit.Address" 
          ng-blur="employee.edit.Address = !employee.edit.Address"
        ng-model="employee.Address" />

    <div ng-show="!employee.edit.Country" ng-dblclick="employee.edit.Country = 
                      !employee.edit.Country">
        <strong>Country:</strong> {{employee.Country.Name}}
    </div>
    <select ng-options="c.Name for c in countries" ng-show="employee.edit.Country" 
                  ng-blur="employee.edit.Country = !employee.edit.Country"
        ng-model="employee.Country" ng-init="setDropDown(employee);" 
            ng-change="employee.CountryId = employee.Country.Id"></select>
</div>

The approach for batch edit is quite similar here as in tabular batch edit. The only difference is, instead of tr and td, div is used here. Below is the output for the same:

Image 3

About the Code

In this section, I have explained a bit about the way in which code is written. It will be helpful for those who are new to AngularJs.

The CSS Stuff

The best advantage of using a native approach to create a grid is, you can customize it to any extent you want. In our example, we have a textbox, dropdown and other controls inside table cell. For appearance, border is removed and width is set to 100%.

CSS
.batch-edit input, .batch-edit select{
    margin:-4px;
    border:none;
    width:100%;
}

The Controller

For all edit pages, single controller called employeeEditCtrl has been used with multiple views associated with it. This controller contains only three main functions. One to populate Employee and related data from the WebAPI. Another to set the drop-down list values based on retrieved data. And the third one is to submit the data on submit button click. For details, please have a look at the employeeEditCtrl.js file.

Misc

I have used factory to retrieve the data using $http but you can retrieve data in any way you want. angular-ui-router.js is used for routing and navigation. I haven't used any database for simplicity. Mock DB has been used to provide the data to UI.

Points of Interest

This article also acts as a sample for displaying data in grid using AngularJS. Moreover, the code also provides the sample on how to use Angular UI routing and use date-picker control in AngularJs.

Future Consideration

Due to lack of time, I have not provided the sample on inline editing for row-only. At a later point of time, I will also add sample on editing records as a pop-up. Moreover, in the current sample, I have added only the most commonly used editing controls like textbox, number, datetime and dropdown. In future, I will add some complex controls also.

History

  • 15th October, 2014: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Anurag Gandhi
Architect
India India
Anurag Gandhi is a Freelance Developer and Consultant, Architect, Blogger, Speaker, and Ex Microsoft Employee. He is passionate about programming.
He is extensively involved in Asp.Net Core, MVC/Web API, Node/Express, Microsoft Azure/Cloud, web application hosting/architecture, Angular, AngularJs, design, and development. His languages of choice are C#, Node/Express, JavaScript, Asp .NET MVC, Asp, C, C++. He is familiar with many other programming languages as well. He mostly works with MS SQL Server as the preferred database and has worked with Redis, MySQL, Oracle, MS Access, etc. also.
He is active in programming communities and loves to share the knowledge with others whenever he gets the time for it.
He is also a passionate chess player.
Linked in Profile: https://in.linkedin.com/in/anuraggandhi
He can be contacted at soft.gandhi@gmail.com

Comments and Discussions

 
QuestionHow to do in-line edit Pin
Tridip Bhattacharjee27-Oct-16 23:01
professionalTridip Bhattacharjee27-Oct-16 23:01 
GeneralMy vote of 5 Pin
SIVA RAMAKUMAR N.V15-Nov-15 23:03
MemberSIVA RAMAKUMAR N.V15-Nov-15 23:03 
Questionb Pin
piotr piechocki20-Oct-14 7:48
Memberpiotr piechocki20-Oct-14 7:48 
GeneralMy vote of 5 Pin
amitthk19-Oct-14 21:15
professionalamitthk19-Oct-14 21:15 
GeneralRe: My vote of 5 Pin
Anurag Gandhi19-Oct-14 21:48
professionalAnurag Gandhi19-Oct-14 21:48 
GeneralMy vote of 5 Pin
E. Scott McFadden16-Oct-14 8:00
professionalE. Scott McFadden16-Oct-14 8:00 
Very nicely done. Alternatives are always welcome and dependency on canned tools often limit your creativity and abilities.
GeneralRe: My vote of 5 Pin
Anurag Gandhi17-Oct-14 2:50
professionalAnurag Gandhi17-Oct-14 2:50 
QuestionA couple of odd items... Pin
Dewey15-Oct-14 1:38
MemberDewey15-Oct-14 1:38 
AnswerRe: A couple of odd items... Pin
Anurag Gandhi15-Oct-14 9:05
professionalAnurag Gandhi15-Oct-14 9:05 
Questionangular-ui-grid Pin
nbarbosa14-Oct-14 23:32
Membernbarbosa14-Oct-14 23:32 
AnswerRe: angular-ui-grid Pin
Anurag Gandhi15-Oct-14 9:12
professionalAnurag Gandhi15-Oct-14 9:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.