Newbie Question on Web DataGrid Focus

R

rlaws

I have a datagrid that is being populated in edit mode on load (I didn't
come up with the requirements, I'm just trying to make it work). Any change
or entry in the datagrid causes a postback to the server (not a database
update). When a change or entry is made and the cell is tabbed out of, after
the postback the cursor goes back to the cell the change or entry was made
in. I want to make sure that the focus is set to the next cell instead of
going back to the previous cell. Is there a way to do this?
 
S

Steven Cheng[MSFT]

Hi Rlaw,

Welcome to ASPNET newsgroup. From your description, you are populating
some datas in a webform
datagrid, and the datagrid is always in Editmode so that the user can entry
new value or modify the exsitn
datas in the grid's cells(textboxes). Since you set those entry fields to
be autopostback, you found the page
will focus on the cell being edited previously after post back, and you're
wondering how to make the focus auto went to the next cell , yes?

AS for this question, I'm not sure how you define your datagrid's template
columns and bind the data with the textboxes(also , the autopostback
things). Would you provide me some code snippet so that I can get a
detailed view ?

Generally the webform datagrid should be used to display datas and in edit
mode, only one gridrow is under editing. Also, the TextBoxes are not
autopostback by default, are you using Custom TemplateColumn ? As for set
the focus on control, we can make use the clientside 's "focus()" jscript
, and at serverside, we can get a control's clientside DOM id via its
ClientID property, I think this is a potential approach. So if you can
provide me some code snippet , I can have a further look into it .

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
R

rlaws

Hello Steven Cheng[MSFT],
Hi Rlaw,

Welcome to ASPNET newsgroup. From your description, you are
populating some datas in a webform datagrid, and the datagrid is
always in Editmode so that the user can entry new value or modify the
exsitn datas in the grid's cells(textboxes). Since you set those entry
fields to be autopostback, you found the page will focus on the cell
being edited previously after post back, and you're wondering how to
make the focus auto went to the next cell , yes?

Yes this is totally correct!!
AS for this question, I'm not sure how you define your datagrid's
template columns and bind the data with the textboxes(also , the
autopostback things). Would you provide me some code snippet so that I
can get a detailed view ?

Here is the code for the datagrid, I believe thats the snippet you're looking
for:

<CODE>
<div style="OVERFLOW-Y: scroll; Z-INDEX: 101; LEFT: 136px; OVERFLOW-X: scroll;
WIDTH: 737px; POSITION: absolute; TOP: 387px; HEIGHT: 298px">
<asp:datagrid id="dtgClaimsDetail" runat="server" Font-Size="8pt" Font-Names="Verdana"
Width="1373px"
BackColor="White" BorderStyle="None" ForeColor="Black" AutoGenerateColumns="False"
BorderColor="#DEDFDE" BorderWidth="1px" CellPadding="4" GridLines="Vertical">
<FooterStyle BackColor="#CCCC99"></FooterStyle>
<SelectedItemStyle Font-Bold="True" ForeColor="White" BackColor="#CE5D5A"></SelectedItemStyle>
<AlternatingItemStyle BackColor="White"></AlternatingItemStyle>
<ItemStyle BackColor="#CCCD94"></ItemStyle>
<HeaderStyle Font-Bold="True" ForeColor="#49637A" BackColor="#DAD5D2"></HeaderStyle>
<Columns>
<asp:EditCommandColumn Visible="False" ButtonType="LinkButton" UpdateText="Update"
CancelText="Cancel"
EditText="Edit"></asp:EditCommandColumn>
<asp:TemplateColumn HeaderText="Claim Line&lt;br&gt;Item">
<ItemTemplate>
<asp:Label id=lblClaimLineItem runat="server" Font-Names="Verdana" Font-Size="8pt"
Text='<%# DataBinder.Eval(Container, "DataItem.CLAIM_LINE_ITEM") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Site Id">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:DropDownList id=ddlLinesSiteId AutoPostBack="true" onSelectedIndexChanged="dtgRowChanged"
Font-Names="Verdana" Font-Size="8pt" Runat="server" datavaluefield="SITE_ID"
datatextfield="NAME" datamember="SiteIDs" datasource="<%# DataSet7 %>">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Dept Id">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:DropDownList id=ddlDeptID Font-Size="8pt" Font-Names="Verdana" AutoPostBack="true"
onSelectedIndexChanged="dtgRowChanged" datasource="<%# DataSet6 %>" datamember="DeptIDs"
datatextfield="SHORT_TEXT" datavaluefield="MASTER_CODE_VAL" Runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Reason">
<ItemTemplate>
<asp:TextBox id=txtdtgReason runat="server" Font-Size="8pt" Font-Names="Verdana"
Text='<%# DataBinder.Eval(Container, "DataItem.SHORT_TEXT") %>' AutoPostBack="true"
onTextChanged="dtgRowChanged" TextMode="MultiLine">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Qty">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:TextBox id=txtdtgQty runat="server" Font-Size="8pt" Font-Names="Verdana"
Width="73px" Text='<%# DataBinder.Eval(Container, "DataItem.QTY") %>' AutoPostBack="true"
onTextChanged="dtgQtyPriceChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="UOM Code">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:DropDownList id=ddlLinesUOM Font-Names="Verdana" Font-Size="8pt" AutoPostBack="true"
onSelectedIndexChanged="dtgRowChanged" Runat="server" datavaluefield="MASTER_CODE_VAL"
datatextfield="SHORT_TEXT" datamember="UOMCodes" datasource="<%# DataSet8
%>">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Price">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:TextBox id=txtdtgPrice Font-Names="Verdana" Font-Size="8pt" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.PRICE") %>' Width="73px" AutoPostBack="true"
onTextChanged="dtgQtyPriceChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Claim Amount">
<HeaderStyle ForeColor="Red"></HeaderStyle>
<ItemTemplate>
<asp:TextBox id=txtdtgClaimAmt Font-Names="Verdana" Font-Size="8pt" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.CLAIM_AMT") %>' Width="73px"
AutoPostBack="true" onTextChanged="dtgRowChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Supp Invt Unit Id">
<ItemTemplate>
<asp:TextBox id=txtdtgSuppInvtUnitId Font-Names="Verdana" Font-Size="8pt"
runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.SUPP_INVT_UNIT_ID")
%>' Width="73px" AutoPostBack="true" onTextChanged="dtgRowChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Mfg Ord No">
<ItemTemplate>
<asp:TextBox id=txtdtgMfgOrdNo Font-Names="Verdana" Font-Size="8pt" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.MFG_ORD_NO") %>' Width="73px"
AutoPostBack="True" ontextchanged="dtgMfgChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Fin Style Id">
<ItemTemplate>
<asp:TextBox id=txtdtgFinStyleId Font-Names="Verdana" Font-Size="8pt" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.FIN_STYLE_ID") %>' Width="73px"
AutoPostBack="true" onTextChanged="dtgRowChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Comment">
<ItemTemplate>
<asp:TextBox id=txtdtgComment Font-Names="Verdana" Font-Size="8pt" runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.COMMENT") %>' AutoPostBack="true"
TextMode="MultiLine" onTextChanged="dtgRowChanged">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Created Dttm">
<ItemTemplate>
<asp:Label Font-Names="Verdana" Font-Size="8pt" runat="server" Text='<%#
DataBinder.Eval(Container, "DataItem.ROW_CREATED_DTTM") %>' ID="Label1">
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Created By">
<ItemTemplate>
<asp:Label Font-Names="Verdana" Font-Size="8pt" runat="server" Text='<%#
DataBinder.Eval(Container, "DataItem.ROW_CREATED_BY_USER_ID") %>' ID="Label2">
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Updated Dttm">
<ItemTemplate>
<asp:Label Font-Names="Verdana" Font-Size="8pt" runat="server" Text='<%#
DataBinder.Eval(Container, "DataItem.ROW_UPDATED_DTTM") %>' ID="Label3">
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Updated By">
<ItemTemplate>
<asp:Label Font-Names="Verdana" Font-Size="8pt" runat="server" Text='<%#
DataBinder.Eval(Container, "DataItem.ROW_UPDATED_BY_USER_ID") %>' ID="Label4">
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
<PagerStyle NextPageText="|Next 10" PrevPageText="Prev 10|" HorizontalAlign="Right"
ForeColor="Black"
BackColor="#F7F7DE" Mode="NumericPages"></PagerStyle>
</asp:datagrid>
</div>
Generally the webform datagrid should be used to display datas and in
edit mode, only one gridrow is under editing. Also, the TextBoxes are
not autopostback by default, are you using Custom TemplateColumn ?

Normally yes I would only have one gridrow under editing however, in this
case the design calls for all rows to be in edit mode without the user having
to do anything. SIGH. Yes, I am using the Custom TemplateColumn.
As for set the focus on control, we can make use the clientside 's
"focus()" jscript , and at serverside, we can get a control's
clientside DOM id via its ClientID property, I think this is a
potential approach. So if you can provide me some code snippet , I can
have a further look into it .

Thanks,

Steven Cheng
Microsoft Online Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

THANKS for the quick response and the help!!
 
S

Steven Cheng[MSFT]

Hi Rlaw,

Thanks for your detailed page template , I think I can build a similiar
page and perform some tests now.
I'll try to see whether we can got it work through some client script
tricks and I'll update you when i got some results.

Thanks,

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi Rlaw,

OK. I'm just building a simple demo page according to the DataGrid template
you provided. There is a DataGrid which contains 4 columns in it and 3 are
textbox column , one is dropdownlist column. All of them are autopostback.
I have been able to use registing clientscript to make the "Move to next
Control" work. Below is the complete page code:

HTH. Thanks,


Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


==========aspx===================
<HTML>
<HEAD>
<title>EditGrid</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<table width="100%" align="center">
<tr>
<td>
<asp:Label id="lblMessage" runat="server">Hello Edit!</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:DataGrid id="dgEdit" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn HeaderText="FirstName">
<ItemTemplate>
<asp:TextBox ID="txtFirstName" Runat="server" AutoPostBack="True"
OnTextChanged="txt_TextChanged"
Text='<%# DataBinder.Eval(Container.DataItem,"FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="LastName">
<ItemTemplate>
<asp:TextBox ID="txtLastName" Runat="server" AutoPostBack="True"
OnTextChanged="txt_TextChanged"
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="txtEmail">
<ItemTemplate>
<asp:TextBox ID="txtEmail" Runat="server" AutoPostBack="True"
OnTextChanged="txt_TextChanged"
Text='<%# DataBinder.Eval(Container.DataItem,"Email") %>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Gender">
<ItemTemplate>
<asp:DropDownList ID="lstGender" Runat="server"
AutoPostBack="True" SelectedIndex='<%#
DataBinder.Eval(Container.DataItem,"Gender") %>'
OnSelectedIndexChanged="lst_SelectedIndexChanged" >
<asp:ListItem Selected="True" Value="m">Male</asp:ListItem>
<asp:ListItem Value="f">Female</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</td>
</tr>
</table>
</form>
</body>
</HTML>

=============code behind===============

public class EditGrid : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label lblMessage;
protected System.Web.UI.WebControls.DataGrid dgEdit;

private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
this.dgEdit.DataSource = GetDataSource();
this.dgEdit.DataBind();
}
}

