htmlvb.net

When button is clicked, the focus jumps to DropDownList. Any ideas?


We have a web app that has run perfectly since 2018 until we made a minor change.

This is app allows user to dynamically add a new row as needed.

Recently, we were instructed to create a DropdownList that dynamically displays or hides some controls based on selection from the DropdownList.

The issue we are currently having is that each time you click a button to add a new row, though the new row gets created but the mouse quickly jumps and focuses on the dropdown.

User will have to scroll back down to the row just added.

Below is the code we are currently using.

//HTML

         <asp:DropDownList ID="ddlChoice" AutoPostBack="true" style="background-color:#0093B2;border: 2px solid #92b200;width:310px;color:white;border-width:5px;" runat="server" class="form-control select2-selection select2-selection--single form-control input-lg" role="combobox" aria-haspopup="true" aria-expanded="false" aria-labelledby="select2-e8ez-container" OnSelectedIndexChanged="ddlChoice_Changed">

       <asp:ListItem Text="Please select >>" Value="" />

       <asp:ListItem Text="I want to use my ID Card" Value="CardNo" />

       <asp:ListItem Text="I want to use my SS number" Value="SSNo" />

      </asp:DropDownList><br />

      <asp:RequiredFieldValidator ID="rfvDDL" runat="server"

                        ControlToValidate="ddlChoice"

                        Display="Dynamic"

                        ErrorMessage="Please make your selection."

                        InitialValue=""

                        ForeColor="Red" >

     </asp:RequiredFieldValidator>



    <div class="table-responsive">

       <asp:gridview ID="Gridview1" RowStyle-Wrap="false" gridlines="None" runat="server" ShowFooter="true" AutoGenerateColumns="false" onrowdatabound="Gridview1_RowDataBound" OnRowDeleting="Gridview1_RowDeleting">

        <Columns>

        <asp:BoundField DataField="RowNumber" Visible="false" HeaderText="Row Number" />

        <asp:TemplateField HeaderText="Name">

         <headerstyle horizontalalign="Left" />

            <ItemTemplate>

                <asp:TextBox ID="txtname" TabIndex="4" Text='<%# Eval("ename") %>' placeholder="Name...(e.g, ABC, Inc.)" runat="server" style="width:375px;" AutoPostBack="true" class="form-control textClass align-left" OnTextChanged="txtname_TextChanged"></asp:TextBox><br />

                <asp:CheckBox ID="grid1Details" ClientIDMode="Static" runat="server" Checked="false" AutoPostBack="true" OnCheckedChanged="Grid1CheckChanged" /><span id="srcemp" runat="server" style="color:#ff0000">*Check this box if N/A</span>

            </ItemTemplate>

        </asp:TemplateField>

        <asp:TemplateField HeaderText="Address">

        <ItemStyle HorizontalAlign="Left"></ItemStyle>

            <ItemTemplate>

                <asp:TextBox ID="txtaddress" TabIndex="5" Text='<%# Eval("address") %>' placeholder="Address..." runat="server" style="width:375px;" class="form-control textClass align-left" AutoPostBack="true" OnTextChanged="txtname_TextChanged"></asp:TextBox><br /><br />

            </ItemTemplate>

        </asp:TemplateField>

        <asp:TemplateField HeaderText="">

            <ItemTemplate>

             <asp:Button ID="ButtonAdd" runat="server" OnClientClick="BtnClick();" CausesValidation="true" Text="Add another row if needed"

                    onclick="ButtonAdd_Click" style="border: 1px solid #6E6E6E;font-family: 'Arial Unicode MS';background-color: #0093B2;color: #FFFFFF;font-size: 12pt;font-style: normal;text-align: center;padding-right: 10px;padding-left: 10px;" /><br /><br /><br>

            </ItemTemplate>

        </asp:TemplateField>

        <asp:TemplateField HeaderText="">

            <ItemTemplate>

             <asp:Button ID="sourceDelete" runat="server" Text="Delete" CommandName="Delete"

                     style="border: 1px solid #6E6E6E;font-family: 'Arial Unicode MS';background-color: #0093B2;color: #FFFFFF;font-size: 12pt;font-style: normal;text-align: center;padding-right: 10px;padding-left: 10px;" OnClientClick="return confirm('Are you sure you want to remove this row?')"  /> <br /><br /><br />

            </ItemTemplate>

        </asp:TemplateField>

        </Columns>

      </asp:gridview>

     </div>

