views:

52

answers:

2

I am updating one of my sites from asp.net with jQuery UI to use master pages.

Here is a snippet of my original code, which works w/out master pages, but not with:

    $('#myCancelEventDialog').dialog({
        autoOpen: false,
        width: 500,
        buttons: {
            "Cancel This Event": function () { __doPostBack('btnCancel', ''); },  
            "Do Nothing": function () { $(this).dialog("close"); }
        }
    });

However, I see what is going on, with the master page chaging the names of the functions, and this code below fixes it for this instance.

    $('#myCancelEventDialog').dialog({
        autoOpen: false,
        width: 500,
        buttons: {
            "Cancel This Event": function () { __doPostBack('ctl00$ContentPlaceHolder$btnCancel', ''); },  
            "Do Nothing": function () { $(this).dialog("close"); }
        }
    });

Notice I have put the 'ctl00$ContentPlaceHolder$' prefix on the btnCancel so that the appropriate callback function is fixed.

From other threads I have read on stackoverflow, there is a better solution than patching up the code one place at a time as I have done above, but haven't quite got it right yet.

What is the general-purpose way to get jQuery UI postback functions to find the right callback function when you are using master pages like in my example above?

+1  A: 

You will want to use the ClientID of the control you are after:

__doPostBack('<%= btnCancel.ClientID %>', '');

However, if you use this technique, you will have to enclose your script block inside a div that is exposed to the ASP.Net runtime via the runat attribute.

<div runat="server">
    <script type="text/javascript" language="javascript">
        //Your Script Here
    </script>
</div>
Josh
+2  A: 

A quick fix could be to do the following

 $('#myCancelEventDialog').dialog({
        autoOpen: false,
        width: 500,
        buttons: {
            "Cancel This Event": function () { __doPostBack("'" + $('[id$=btnvalue]')[0].id + "'", ''); },  
            "Do Nothing": function () { $(this).dialog("close"); }
        }
    });

This uses the jQuery endswith selector since the master page now means your control id have prefixes but the ending is the same. This works as long as you dont have duplicate id's dotted around which is what the asp.net team aimed to stop by prefixing nested control id's. The downside of this is that jQuery has to do more work to find the element as it cannot use the native getElementById.

Another fix would be to upgrade to asp.net 4.0 where you can turn of the prefixing of controls using the clientidmode

redsquare
Nice, I am using 4.0 and was not aware of that option: which of the 4 Clientidmode values would I need to set it to? and as far as you know, is there any downside to this option?
EJB
No downside at all as long as you have not got the same id in various user controls / repeaters etc which hopefully you should not! No other web framework tried to help the developer by ensuring all the element id's were unique, they trusted the developer! As for which mode. I would choose Static but again depends on your existing pages/controls
redsquare
Thanks, I'll give you the answer for the ClientIDMode tip...nice find. Here is a link for anyone else that wants to read about it: https://www.west-wind.com/weblog/posts/54760.aspx
EJB