private DataTable GetDataSource()
{
DataTable dt = Cache["data_source"] as DataTable;

if(dt == null)
{
dt = new DataTable("user");
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("Email");
dt.Columns.Add("Gender", typeof(int));

for(int i=0;i<6;i++)
{
DataRow dr = dt.NewRow();
dr[0] = "FirstName_" + i;
dr[1] = "LastName_" + i;
dr[2] = "Email_" + i;
dr[3] = i% 2;

dt.Rows.Add(dr);
}

Cache.Add( "data_source",dt, null,DateTime.MaxValue,
TimeSpan.FromMinutes(30), System.Web.Caching.CacheItemPriority.Normal,
null);
}

return dt;
}





#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion



protected void txt_TextChanged(object source, EventArgs e)
{
TextBox txt = source as TextBox;

if(txt != null)
{
SetNextControlFocus(txt);
}
}

protected void lst_SelectedIndexChanged(object source, EventArgs e)
{
DropDownList lst = source as DropDownList;

if(lst != null)
{
SetNextControlFocus(lst);
}
}

protected void SetNextControlFocus(Control prectrl)
{
DataGridItem item = prectrl.NamingContainer as DataGridItem;

if(item != null)
{
string nextid = "";

switch(prectrl.ID)
{
case "txtFirstName":
nextid = "txtLastName";
break;

case "txtLastName":
nextid = "txtEmail";
break;

case "txtEmail":
nextid = "lstGender";
break;

case "lstGender":
item = dgEdit.Items[(item.ItemIndex + 1)% dgEdit.Items.Count];
nextid = "txtFirstName";
break;
}

Control nextctrl = item.FindControl(nextid);

RegisterSetFocusScript(nextctrl.ClientID);

}

}