//VB

   Protected Sub ddlChoice_Changed(ByVal sender As Object, ByVal e As EventArgs)

    If ddlChoice.SelectedItem.Value = "CardNo" Then

        pnlCardNo.Visible = True

        pnlSSNO.Visible = False

    Else

        pnlCardNo.Visible = False

        pnlSSNO.Visible = True

    End If

End Sub

//jS

<script type="text/javascript">
        function BtnClick() {
            var val = Page_ClientValidate();
            if (!val) {
                var i = 0;
                for (; i < Page_Validators.length; i++) {
                    if (!Page_Validators[i].isvalid) {
                        $("#" + Page_Validators[i].controltovalidate)
                            .css("border-color", "red");
                    }
                }
            }
            return val;
        }
    </script>

<asp:Button ID="ButtonAdd" runat="server" OnClientClick="BtnClick();" CausesValidation="true" Text="Add another row if needed"

Protected Sub ButtonAdd_Click(sender As Object, e As EventArgs) AddNewRowToGrid() End Sub

Private Sub AddNewRowToGrid() Dim rowIndex As Integer = 0

 If ViewState("CurrentTable") IsNot Nothing Then
     Dim dtCurrentTable As DataTable = DirectCast(ViewState("CurrentTable"), DataTable)
     Dim drCurrentRow As DataRow = Nothing
     If dtCurrentTable.Rows.Count > 0 Then
         Dim txtsoname As TextBox = Nothing
         Dim txtsoaddress As TextBox = Nothing

         For i As Integer = 1 To dtCurrentTable.Rows.Count
             'extract the TextBox values
             txtsoname = DirectCast(Gridview1.Rows(rowIndex).Cells(1).FindControl("txtsourcename"), TextBox)
             txtsoaddress = DirectCast(Gridview1.Rows(rowIndex).Cells(2).FindControl("txtsourceaddress"), TextBox)

             drCurrentRow = dtCurrentTable.NewRow()
             drCurrentRow("RowNumber") = i + 1

             dtCurrentTable.Rows(i - 1)("sourcename") = txtsoname.Text
             dtCurrentTable.Rows(i - 1)("sourceaddress") = txtsoaddress.Text

             rowIndex += 1
         Next
         If Not String.IsNullOrEmpty(txtsoname.Text) AndAlso Not String.IsNullOrEmpty(txtsoaddress.Text) Then
             dtCurrentTable.Rows.Add(drCurrentRow)
         Else
             ScriptManager.RegisterStartupScript(Me, Me.GetType(), "Confirm", "jAlert('Please complete first row before adding a new row!');", True)
         End If
         'dtCurrentTable.Rows.Add(drCurrentRow)
         ViewState("CurrentTable") = dtCurrentTable

         Gridview1.DataSource = dtCurrentTable
         Gridview1.DataBind()
     End If
 Else
     Response.Write("ViewState is null")
 End If

 SetPreviousData()

End Sub

Any ideas how to fix this issue?


Solution

  • Ok, as per my comments, there is nothing that looks to have changed from what you had previous, to what you had/have now.

    With the posted code, and a post-back, I see no code that in the past that attempts to set the focus, and thus clicking on a check box (with a post-back), or clicking on that Add New row button, once again, it re-binds the GridView.

    I suggest adding some code to set focus to the last new row when the user hits add new row.

    Hence, one could simply add some code to set focus to the first text box on that new row you just added.

    So, your code after the GridView binding could be this:

    GridView1.DataBind()
    
    Dim LastRow As GridViewRow = GridView1.Rows(GridView1.Rows.Count - 1)
    Dim txtName As TextBox = LastRow.FindControl("txtname")
    txtName.Focus()
    

    So, the above should thus set the focus to the text box of the newly added row. And if that row is below the current view of the browser, then using .Focus() method of that control should scroll the browser down to that new row, and set the cursor and focus to that text box.