Introduction

For a GridView that utilizes template columns, when a row is placed in edit mode and the last cell's control is selected, when the user presses the TAB key, it automatically updates that row's changes, then places the next row in Edit mode.

Background

The customer requirement was that while editing a GridView row, when TAB is pressed on the last cell, save the changes to that row and place the next row in edit mode. This allows them to quickly do mass updates without having to stop to use the mouse to click the Update and Edit buttons on particular rows.

When I first started coding this, I thought I could simply generate the cryptic object names (e.g., gvPunchList$ctl103$ctl100) that the ASP.NET GridView generates, until I realized that these names change, depending on the postback and event. I drove myself crazy trying to figure out how the GridView/ASP.NET does this, until I found the above methods. No need to understand the inner workings of the GridView now.

Using the Code

The following code was added to the GridView's RowEditing event:

//This is the control found in the last cell of the GridView template:
DropDownList dlc =
(DropDownList)gvPunchList.Rows[e.NewEditIndex].FindControl("dlCategory");
//////////////////////////////////////////////////////////////////////
// TAB KEYPRESS ON LAST CONTROL TO AUTO SAVE AND EDIT NEXT RECORD://////////////////////////////////////////////////////////////////////
// This Code Block wires up the category drop down list so that// if the user preses TAB while on that control, the edit record// will be saved, and the next record will be brought into edit mode://////////////////////////////////////////////////////////////////////
PostBackOptions myPostBackOptions = new PostBackOptions(this);
myPostBackOptions.AutoPostBack = false;
myPostBackOptions.RequiresJavaScriptProtocol = true;
myPostBackOptions.PerformValidation = true;
//This gets the required javascript code that fires //when the UPDATE link button is clicked:String evt = Page.ClientScript.GetPostBackClientHyperlink(
sender as GridView, "Update$" +
e.NewEditIndex.ToString());
// iNewNavigate is used to determine the target row.// if we are at the end of the GridView rows we will // go back to the first row and place it in edit mode:int iNewNavigate = 0;
if (gvPunchList.Rows.Count - 1 != e.NewEditIndex)
{
iNewNavigate = e.NewEditIndex + 1;
}
else
{
iNewNavigate = 0;
}
// Get the javascript that is used to place a gridview row// into edit mode and specify the next row //as the target:string evt2 = Page.ClientScript.GetPostBackClientHyperlink(
sender as GridView, "Edit$" + iNewNavigate.ToString());
// Add to the control onkeydown javascript event code// to check if the TAB key has been pressed// If it was, and fire off the events to execute// the intrinsic Update event, and place the next row// into Edit mode:
StringBuilder js = new StringBuilder();
js.Append(@"if(event.which || event.keyCode)");
js.Append(@"{if ((event.which == 9) || (event.keyCode == 9)) ");
js.Append("{" + evt + ";" + evt2 + ";return false;}} else {return true}");
// Add this javascript event to the last control in the GridView Row:
dlc.Attributes.Add("onkeydown", js.ToString());
//////////////////////////////////////////////////////////////////////////
// END TAB KEYPRESS AUTOSAVE/EDIT/////////////////////////////////////////////////////////////////////////

The comments in the above code block should explain what's going on. Basically, we automatically build the necessary postback methods for the control found in the last cell of a GridView row, and fire that postback method(s) when that control has focus, and the TAB key is pressed. The TAB key is detected with the JavaScript keyCode method.

GetPostBackClientHyperlink is used to provide us a string containing the necessary JavaScript statements required to fire the UPDATE or EDIT events of the GridView CommandField (Edit or Update, could also be SELECT).

After we create our JavaScript key trap and the client-side postback methods, we just bind that to the control in the last GridView row cell's onkeydown event.

Comments and Discussions

I think the issue is (at least for me) that because I am using a template with an EditItemTemplate and ItemTemplate the mode when the RowEditing fires is non-edit and the labels are visible but the tag (textbox in my case) to do the editing is not. So it can not have the JavaScript attached to it.

I am still attempting to find a place later down the road where I can attach to the control I need. Has anyone jumped this hoop?

CODE BEHIND;
Private Sub GridView1_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView1.RowEditing
'This is the control found in the last editable cell of the GridView template:
Dim txtc As TextBox = CType(GridView1.Rows(e.NewEditIndex).FindControl("TRXAMNT"), TextBox)
'////////////////////////////////////////////////////////////////////
' TAB KEYPRESS ON LAST CONTROL TO AUTO SAVE AND EDIT NEXT RECORD:
'////////////////////////////////////////////////////////////////////
' This Code Block wires up the category drop down list so that
' if the user preses TAB while on that control, the edit record
' will be saved, and the next record will be brought into edit mode:
'////////////////////////////////////////////////////////////////////
Dim myPostBackOptions As PostBackOptions = New PostBackOptions(Me)
myPostBackOptions.AutoPostBack = False
myPostBackOptions.RequiresJavaScriptProtocol = True
myPostBackOptions.PerformValidation = True
'This gets the required javascript code that fires when the UPDATE link button is clicked:
Dim evt As String = Page.ClientScript.GetPostBackClientHyperlink(sender, "Update$" + e.NewEditIndex.ToString())
' iNewNavigate is used to determine the target row.
' if we are at the end of the GridView rows we will
' go back to the first row and place it in edit mode:
Dim iNewNavigate As Integer = 0
If GridView1.Rows.Count - 1 <> e.NewEditIndex Then
iNewNavigate = e.NewEditIndex + 1
Else
iNewNavigate = 0
End If
' Get the javascript that is used to place a gridview row into edit mode and specify the next row //as the target:
Dim evt2 As String = Page.ClientScript.GetPostBackClientHyperlink(sender, "Edit$" + iNewNavigate.ToString())
' Add to the control onkeydown javascript event code to check if the TAB key has been pressed
' If it was, and fire off the events to execute the intrinsic Update event, and place the next row
' into Edit mode:
Dim js As StringBuilder = New StringBuilder()
js.Append("if(event.which || event.keyCode)")
js.Append("{if ((event.which == 9) || (event.keyCode == 9)) ")
js.Append("{" + evt + ";" + evt2 + ";return false;}} else {return true}")
' Add this javascript event to the last control in the GridView Row:
txtc.Attributes.Add("onkeydown", js.ToString())
'////////////////////////////////////////////////////////////////////////
End Sub

I believe I can't see all of your code from the aspx page, but assume that you have asp.net server controls in the template columns as I do.
Write a htm page and put an input box on it and wire it to the javascript onkeypress event, ensure that the TAB key on your machine is 9 - as I read there are some differences in javascript's interpretation of the tab key and keyCode

The Tab does work in testing - but nothing is firing for the DataGrid TextBox..... Is the added JavaScript Code viewable from the show source when viewing the webpage?? I don't see it, wondering if you do?

Great work, but how you can detect tab key in internet explorer? In my work, searching for tab detection I discover that, while firefox and other browser throw tab key event, internet explorer doesn't. In my case was sufficient to check "onblur event". This can help you? Do you ever tested with internet explorer? Thanks