protected void RegisterSetFocusScript(string clientid)
{
string strFormat = "<script language='javascript'
document.getElementById('{0}').focus();</script>";

Page.RegisterStartupScript("datagrid_focus_script",
string.Format(strFormat, clientid));

}



}
 
R

rlaws

Hello Steven Cheng[MSFT],

I copied the code down and built the application and it works great <GRIN>.
That's the good news. I took what I needed and converted it to VB. The
code run, doesn't fail, but the focus isn't going to the next item. Here
is what I did, if you see something wrong with it please let me know. Sorry
to keep bugging you.

<CODE>

Protected Sub dtgRowChanged(ByVal sender As Object, ByVal e As System.EventArgs)

Dim txt As TextBox = sender

If Not txt Is Nothing Then
SetNextControlFocus(txt)
End If

End Sub


Protected Sub SetNextControlFocus(ByVal prectrl As Control)
Dim item As DataGridItem = prectrl.NamingContainer


If Not item Is Nothing Then
Dim nextid As String = ""

Select Case prectrl.ID
Case "ddlLinesSiteId"
item = dtgClaimsDetail.Items((item.ItemIndex + 1) & dtgClaimsDetail.Items.Count)
nextid = "ddlDeptID"


Case "ddlDeptID"
item = dtgClaimsDetail.Items((item.ItemIndex + 1) & dtgClaimsDetail.Items.Count)
nextid = "txtdtgReason"


