1

I have some markup like this:

<form id="ddlSelections" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />

    <asp:UpdatePanel ID="UpdatePanel2" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="DDL3" EventName="SelectedIndexChanged" />
        </Triggers>
        <ContentTemplate>
            <asp:DropDownList ID="DDL3" OnSelectedIndexChanged="testFunc" runat="server" />
        </ContentTemplate>
    </asp:UpdatePanel>
</form>

<div id="placeholder"></div>

When the drop down list DDL3 changes, a callback to testFunc is performed. I want to add an additional event handler to this drop down box that will update placeholder div. For this I am trying to use jQuery. I tried this in the head tag:

$(function () {
       $("#DDL3").click(function () {
           alert("Clicked" + $("#DDL3").val());
       });
});

but jQuery is not catching these events. I am guessing this is because ASP is perhaps over-writing the event handlers.

Is there anyway to achieve this?

EDIT: What gets rendered:

<select id="DDL3" onchange="javascript:setTimeout('__doPostBack(\'DDL3\',\'\')', 0)" name="DDL3">
Legend
  • 113,822
  • 119
  • 272
  • 400
  • `$("#DDL3").change() {}` is not valid JavaScript. Could you post some concrete tries? – pimvdb Oct 20 '11 at 22:28
  • Sorry! Updated with the actual code. – Legend Oct 20 '11 at 22:30
  • For reference, you don't need (or want, really) `javascript:` in event handlers. It "works" because it's parsed as a label, but it has no purpose. `javascript:` is a URL scheme, and is only useful in link targets. – cHao Oct 20 '11 at 23:03

2 Answers2

2

Since it's an ASP.NET control, you need to reference it by the ClientID:

Here is the test case:

<asp:UpdatePanel ID="pnl" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="DDL3" runat="server">
            <asp:ListItem Text="Test" Value="1"></asp:ListItem>
            <asp:ListItem Text="Test 2" Value="2"></asp:ListItem>
        </asp:DropDownList>                    
    </ContentTemplate>                
</asp:UpdatePanel>                
<div id="placeholder">I'm here</div>

There are two ways to handle the selection change:

$(function() {
    $("#<%=DDL3.ClientID%>").change(function(e) {
        $("#placeholder").html("Hello world!");
    });
});

You can use this approach too if you prefer:

$(function() {
    $("#<%=DDL3.ClientID%> option").click(function() {
        $("#placeholder").html("Hello world!");
    });
});

If neither of the above work, another solution can be found here.

Community
  • 1
  • 1
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • Thank You. It still does not work. When I checked the HTML source of the rendered page, it still substitutes the ID I was using. Do you have any more suggestions? – Legend Oct 20 '11 at 22:32
  • Do you mean that it's still using `DDL3` instead of the full ID? – James Johnson Oct 20 '11 at 22:35
  • Yes. Also, I updated my question with what is getting rendered after incorporating your suggestion. – Legend Oct 20 '11 at 22:35
  • Are you setting `ClientIDMode` to `Static` anywhere? – James Johnson Oct 20 '11 at 22:36
  • Actually no. I did not modify that setting. I am currently looking into this: http://stackoverflow.com/questions/256195/jquery-document-ready-and-updatepanels Maybe it has something to do with my situation. I will try this in the mean time. – Legend Oct 20 '11 at 22:39
  • See edited answer. Tested it myself, and it works. I was missing the argument `(e)` – James Johnson Oct 20 '11 at 22:43
  • +1 for your time. Sorry! It does not seem to work for me but thank you for all the suggestions. I added a link to the solution that did work for me. It looks like an UpdatePanel updates everything so we need to add the event handlers every time an update is performed. – Legend Oct 20 '11 at 22:48
  • I tested it with an update panel... that's very strange that it didn't work for you. – James Johnson Oct 20 '11 at 22:52
  • I am not sure if something else is conflicting with it. It could very well be a mistake on my side. I will revisit this one. However, the link I posted as well the procedure outlined in the other post worked well for me. – Legend Oct 20 '11 at 22:54
1

Your "issue" is the <asp:UpdatePanel>. UpdatePanels rewrite their contents when they update, so the <select> you're binding to probably isn't the <select> you're interacting with -- even if they look the same.

You can listen to Microsoft Ajax' events -- either endRequest or pageLoaded -- after which you can bind as you were:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () {
    $('#<%= DDL3.ClientID %>').click(function () {
        alert("Clicked " + $(this).val();
    });
});

Or, use jQuery's .live or .delegate:

$('#<%= DDL3.ClientID %>').live('click', function () {
    alert("Clicked " + $(this).val());
});
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
  • +1 Ok the `live` one worked! I will accept this as an answer because it does not require any ASP specific hacks and also the explanation was very helpful to me. Thank you! – Legend Oct 20 '11 at 22:51
  • @Legend: If you put the DropDownList inside of a control that implements `INamingContainer`, this will not work. You'll need to use the `ClientID`, which is why I suggested it. The `ClientID` approach will work regardless of where in the page the control is located. – James Johnson Oct 20 '11 at 22:53
  • @JamesJohnson [`ClientIDMode`](http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode.aspx), if available, can counter that, but of course `ClientID` is far less error-prone. Was just nice to see someone not *yet* have to use it, so I left it. :) – Jonathan Lonowski Oct 20 '11 at 23:08