Introduction

In this article, I am presenting a different way to look at EditItemTemplate, using which user navigation for editing is reduced and … it looks very different (see screen shots) than regular implementation of GridView.

Background

Few days ago, I got an assignment. I needed to add a few new fields in a DataView and let the user edit those (along with all existing fields).

I thought it was a very small change, just new fields in ItemTemplate and EditItemTemplate and perform few basic validations on it using JavaScript and I'm done! I was dead wrong. As soon as I modified EditItemTemplate, a Horizontal scrollbar started to appear on the page. One of the UI rules in our entire application on minimum resolution 1024x678 and with default font size, is that no Horizontal Scrollbar should appear on any of the pages. So I started thinking and creating new concepts. Here we had a few options.

Various Options

Option 1

Create a new page for edit. When user clicks on the edit button, we redirect the user to a new page and when users clicks on Update/Close, we bring them back to the list page.

Problem

It was a lengthy process to create a new page, validate and bring them back, Also in this case, the link between current work and edit was broken as a user was moving back and forth for editing.

Option 2

Create a popup window. When user clicks on edit button, we create a popup window and let the user edit in a new window. When a user clicks on update/close, the user comes back to the list page.

Problem

As a modern design approach, we were moving away from popup windows (which opens as a new window) and try to find some other alternate for these popup windows. While talking about this option, I also threw AjaxControlToolkit Model Popup but it had the same problem as option 1. The link between current data and editing data was broken.

Option 3

Create an inline form which gets displayed between two rows in GridView. Let the user make any modification required there and when the user clicks on update/close, bring back the same row. This is not a new technique but there are many companies that offer this kind of facility (and charge big bucks for that). As this was a bit easy to implement, I thought of trying to create it on our own (and save some bucks, of course for the company ).

Problem

NONE !!!

My IT Director was very happy to see this prototype. She suggested that I implement this style. And the journey begins …

There are a few things which generate this facility.

As you already know, GridView gets rendered as a table and each column definition in GridView generates one column; so we defined only one column. To create an illusion of Table, we defined only one column and created a table in it. We created the required columns in this new inner table. This gets rendered as one table per DataRow with all columns we specified.

From our ItemTemplate, it was clear that in edit mode we will get only one column, so just like in ItemTemplate, here too we defined edit layout whichever way we wanted. In our case, we wanted rounded corner center aligned table, with different style on header. To achieve this, we used AjaxControlToolkit's RoundedCornerExtension. It has a facility to define which corners we want as rounded corners, so as header we defined only top corners as rounded and for content part we defined only bottom corners as rounded corners. And using table, we defined a layout of form for editing. This gives us a nice looking form when the user clicks on the edit button. And as a result, we got the following GridView:

Image 2: Edit View in inline Grid View

As a final touch, we also needed the header to match the given columns, so we used the same type of style we used on ItemTemplate.

<HeaderTemplate><tablewidth="100%"cellpadding="0"cellspacing="0"><tr><tdstyle="width:15%;"align="left">
First Name
</td><tdstyle="width:15%;"align="left">
Last Name
</td><tdstyle="width:35%;"align="left">
Web
</td><tdstyle="width:35%;"align="left">
Email
</td></tr></table></HeaderTemplate>

Note: Please make sure that ItemTemplate table definition matches the header (specially width of each column) as it will give one table look.

Update: After publishing this article, I got several requests about few things:

Code to update data on click of Update button.

Add paging and code to preserve edit while moving between pages in pageble GridView.

1. Code to Update Data on Click of Update Button

The main purpose for this article was to present a different way to use ItemTemplate. I understand that there may be a few questions about updating data which is beyond the scope of this article. Here is the sample code for how to access updated value when user clicks on the Update Button.

The trick here is to use FindControl on currently editing row and pass ID of control which you want to access. And to access currently editing row, you can use GridView1.Rows[GridView1.EditIndex]. Once we are done updating data, change EditIndex to -1 (indicating no row is in edit state); this will restore all rows of grid back to view state (i.e. hide edit template).

For more details on how to update data into the database, please refer to this link.

2. Add Paging and Code to Preserve Edit while Moving Between Pages in Pageble GridView.

and then we compare this value against current row's DataItemIndex. If it is the same, then this indicates this is the row in edit state, hence we store RowIndex into iCurrentEdit so; when if (iCurrentEdit != -1) gets executed in PageIndexChanging, there will be a value in iCurrentEdit (if a row is in edit state). If this is the case, then we call:

GridView1_RowEditing(GridView1, new GridViewEditEventArgs(iCurrentEdit));

to simulate rowEditClick.

In the above code, there is one potential problem. If the user clicks on edit and changes First Name (or any other field for that matter); does not click on update button and goes to another page to view some information and comes back, the above code will take care of putting the correct row in edit mode, but will not preserve values entered by user. To save those values temporarily, we can use ViewState.

