views:

373

answers:

4

I have a traditional ASP.NET GridView. Inside of it I have a Template Field with edit capabilities. I need to use a jQuery autocomplete plugin on the edit piece. It works anywhere but inside of this GridView. In other words, I know the plugin works.

Here is the ASP.NET stuff (yes, I'm using a SqlDataSource):


<%# Eval("INGREDIENT_CODE") %>

And here is the jQuery in the document.ready():

$('[id$=txtEditIngredients]').autocomplete("LookupCodes.aspx?type=IC", { mustMatch: true });

What might I be doing wrong here?

+2  A: 

you will want to use within the item template:

<%# ((GridViewRow)Container).FindControl("txtEditIngredients").ClientID %>

If you look at the source of your rendered page you will see the controls ID of the textbox in the gridview is not just txtEditIngredients, it has pre-appended information.

Another option would be to add a class to the textboxs and apply the autocomplete based on the class. This way they are not id-dependent

$('.ICLookup').autocomplete("LookupCodes.aspx?type=IC", { mustMatch: true });

Also if using the client ID, make sure you put a specific document.ready(): into the EditTemplate to make sure it is only only being called when the edit controls are visible.

Glennular
Actually, this is wrong - you can't use <%=txtEditIngredients.ClientID %> because there will be more than one of these on the page, and only one jQuery call, so you need to do something in the jQuery selector that will select all of them.
Charles Boyung
I think he was implying that there was only one on the page. I would assume he would of had a line for each textbox's ID. Not knowing if there were one or many, i also suggested he use the Class route, to add it it multiple controls.
Glennular
I have added the (document).ready function to the EditTemplate but it is still not working. I also went with the Class route and I'm still not getting a green light.
Matt
do you have an example of the code?
Glennular
@Glennular - why would there only be one on the page if it is in a gridview - that makes absolutely no sense.
Charles Boyung
+3  A: 

I think the best way to do it to specify a Class for the textbox and handle it based on class and not ID.

$('.AutoCompleteField').autocomplete("LookupCodes.aspx?type=IC", { mustMatch: true });

I have had problems when I tried to access controls inside gridview using ID.

HTH

Raja
I'm trying this and it still won't work. Is it because it's in the EditTemplate?
Matt
I removed the GridView from the UpdatePanel and now it works. Wonder what's up with that?
Matt
+1  A: 

You can use a class to do the selecting if you want (as others have mentioned), but to me, if you are adding a class for just that purpose and you have an ID you can select with, it seems like a waste.

I created a very simple example and it shows that the way you are doing it (with [id$=txtField] as your selector does indeed work with the plugin. Here's the .aspx code:

<head runat="server">
    <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="jquery.autocomplete.min.js"></script>
    <link type="text/css" href="jquery.autocomplete.css" rel="stylesheet" />
    <script type="text/javascript">
        $(function() {
            $('[id$=txtTest]').autocomplete(["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "pearl"], {
                mustMatch: true
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:GridView runat="server" ID="grdView" AutoGenerateColumns="false">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="txtTest" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    </div>
    </form>
</body>
</html>

And here's the codebehind updates needed to run the test:

protected void Page_Load(object sender, EventArgs e)
{
    List<string> data = new List<string>();
    data.Add("test");
    data.Add("test2");
    this.grdView.DataSource = data;
    this.grdView.DataBind();
}

If you create a test webapp with this as your test page and run it, the autocomplete will work just fine.

Since this is not working for your app, you need to check to make sure that the selector you are using ([id$=txtEditIngredients]) actually matches something. To test this, put this code in place before it in your document.ready event:

alert($('[id$=txtEditIngredients]').size());

This should alert a number with the number of rows in your GridView. If it doesn't, view the source and find that text field in one of your rows to see what the ID is, and adjust your selector accordingly.

Edit: I just wanted to add that I use the [id$=controlName] all the time in jQuery/.Net because of the .Net control naming structure and it works fine every time, so this should not be an issue at all.

Charles Boyung
in your example the ID's for the textboxes are "grdView_ctl02_txtTest" and "grdView_ctl03_txtTest".You would have to call $('[id$=grdView_ctl02_txtTest]')
Glennular
I notice too, that your example, while helpful, doesn't have the TextBox in the Edit template. That's where mine is. Not sure if makes a difference or not.
Matt
@Glennular - no you wouldn't. [id$=txtTest] means that the id ends with txtTest, this is why it works with all instances in a gridview
Charles Boyung
@Matt, did you try what I suggested and see what .size returned for your selector?
Charles Boyung
@Glennular - thanks for voting down when you clearly don't understand jQuery selectors. Just because your answer was 100% wrong doesn't mean you should vote me down because you don't understand what is being discussed.
Charles Boyung
@Charles Boyung - I did rerun the code you gave and I see now that it works. I had used the supplied line for the size() test, that was using txtEditIngredients not txtTest.
Glennular
@Charles Boyung - If you were to edit your response i would be happy to reset my vote.
Glennular
@Glennular - done
Charles Boyung
+1  A: 

Well, now that you said it is inside an updatepanel, it makes a lot more sense. The code in the updatepanel is not necessarily going to be rendered by the time your jquery runs. Doing the alert with .size like I suggested in my other answer would confirm this.

If you did a .live('autocomplete') call instead of .autocomplete(), it should work even with the updatepanel. The jQuery .live function causes the jQuery event to be added to all controls that match the selector, even if they are added after you make the call. See http://api.jquery.com/live/ for details.

Charles Boyung