I have a user control that has two dropdownlists, four textboxes and a gridview in said order. I want the focus to move in this order as tab key is pressed.
I have tabindex property of each control set in sequence (1005, 1010, 1015 ...) except the gridview whose tabindex property is not set to anything.
At page_load I am setting focus to the first dropdownlist.
When page is loaded, focus is on the first dropdownlist, as desired. Then when tab is pressed focus moves to the next dropdownlist, as desired. The problem is when the tab is pressed at this stage, now instead of moving to the first textbox (which has tabindex set to 1015), the focus is moved on the gridview. Note that the gridview do not have its tabindex set to anything. When tab is pressed now, the focus is moved on other user controls on the page, that is, totally out of the discussed user control. Then after several key presses user control do come back to the user control and then move in desired order, that is, first dropdownlist, then second dropdownlist, then first textbox, then second textbox, then third textbox, then fourth textbox. After this it skip the gridview altogether and move to controls which are at the master page.
So, when page is loaded, tab is moving in a different order than what it do once cycle of tabs is completed, that is, all controls are focused.
If I move focus to the first textbox by using mouse click, then press tab then focus is moved to the second textbox as desired, then to third textbox as desired, then to fourth textbox as desired.
I am using two user controls in the page, one of which is discussed above, plus a control directly on page. There are some controls in master page too.
No server or client side event handling happens when tab key is being pressed.
I have tried replace html input control with asp.net textbox control but problem remains.
Request: Please prefer a simple solution, that is one that do not require manually setting tabindex in code-behind because that is not very scalable.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GridExpense.ascx.cs" Inherits="StationaryManagementSystem.GridExpense" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<script type="text/javascript">
function MinQuantity_Blurred()
{
$('#' + '<%= hitMaxQuantitySearch.ClientID %>')[0].value = $('#' + '<%= hitMinQuantitySearch.ClientID %>')[0].value;
}
function FromDated_Blurred()
{
$('#' + '<%= txtToDatedSearch.ClientID %>')[0].value = $('#' + '<%= txtFromDatedSearch.ClientID %>')[0].value;
}
</script>
<asp:Panel ID="panel" runat="server">
<table>
<tr>
<td>
<table width="800px">
<tr align="right">
<td class="columnOne">
Item :
</td>
<td class="columnTwo">
<asp:DropDownList ID="ddlItemSearch" runat="server" EnableViewState="true" DataValueField="Id" DataTextField="Name" TabIndex="1005" Width="200px" />
</td>
<td class="columnOne">
Officer :
</td>
<td class="columnTwo">
<asp:DropDownList ID="ddlOfficerSearch" runat="server" EnableViewState="true" DataValueField="Id" DataTextField="Name" TabIndex="1010" Width="200px" />
</td>
</tr>
<tr align="right">
<td align="right" style="width:200px">
From Quantity:
</td>
<td align="left">
<input type="text" id="hitMinQuantitySearch" name="hitMinQuantitySearch" runat="server" maxlength="9" tabindex="1015"
style="width: 90px; text-align: right" onkeydown="return isNumericKeyDown(event, false);" onkeypress="return isNumericKeyPress(event, false);"
onblur="MinQuantity_Blurred();" />
</td>
<td align="right" style="width:200px">
To Quantity:
</td>
<td align="left">
<input type="text" id="hitMaxQuantitySearch" name="hitMaxQuantitySearch" runat="server" maxlength="9" tabindex="1020"
style="width: 90px; text-align: right" onkeydown="return isNumericKeyDown(event, false);" onkeypress="return isNumericKeyPress(event, false);" />
</td>
</tr>
<tr align="right">
<td class="columnOne">
From Dated :
</td>
<td class="columnTwo">
<asp:TextBox ID="txtFromDatedSearch" runat="server" MaxLength="11" TabIndex="1025" onblur="FromDated_Blurred();" Width="90px" />
<asp:CalendarExtender ID="ceFromDatedSearch" runat="server" TargetControlID="txtFromDatedSearch" Format="dd-MMM-yyyy" />
</td>
<td class="columnOne">
To Dated :
</td>
<td class="columnTwo">
<asp:TextBox ID="txtToDatedSearch" runat="server" MaxLength="11" TabIndex="1030" Width="90px" />
<asp:CalendarExtender ID="ceToDatedSearch" runat="server" TargetControlID="txtToDatedSearch" Format="dd-MMM-yyyy" />
</td>
<td align="left">
<asp:Button ID="btnLoad" runat="server" Text="Load" TabIndex="1035" CssClass="foreRed gradientGreen cornerRound" OnClick="btnLoad_Click" />
</td>
</>
</table>
</td>
</tr>
<tr>
<td>
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" DataSourceID="ods" AllowSorting="True" AllowPaging="True" PageSize="5"
AutoGenerateSelectButton="True" onrowcommand="gv_RowCommand" CssClass="gridSapphire" PagerStyle-CssClass="pagerSapphire"
AlternatingRowStyle-CssClass="alterSapphire" onpageindexchanged="gv_PageIndexChanged" Width="100%" EmptyDataText="List is empty."
DataKeyNames="Id" EnableViewState="true" onrowdeleted="gv_RowDeleted">
<PagerSettings Mode="Numeric"/>
<Columns>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lblIdGrid" runat="server" Text='<%#Eval("Id") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lblIdItemGrid" runat="server" Text='<%#Eval("IdItem") %>' Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item" SortExpression="NameItem" ControlStyle-Width="260px">
<ItemTemplate>
<asp:Label ID="lblNameItemGrid" runat="server" Text='<%#Eval("NameItem") %>' Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lblIdOfficerGrid" runat="server" Text='<%#Eval("IdOfficer") %>' Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Officer" SortExpression="NameOfficer" ControlStyle-Width="200px">
<ItemTemplate>
<asp:Label ID="lblNameOfficerGrid" runat="server" Text='<%#Eval("NameOfficer") %>' Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity" SortExpression="Quantity" ControlStyle-Width="100px">
<ItemTemplate>
<asp:Label ID="lblQuantityGrid" runat="server" Text='<%#Eval("Quantity") %>' Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dated" SortExpression="Dated" ControlStyle-Width="100px">
<ItemTemplate>
<asp:Label ID="lblDatedGrid" runat="server" Text='<%# DateTime.Parse(Eval("Dated").ToString()).ToString("dd-MMM-yyyy") %>'
Style="text-align:left; padding-left:5px" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbDeleteGrid" runat="server" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this Expense?')">
Delete
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="pagerSapphire" />
<AlternatingRowStyle CssClass="alterSapphire" />
</asp:GridView>
<asp:ObjectDataSource ID="ods" runat="server" TypeName="StationaryManagementSystem.Classes.DAL.Expense"
SelectMethod="Search" SelectCountMethod="CountSearch" SortParameterName="sSortExpression" EnablePaging="true"
StartRowIndexParameterName="iZeroIndexStartPage" MaximumRowsParameterName="iSizePage"
onselecting="ods_Selecting"
DeleteMethod="Delete" ondeleting="ods_Deleting">
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int64" />
</DeleteParameters>
</asp:ObjectDataSource>
</td>
</tr>
</table>
</asp:Panel>