Case "txtdtgReason"
nextid = "txtdtgQty"


Case "txtdtgQty"
nextid = "ddLinesUom"


Case "ddLinesUom"
item = dtgClaimsDetail.Items((item.ItemIndex + 1) & dtgClaimsDetail.Items.Count)
nextid = "txtdtgPrice"


Case "txtdtgPrice"
nextid = "txtdtgClaimAmt"


Case "txtdtgClaimAmt"
nextid = "txtdtgSuppInvtUnitId"


Case "txtdtgSuppInvtUnitId"
nextid = "txtdtgMfgOrdNo"


Case "txtdtgMfgOrdNo"
nextid = "txtdtgFinStyleId"


Case "txtdtgFinStyleId"
nextid = "txtdtgComment"


Case "txtdtgComment"
nextid = "ddLinesSiteId"

End Select

Dim nextctrl As Control = item.FindControl(nextid)

RegisterSetFocusScript(nextctrl.ClientID)

End If

End Sub

Protected Sub RegisterSetFocusScript(ByVal clientid As String)

Dim strFormat As String = "<script language='javascript'> document.getElementById('{0}').focus();</script>"

Page.RegisterStartupScript("datagrid_focus_script", String.Format(strFormat,
clientid))

End Sub

</CODE>

It appears that everything is working fine, I can actually debug and step
through the code and see what it is doing but either the Script isn't running
or the register fails.
Hi Rlaw,

