1

I am trying to filter my gridview using textbox within my gridiview headerTemplate. I am currently using TextChanged event method, to execute this task, however when I execute the events method, I am unable to filter the gridiview based on the search input, in the 'txtID'.

protected void grdAdjAMT_TextChanged(object sender, EventArgs e)
    {
        TextBox txtName = (TextBox)GridView1.Rows[(0)].FindControl("txtID");

        string strConnString = ConfigurationManager.ConnectionStrings["####"].ConnectionString;
        using (SqlConnection con = new SqlConnection(strConnString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = "select u.[uID], u.[uForenames], 
                    u.[uSurname], u.[uCompany], u.[uEmailAddress], 
                    s.[sStartDate] 
                from [dbo].[UserDe] 
                where u.[uID] like '%" + txtName + "%' 
                order by s.[sStartDate] desc";

                cmd.Connection = con;
                con.Open();
                GridView1.DataSource = cmd.ExecuteReader();
                GridView1.DataBind();
                con.Close();
            }
        }
    }

protected void Page_Load(object sender, EventArgs e)
    {
        BindGrid();

    }

I debugged my script and found that the debugger only goes through the pageload and BindGrid method, but it does not go through the "grdAdjAMT_TextChanged" method. I also tried to debug the textChange method separately, and still nothing happens.

 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="uID" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" CellPadding="4" ForeColor="#333333" GridLines="None" >
        <AlternatingRowStyle BackColor="White" />
    <Columns>

        <asp:TemplateField HeaderText="ID" SortExpression="ID">
        <HeaderTemplate>
        <asp:Label ID="Label1" runat="server" Text="ID"></asp:Label><br />
            <asp:TextBox ID="txtID" runat="server" OnTextChanged="grdAdjAMT_TextChanged" AutoPostBack="true"></asp:TextBox>
        </HeaderTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" Text='<%# Bind("uID") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>

Any further advice would be very much appreciated. Thanks

5
  • The TextChanged event is raised when the text changes between posts to the server - are you expecting this to post back as the text changes on the client side? Commented Jan 20, 2015 at 17:04
  • are you familiar with __doPostBack jacascript method This sounds like you need to add some if(IsPostBack){} checks in the Page_Load Event also FYI you do not need to call con.Close(); since it's nested inside the using(){} Commented Jan 20, 2015 at 17:05
  • @barrick, Yes, that is my aim. Thank you for your reply. Commented Jan 20, 2015 at 17:13
  • @MethodMan, thank you for your reply. if its not too much trouble, would you mind explaining little more of the javascript logic and then I could use this approach to move forward. Much appreciated. Commented Jan 20, 2015 at 17:17
  • I will post it as an example in the answer so it's easier to read.. I hope this makes sense.. it's pretty straight forward and I use something like this all the time when I don't wanna fool around with Ajax Commented Jan 20, 2015 at 17:26

3 Answers 3

1
  • You could create a JavaScript Function for example: If I have on my control OnClientClick="OnClientSelectedIndexChanged" for example I would write the following:

    <script type="text/javascript">
        function OnClientSelectedIndexChanged(sender, args) {
            __doPostBack('ddlSomeDropDownList', '');
        }
    </script>
    
  • You would need to do something similar for your TextBox then what happens is it will first hit the Page_load Event and if it's properly setup it will then hit the event in my case of the ddlSomeDropDownList.
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I shall give this go. Many thanks for your reply and help.
not a problem let me know if you are have any problems and or issues
1

The short answer here is that what you want to achieve (retriving results that match the given filter) isn't possible using server-side code alone.

Being stateless, the ASP.NET runtime will only be aware of the values it receives from a form when posted to it, and the values that it creates when rendering the page. Therefore, without posting back i.e. via a 'Filter' button, it will have no idea whether the text changed at all. Indeed, the TextChanged event only works due to the Viewstate property, a potentially large base-64 encoded string that's embedded into a form by the runtime to hold the 'previous' values for controls, and the like.

Pressing a button is a client-side act, so the server knows nothing about it. A point to demonstrate this is that whereas there's a Control.KeyPress event in System.Windows.Forms, there's no equivalent in System.Web.UI.WebControls.

As already indicated in other answers, Javascript will be involved in your solution, capturing the key press and then firing a request to the server. I'd recommend researching that approach and posting new questions if you run in to problems there.

A couple of points I'd make about the 'normal' implementation of this sort of functionality:

  1. You probably don't want to be creating a brand new request to the database each time a key is pressed. You could filter a pre-loaded data set in memory to improve response time, but this may not be appropriate where the data set is very large and the page is used frequently.

  2. You might want to have a minimum number of characters in the Filter field before applying the filter. If you have thousands of records, a filter of all those starting with 'a' would not be particularly useful, not least as it would result in a large page. You could apply the filter only when the field has reached a certain length easily with Javascript.

  3. Another common feature is applying the filter after a specific period of time (i.e. 500 milliseconds) without further input. If a user knows what they want to search for e.g. 'computer', then there's no point filtering on each letter (or 6 times, if you've got a minimum of 3 characters needed before applying the filter). If you wait a short time after input before applying the filter, whilst resetting the timer each time any key is pressed, then you'll not have several rapid refilterings going on, and such things can degrade user experience and sometimes result in incorrect results (i.e. the last filter to be applied isn't the last one to have been entered).

  4. If you only remember one of these points, remember this one. Have a good look at the concept of SQL injection, and amend your code accordingly. There are articles everywhere about it, so it shouldn't be hard to explore, but it involves users entering malicious commands into input fields that then end up cascaded to the database, for example, putting '; drop table UserDe; ' into the seach field.

Comments

1

If BindGrid(); is working on the same grid as grdAdjAMT_TextChanged() you probably need to do:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {         
        BindGrid();
    }
}

On a post back the Page_Load runs before the OnTextChanged event. So if you're binding the grid on every post back its going to clear the search text in your grid. Then when it check the TextChanged its going to compare the empty string to the empty string and say no change, so it won't run the event.

You might also want to change:

TextBox txtName = (TextBox)GridView1.Rows[(0)].FindControl("txtID");

to:

TextBox txtName = (TextBox)GridView1.HeaderRow.FindControl("txtID");

3 Comments

I was originally calling the bindgrid() within a postback statement, however, when I input the search value in the txtID textbox, the gridview outputs the entire dataset and does not filter the gridview to one records, as it suppose to. I am also little unclear, what maybe causing this behavior in the event method code. Thank you for your reply.
AutoPostBack="true" (which you have) causes your post back OnTextChaned, so you don't need javascript as suggested in other posts. I would change the line that you are getting the textbox to TextBox txtName = (TextBox)GridView1.HeaderRow.FindControl("txtID"); string Id = txtName.Text;
Thank you for your suggestion, I choose the javascript approach but I test to give your method a try and that also works. I wished, I had seen it sooner. thank you for your help and time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.