3. Disable All Edit Buttons in Edit State (So User Can Not 'By Accident' Update Another Row

When a user clicks on edit button for any row; the user can not (or should not) be able to click on the edit button of any other row; for that we need to disable all edit buttons when user is in edit mode.

Here, when the user clicks on Edit button, we loop through the entire grid and Disable edit button if its index does not match with the current edit row index. To access edit button, we use:

editButton = (ImageButton)(e.Row.Cells[1].Controls[0]);

As you already know, we have created an entire edit template in one table cell, hence the second cell (at cell index 1) will be for edit/update/cancel buttons, and from that, we access the first control which is the edit button. We disable it and change image icon to indicate this row is not available for editing. We are doing an almost similar thing on row bound which takes care of rows which are not on the current page. When user goes from currently editing page to another page, we wanted to disable editing which we took care of in the RowBound event.

Share

About the Author

He is a results oriented professional building on 10 years of progressive accomplishments in Software Development and Information Technology. He loves to make and help making user friendly web applications which provides enhanced user experience.

You posted a sample project full of bugs--it might be a good article or sample but as it is it is only a 1.

Your updae doesn't update the record. And there are other bugs... fix the demo project, and add paging on large datasets and teh the article would be a 4 or 5 but right is is below amateur and very unprofessional to post samples that don't work.

Before posting this kind of 'unprofessional' comment please read my code & article. I have clearly mentioned that I have not included code for update. Here is comment from my code.

// now you have all values entered by user
// set those values in data set and update
// OR generate UPDATE sql statement here and save values in db.
// more details / example can be found at
// http://msdn.microsoft.com/en-us/library/ms972948.aspx
// OR
// http://www.aspdotnetcodes.com/GridView_Insert_Edit_Update_Delete.aspx

please read above comments and if you want to get information about how to update data please follow above mentioned link.

for purpose of understanding one do not need LARGE dataset. if you really want large data-set please generate and use it.

I didn't rate your article but if I did I would rate it a "1" since the demo project you included has an "update" button and it doesn't work--if you didn't know how to do an update then you shouldn't have included an "update" button--it is not professional at all--by the way--there is no such word as "Professional"--something may not be professsional but it is never "unprofessional" which is what we call "grammar."

In other words, it is not professional in an article to provide a demo and include a button labelled "update" that doesn't work when that is the most important thing about your grid--there are many samples on the Internet of doing a grid this way.

Fix the update button so it works or REMOVE it fom the demo so you don't confuse people.

I thought about fixing it for you and posting a new article that shows people how to fix your demo that doesn't work!

(note, I have no connections to the publisher of this article; other than a being a reader of such)

This design requires more custom programming to handle paging, sorting, and the likes, versus merely using the built-in paging, sorting etc.

Combining the "all buttons can still be clicked" along with "more custom programming", then shoot for a more solid solution.

A more solid solution (IMHO) would be to implement an "in-panel" dialog/popup using the AJAX ModalPopupExtender (MPE) to show a detailed record being edited, with a grayed-out background (a div, per the MPE).

PROs:
- prevent other buttons/links/etc. on the page being pressed;
- load the record at the time of edit (as it may have changed since the gridview loaded);
- separates out data modes for view, new, and edit;
- same MPE can be used for adding records;
- can still keep the 'rounded-corner' feature;
- design the new/edit MPE as a user-control and it can be used where-ever needed;
- as a User-control, put the save & cancel buttons on the main page, which then calls the public Save function in the UserControl. Pass in a ref to a System.Exception, with the user control's save function having a tryCatchFinal.

CONs:
- Gridview would need to be refreshed;
- However, in most data-centric webapps, viewing the most recent data is paramount.
- Gridview page size & page index be reestablished on refresh;

If anybody would like, I'd be more than delighted to post a simple example of the above 'solution' I've noted. Toss an email.

1. As I have mentioned in article we were moving 'away' from popups (even AjaxControlToolkit's ModelPopups) so we needed something like inline editing. In Model Popup solution user can not move back and forth to review other information, In case of Inline Edit it is possible. Again both solutions are equally correct but given situation We needed to implement editing with Inline Editing.

2. You are right about all other links 'active' while editing record; While writing this article I was focus on template that I didn't included other relevant code (like disabling other buttons) I have updated article & code. (sent updated code & article for updating to CodeProject) meanwhile if you want to take a look please visit my blog at http://DayAsDev.Blogspot.com to view updated version of this article.

I'm gonna to add some records to GridView, and paging. when editing the second record, I want to see some records on next page, So I do it, found it displays the panel on the next page with the current second record but not the one I want to edit.
Any help?
Thanks

Yes, you're right.
But, Maybe I haven't make myself clearly: I just want to keep the edit templete and don't lost my editing data which waiting confirm(only this one) when paging.
if I set "GridView1.EditIndex = -1", it will lost all even I don't want to.
Regards