OK. I'm just building a simple demo page according to the DataGrid
template you provided. There is a DataGrid which contains 4 columns in
it and 3 are textbox column , one is dropdownlist column. All of them
are autopostback. I have been able to use registing clientscript to
make the "Move to next Control" work. Below is the complete page code:

HTH. Thanks,

Steven Cheng
Microsoft Online Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
==========aspx===================
<HTML>
<HEAD>
<title>EditGrid</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<table width="100%" align="center">
<tr>
<td>
<asp:Label id="lblMessage" runat="server">Hello
Edit!</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:DataGrid id="dgEdit" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn HeaderText="FirstName">
<ItemTemplate>
<asp:TextBox ID="txtFirstName" Runat="server"
AutoPostBack="True"
OnTextChanged="txt_TextChanged"
Text='<%# DataBinder.Eval(Container.DataItem,"FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="LastName">
<ItemTemplate>
<asp:TextBox ID="txtLastName" Runat="server"
AutoPostBack="True"
OnTextChanged="txt_TextChanged"
Text='<%# DataBinder.Eval(Container.DataItem,"LastName") %>'
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="txtEmail">
<ItemTemplate>
<asp:TextBox ID="txtEmail" Runat="server"
AutoPostBack="True"
OnTextChanged="txt_TextChanged"
Text='<%# DataBinder.Eval(Container.DataItem,"Email") %>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Gender">
<ItemTemplate>
<asp:DropDownList ID="lstGender" Runat="server"
AutoPostBack="True" SelectedIndex='<%#
DataBinder.Eval(Container.DataItem,"Gender") %>'
OnSelectedIndexChanged="lst_SelectedIndexChanged" >
<asp:ListItem Selected="True" Value="m">Male</asp:ListItem>
<asp:ListItem Value="f">Female</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</td>
</tr>
</table>
</form>
</body>
</HTML>
=============code behind===============

public class EditGrid : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label lblMessage;
protected System.Web.UI.WebControls.DataGrid dgEdit;
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
this.dgEdit.DataSource = GetDataSource();
this.dgEdit.DataBind();
}
}
private DataTable GetDataSource()
{
DataTable dt = Cache["data_source"] as DataTable;
if(dt == null)
{
dt = new DataTable("user");
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("Email");
dt.Columns.Add("Gender", typeof(int));
for(int i=0;i<6;i++)
{
DataRow dr = dt.NewRow();
dr[0] = "FirstName_" + i;
dr[1] = "LastName_" + i;
dr[2] = "Email_" + i;
dr[3] = i% 2;
dt.Rows.Add(dr);
}
Cache.Add( "data_source",dt, null,DateTime.MaxValue,
TimeSpan.FromMinutes(30), System.Web.Caching.CacheItemPriority.Normal,
null);
}
return dt;
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
protected void txt_TextChanged(object source, EventArgs e)
{
TextBox txt = source as TextBox;
if(txt != null)
{
SetNextControlFocus(txt);
}
}
protected void lst_SelectedIndexChanged(object source, EventArgs e)
{
DropDownList lst = source as DropDownList;
if(lst != null)
{
SetNextControlFocus(lst);
}
}
protected void SetNextControlFocus(Control prectrl)
{
DataGridItem item = prectrl.NamingContainer as DataGridItem;
if(item != null)
{
string nextid = "";
switch(prectrl.ID)
{
case "txtFirstName":
nextid = "txtLastName";
break;
case "txtLastName":
nextid = "txtEmail";
break;
case "txtEmail":
nextid = "lstGender";
break;
case "lstGender":
item = dgEdit.Items[(item.ItemIndex + 1)% dgEdit.Items.Count];
nextid = "txtFirstName";
break;
}
Control nextctrl = item.FindControl(nextid);

RegisterSetFocusScript(nextctrl.ClientID);

}

}

protected void RegisterSetFocusScript(string clientid)
{
string strFormat = "<script language='javascript'
document.getElementById('{0}').focus();</script>";
Page.RegisterStartupScript("datagrid_focus_script",
string.Format(strFormat, clientid));

}

}
 
S

Steven Cheng[MSFT]

Hello Rlaw,

