Click here to Skip to main content
13,594,670 members
Click here to Skip to main content
Add your own
alternative version

Stats

38.9K views
2.1K downloads
45 bookmarked
Posted 14 Oct 2014
Licenced CPOL

GridView Batch Editing in AngularJs

, 19 Oct 2014
Rate this:
Please Sign up or sign in to vote.
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 scenario 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. 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:

The below screenshot shows the 2nd approach on batch editing:

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 element 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, it updates the model automatically as soon as you change the data in your html control.

<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 demonstrate this approach:

<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 and 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 scnarios, 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:

<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 sued here. Below is the output for the same:

About the code

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

The CSS Stuff

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

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

The Controller

For all edit page, 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 by any way you want. angular-ui-router.js is used for routing and navigation. I havn'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 angular js. 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 later point of time, I will also add sample on editing records as a pop-up. Moreover, in current sample, I have added only most commonly used editing controls like textbox, number, datetime and dropdown. In future, I will add some complex controls also.

History

15 Oct, 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 Developer, Consultant, Architect, Blogger, Speaker and a Microsoft Employee. He is passionate about programming.
He is extensively involved in Asp.Net Core, MVC/Web API, 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

Disclaimer: Any posts, article, content present in this website is my personal opinion based on best of my knowledge and experience. None of the content provided by me should be considered as official communication/opinion or my Employer.

You may also be interested in...

Comments and Discussions

 
QuestionHow to do in-line edit Pin
Tridip Bhattacharjee27-Oct-16 22:01
professionalTridip Bhattacharjee27-Oct-16 22:01 
GeneralMy vote of 5 Pin
SIVA RAMAKUMAR N.V15-Nov-15 22:03
memberSIVA RAMAKUMAR N.V15-Nov-15 22:03 
Questionb Pin
piotr piechocki20-Oct-14 6:48
memberpiotr piechocki20-Oct-14 6:48 
GeneralMy vote of 5 Pin
amitthk19-Oct-14 20:15
memberamitthk19-Oct-14 20:15 
GeneralRe: My vote of 5 Pin
Anurag Gandhi19-Oct-14 20:48
professionalAnurag Gandhi19-Oct-14 20:48 
GeneralMy vote of 5 Pin
E. Scott McFadden16-Oct-14 7:00
professionalE. Scott McFadden16-Oct-14 7:00 
GeneralRe: My vote of 5 Pin
Anurag Gandhi17-Oct-14 1:50
professionalAnurag Gandhi17-Oct-14 1:50 
QuestionA couple of odd items... Pin
Dewey15-Oct-14 0:38
memberDewey15-Oct-14 0:38 
AnswerRe: A couple of odd items... Pin
Anurag Gandhi15-Oct-14 8:05
professionalAnurag Gandhi15-Oct-14 8:05 
Questionangular-ui-grid Pin
nbarbosa14-Oct-14 22:32
membernbarbosa14-Oct-14 22:32 
AnswerRe: angular-ui-grid Pin
Anurag Gandhi15-Oct-14 8:12
professionalAnurag Gandhi15-Oct-14 8: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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.180621.3 | Last Updated 20 Oct 2014
Article Copyright 2014 by Anurag Gandhi
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid