Referencing ids unknown at compile time - asp.net

I'm making a user control to gather all the functionality for popups on my website in one place. When someone instantiates the control, they'll pass in a PopupID attribute, which is assigned to the id of a div inside the control, and will be used to call show() and hide() functions in javascript. I'm going to use content templates so that different stuff can be put inside the control by different kinds of popups.
The html for the popup will look something like this:
<div id="<%=PopupID %>" class="popup box" runat="server">
<asp:PlaceHolder runat="server" ID="popupPlaceHolder"></asp:PlaceHolder>
</div>
However, there is a problem: asp.net has the habit of giving controls different IDs when served up to the client than what you write in the html. So the ID of that div might not be <%=PopupID%> It could be somethling like #ctl00_whatever_<%=PopupID%>. Usually I get around this by putting something like:
<script type="text/javascript">
var ddlCountry0 = '<%=ddlCountry0.ClientID%>';
var ddlActivity0 = '<%=ddlActivity0.ClientID%>';
var chkPrivateContacts = '<%=chkPrivateContacts.ClientID%>';;
</script>
In the header for the page. Then when refering to things in the javascript you just do $(ddlCountry0) instead of $('ddlCountry0'). However, I don't see how I can do that in this case, As I don't know the ID of the element until someone instantiates it. What do I do to get around this?

Does the user control have CreateChildControls and OnPreRender methods you can override?
If a control is added and ID set correctly during CreateChildControls...the ClientID property is populated during OnPreRender, at which point the control itself could inject the necessary script block into the body or page header. People often use jQuery to help with this situation:
headerScript.AddLine("var ddlCountry0 = $('[ID$=" & Control.ClientID & "]').attr('id');")
Is that along the right lines?

In the end, I used ClientIDMode=Static to get around these problems.

Related

issues with having same custom control twice in a page

I am facing issues when I tried to add same custom control twice in the same page. The issue is because instance of one control is caling the java script of the other. Added to that I am using ajax popup extender where in I have popup divs with in that control itself.
Now it is leading to java script errors because it is geting confused among the popup div ids and scripts etc.
Please help me.
Take one step further in taking care about client-side IDs generated uniquely for the tags inside each instance of your custom control.
This can be easily fixed by adding runat="server" attributes to the tags which you want to have unique client side IDs when rendered to the browser. Then you should use this kind of code in JS:
document.getElementById("<%= control.ClientID %>");
As about tags which you don't want to mark using runat attribute, you can assign them their IDs uniquely on the server-side manually in each instance of the custom control.
I hope this helps!
There's no automatic fix for this. If a custom control is going to be used more than once on a page, you have to design it to be aware of this. In particular, you'll probably need to refer to generated elements using their generated id:
var ele = document.getElementById("<%= serverSideControl.ClientID %>");
Javascript emitted by the control will have to also emit the appropriate ID's.
And so on.

How can I pass arguments on a ContentPlaceHolder?

Ok, so here is the setup. I have a master page. The page is assigned to a aspx file programatically in the PreInit function. This all works as expected.
I have a function that runs through all the controls on the page an looks for ContentPlaceHolder controls with specific IDs. When a specific ID is found the control is processed (specific content is placed there based on the ID and other information). This all works as expected.
I have a situation where I would like to pass information to my processor function from the control. I would like to be able to, based on an attribute, do different things. For example I would like to be able to put something like this on the masterpage:
<asp:ContentPlaceHolder id="CMS_EXTRABLOCK1" type="text" runat="server"></asp:ContentPlaceHolder>
Note that the type="text" attribute is not a standard attribute. I would like to be able to in the c# code do something like where ctrl is the ContentPlaceHolder.
if (ctrl.Attributes["type"] == "text") {} else {}
Now none of that will work as I get a parse error with the added attribute. So is there a way around the problem while still using the ContentPlaceHolder control? If at all possible I would like to continue using the ContentPlaceHolder control type for consistency with the rest of the code. If I can't use the ContentPlaceHolder in any manner then what would be an equally ideal asp control for this type of situation?

Access hiddenfield using Jquery

I have a page that's derived from a master page. On this page, I have a hiddenfield ("hfUser"). How can I access this "hfUser" control and get/set its value using JQuery?
I've tried variants of this:
$(document).ready(function() {
var test = $("#hfUser").val();
alert(test);
});
but test = undefined. I'm guessing I've got the selector wrong, but I don't know how to get an asp hiddenfield. Any ideas?
Thanks
If you are using Asp.net controls, the server will mangle the control ids. It adds a bunch of extraneous control tree hierarchy information into the id. You need to reference what that acutal id is that's getting rendered, which is availble with the ClientID property on the control (hfUser.ClientID) or access your control in a different, more roundabout way, like find the controls parent, then search through its children to find your control.
If you don't have to use the asp.net HiddenField control, try just using a regular old html input.
ASP does like to mangle ID's. The further down the rabbit hole (or nesting controls) you go, the more ASP adds to your control ID. Throw in Master Pages, and it's yet another level or two.
Another way to access server-side controls (with the runat property set), is to use the square brackets in your jQuery selector.
Like this:
$("[id$='hidImgSource']").val()
That selects any elements whose ID has 'hidImgSource' as ending part of the name. So it will find mangled ID's.
Here is a link to the jQuery Selectors page that explains some more options.
If the hidden field is an ASP.NET control, check out this blog post to help you with jQuery selectors for ASP.NET controls
http://www.foliotek.com/devblog/extending-jquery-to-select-asp-controls/
Do it like this:
$(document).ready(function()
{
var test = $("**#<%= hfUser.ClientID %>**").val();
alert(test);
});

making control in user control visible=false on mouse over

More
I have this datalist in a user control i want when i keep mouse over "More", it should be invisible. it is working on .aspx page not on user control. How to do this. This control is placed on master page.
Please Help.
Probably it will be an issue with getElementById. In a naming container you cannot get the element by simply giving its id. You have to use ClientID to get the generated id of the element at runtime.
Something like
document.getElementById ( "<%= DataList2.ClientID %>");
See Control.ClientID Property
and
Control ID Naming in Content Pages
I would agree that it's probably an issue with trying to get the id of the element since the element's id changes at runtime when you put it inside a user control. You can run your code then do a view source in the browser and see exactly what the id is generating to at runtime.
Have you tried debugging the javascript mover() and mout() function? I am guessing you are looking for elements with the wrong id's since the id's are probably different inside a user control.

Add an Editor control dynamically inside of a repeater using AJAX

I'm looking for a way to add an Editor control (from the ASP.NET AJAX Control Toolkit) to each element of a repeater. It's working fine if I just include it in the ItemTemplate of the repeater, but my problem is that the markup it produces is massive, which slows down the page considerably (even with compression on).
I haven't had any luck adding the control inside the repeater item using an Update Panel - I think this is probably the preferred method, but dynamically adding a control inside an Update Panel inside of a Repeater Item isn't something I've had any success doing, and there don't seem to be any good examples of this that I can find.
The other alternative I considered was using PageMethods to render the control and send the HTML back to the page to let the javascript put it in the appropriate place, then deal with it, but it won't let me render the control - I get an InvalidOperationException of "Page cannot be null. Please ensure that this operation is being performed in the context of an ASP.NET request.". My guess is that all the javascript that's generated makes it so that I can't just render an Editor control on the fly.
Can you point me in the right direction for accomplishing this?
Thanks
EDIT: Another alternative, if it is possible, would be to put a normal Editor control in the markup of the page, then move it around inside of the repeater as needed, using javascript. I can do this with normal controls, but when I do it with an editor, it is not behaving nicely - the textbox appears, but won't let me click inside it. If you have any ideas on this one, I'd appreciate that as well. Here's the code for this:
<span id="spanHiddenEditor" style="display: block;">
<cc1:Editor ID="ed1" runat="server" Height="200" Width="400" />
</span>
<script type="text/javascript">
function createTextBox(idx) {
var span = $get("span1_" + idx); // this gets me the target location
var hiddenEditorSpan = $get("spanHiddenEditor")
var editorHtml = hiddenEditorSpan.innerHTML;
hiddenEditorSpan.innerHTML = "";
span.innerHTML = editorHtml;
}
</script>
identify the location within the repeater with a class then use jquery to inser the html on page ready
$(function() {
$(".myclass").Append("<htmlz>");
});
Then if you need to identify each text box you can do it using the parent container ID eg.
$("#myID div.class input").value
I'm a total jquery newb so none its likely none of it will work, but i believe the idea is a good one!

Resources