Thanks for you followup. Glad that it helps you. Also, I'm sorry for
haven't care that you're using VB.NET. From the further code snippet you
pasted. I think the following statements seems have some problems:

item = dtgClaimsDetail.Items((item.ItemIndex + 1) &
dtgClaimsDetail.Items.Count)

I use this because when the current edit cell is the last on a row, then we
need to jump to the next row. And

in C# "%" means calculate the Mod value, so in VB.NET, we should use the
"Mod" instruction instead (not &).

Also, for your convenience, I've generated a VB.NET version of the demo
page, here is the page source:

Good Luck! :--)

========code behind===============
Public Class EditGrid
Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

End Sub
Protected WithEvents lblMessage As System.Web.UI.WebControls.Label
Protected WithEvents dgEdit As System.Web.UI.WebControls.DataGrid

'NOTE: The following placeholder declaration is required by the Web
Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
dgEdit.DataSource = GetDataSource()
dgEdit.DataBind()
End If
End Sub

Private Function GetDataSource() As DataTable

Dim dt As DataTable = Cache("data_source")

If dt Is Nothing Then

dt = New DataTable("user")
dt.Columns.Add("FirstName")
dt.Columns.Add("LastName")
dt.Columns.Add("Email")
dt.Columns.Add("Gender", GetType(Integer))

Dim i As Integer
For i = 0 To 6

Dim dr As DataRow = dt.NewRow()
dr(0) = "FirstName_" & i
dr(1) = "LastName_" & i
dr(2) = "Email_" & i
dr(3) = i Mod 2

dt.Rows.Add(dr)

Next i

Cache.Add("data_source", dt, Nothing, DateTime.MaxValue,
TimeSpan.FromMinutes(30), System.Web.Caching.CacheItemPriority.Normal,
Nothing)

End If


Return dt
End Function





Protected Sub txt_TextChanged(ByVal source As Object, ByVal e As
EventArgs)
Dim txt As TextBox = source

If Not txt Is Nothing Then

SetNextControlFocus(txt)

End If

End Sub


Protected Sub lst_SelectedIndexChanged(ByVal source As Object, ByVal e
As EventArgs)

Dim lst As DropDownList = source

If Not lst Is Nothing Then
SetNextControlFocus(lst)
End If

End Sub



Protected Sub SetNextControlFocus(ByVal prectrl As Control)
Dim item As DataGridItem = prectrl.NamingContainer

If Not item Is Nothing Then

Dim nextid As String = ""

Select Case prectrl.ID

Case "txtFirstName"
nextid = "txtLastName"

Case "txtLastName"
nextid = "txtEmail"


Case "txtEmail"
nextid = "lstGender"


Case "lstGender"
item = dgEdit.Items((item.ItemIndex + 1) Mod
dgEdit.Items.Count)
nextid = "txtFirstName"

End Select

Dim nextctrl As Control = item.FindControl(nextid)

RegisterSetFocusScript(nextctrl.ClientID)


End If


End Sub



Protected Sub RegisterSetFocusScript(ByVal clientid As String)
Dim strFormat As String = "<script language='javascript'
document.getElementById('{0}').focus();</script>"

Page.RegisterStartupScript("datagrid_focus_script",
String.Format(strFormat, clientid))
End Sub

End Class
============================


Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
R

rlaws

Hello Steven Cheng[MSFT],

Thanks so much for your help. I finally figured out what the problem was
with the code working in the sample that you gave and not in mine......I
had smartNavigation="TRUE" in mine. When I removed that it worked. The
issue is that I need to have the smartNavigation on and for this to work.

Roy
 
S

Steven Cheng[MSFT]

Hi Rlaws,

Thanks for your further description. Now, I think the problem is just the
smartNavigation. As for this problem, I'm afraid we could only choose
either our custom scripts or using smartNavigation. Because if we turn on
smartNavigation for an asp.net page, the smartNavigation will inject its
own script code which will keep the page focus on the last point before it
posted back, that's why our custom script code won't work. Is it ok that
you turn off the smartNavigation for those page which need to use our
custom script codes?

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top