How do I style an ASP.NET HTML server control by ID? - css

When I create an HTML server control in ASP.NET 4.5 with an ID and use CSS to style that ID, it fails. When I inspect the source of the ASPX page, it shows that ASP.NET has changed my control's ID. In this instance...
<div id="PasswordStatus" class="well well-sm" runat="server">
Current
</div>
...becomes...
<div id="article_PasswordStatus" class="well well-sm">
Current
</div>
Can I then reliably (and with best practices in mind) just create the CSS style for #article_PasswordStatus instead? Or should I create a one-use CSS class for it, something like...
<div id="PasswordStatus" class="well well-sm password-status">
Current
</div>
Preferably, can I still somehow use the original ID I assigned?
Note: I do not want to convert this to a Web server control.

Assuming .net 4 and greater, you can use ClientIDMode. Your HTML would be like this
<div id="PasswordStatus" class="well well-sm" runat="server" ClientIDMode="Static">
Current
</div>
When using Static the ClientID value is set to the value of the ID property. If the control is a naming container, the control is used as the top of the hierarchy of naming containers for any controls that it contains.

Add in the ClientIDMode="Static" option to ensure your client Ids do not change.
Information can be found here.
<div id="PasswordStatus" class="well well-sm" runat="server" ClientIDMode="Static">
Current
</div>
This option forces the control’s ClientID to use its ID value directly. No naming container naming at all is applied and you end up with clean client ids

It's usually a best practice to use classes for css styling instead of IDs. You can avoid problems like this, reuse your css and so on, so that would be the path I'd choose.
ID in asp.net (webforms) can be modified in various ways and I wouldn't rely on that personally.

Related

Access web part properties from within CMSRepeater Template

Is there any way I can access a webpart's properties from withing a repeater's template (or vice versa)?
<div ID="RepeaterWrapper" runat="server">
<cms:CMSRepeater ID="repItems" runat="server">
<ItemTemplate>
<div class="col-sm-4">
<!-- I want to access this div in my code behind or else have it access a property from the code behind-->
</div>
</ItemTemplate>
</cms:CMSRepeater>
</div>
I want to set the inner div's bg color and I can't use classes as the property is given as a hexadecimal color so it would mean a few thousand classes!
Worst case scenario I can do it with some js but would rather a "purer" way of doing it if it exists.
Thanks in advance
Assuming your datasource has that background color in the returned data, once you bind your datasource to the repeater you have access to that within the item templates. Simply use something like this:
<div class="col-sm-4 <%# Eval("BgColorColumnName") %>">
Now if you want to set a value from the actual webpart itself, you need to make sure the property is a public property then you can use something like:
<div class="col-sm-4 <%# YourPublicPropertyName %>">
Are all the items going to have the same color? If its per item, then modify the items you are pulling to include the value.
If this was in portal method you could grab the XML from the Page Template table and get values from it. Since it's purely from code, and it's a repeater, usually you need to store the data somewhere outside the repeater itself (in the items you repeat, or in the current page form data).
If you can access it anywhere from a Macro, then you can use the CMS.MacroEngine.MacroContext.Current.ResolveMacro() to resolve that and get the value.
Can you give us a little more info on where the div BG color would be stored? why it has to be in the repeater itself?

asp.net: Is there a way to suppress HTML output of "ID" attribute when using runat="server"?

The new .NET v4 offers some great ways to customise output of control IDs, so they're clean and easier to use with JavaScript.
However, I'd sometimes like to completely suppress the output of a control's ID in the HTML. Is that possible, on a per-control basis?
eg:
<div class="myclass" id="mycontrol" runat="server">
... some HTML
</div>
I want to conditionally control output (visibility) of "mycontrol" in the codebehind. But, when it is visible, I want the HTML output to be simply:
<div class="myclass">
... some HTML
</div>
Do we have that level of control in .NET 4?
I mean directly and easily, ie. without wrapping it in a Placeholder or doing custom rendering.
you can use combination of asp. net and jquery for your top part you can do this if you are using .net 4.0
<div class="myclass" ClientIDMode="Static" id="mycontrol" runat="server">
... some HTML
</div>
and with jquery you can
$(".myclass").removeAttr("id")
and remove more unnecessary attributes
<div class="myclass">
... some HTML
</div>

Javascript won't work on Html server control?

I am writing a website with ASP.Net.
I will have lots of html generic controls like <div> <span> and so on..
I have some onclick javascript functions, onmouseover javascript functions..
They are working fine..
Then I need to control them on the server side.
So, I add runat="server"..
After that, all the javascripts aren't working anymore..
I understand they aren't working coz all the events are now going back to server side.
So, is there anyway to make them work??
For eg,
<div id="myDiv1" onclick="myfunction(para1)"><img src="..." /></div>
the above code is working..
<div id="myDiv1" runat="server" onclick="myfunction(para1)"><img src="..." /></div>
the above code is not working...
I can make it work, probably by
<div id="externalDiv1" onclick="myfunction(para1)"><div id="myDiv1" runat="server" ><img src="..." /></div></div>
Is there any other way?
I assume that you used document.getElementById() to get an element by its id. If you are using master pages, the IDs of server controls will be changed after rendering to the page, in that case, you have to use its ClientID
for e.g.
var myDiv1 = document.getElementById("<%= myDiv1.ClientID %>");
Server-side or client-side controls makes no difference as far as javascript is concerned. ALL server-side controls end up being rendered as normal HTML controls. If your javascript functions are not working might be because you are accessing them by the wrong id since by making them server-side controls they can now have ids that follow a pattern like <parent_id>_<control_id>.
For example, a span element declared like this:
<span id="mylabel" runat="server"> testing</span>
may end up being rendered as:
<span id="MainContent_mylabel"> testing</span>
ASP.NET 4.0 has a feature called CliendIDMode which can be set to static, meaning, that your ids on the markup will stay unchanged after the page is rendered.

Expanding ClientID in an event string

I'm having a problem with <%= obj.ClientID %> expansion, in a .ascx user control.
I have a .js file, containing a javascript function:
function doSomething(objectId)
{
...
}
I have a .ascx file, with some html elements, and in one element's onclick= I want to call doSomething(), passing the ID of an element in that .ascx file, where the passed ID is of an element other than the one being clicked on, so I can't use "this.".
Maybe it'd be clearer with an example.
This works:
<script type="text/javascript">
function redirect()
{
doSomething('<%= top.ClientID %>');
}
</script>
<div id="top" runat="server">
<img src="..." alt="..." onclick="redirect();"/>
</div>
But this does not:
<div id="top" runat="server">
<img src="..." alt="..." onclick="doSomething('<%= top.ClientID %>');"/>
</div>
When I look at the source, I see that the <%= %> substitution has not happened, instead of "doSomething('ctl00_myControl_top');" I get "doSomething('<%= top.ClientID %>');"
For some reason, the script expansion happens in the former case, but not in the latter. The work-around, of course, is not acceptable because it will break if I include multiple copies of the control on a page - only one instance's "redirect()" function will be accessible.
Any ideas on how to make this substitution work?
Works on my machine?
<div id="top" runat="server">
rarrarara
</div>
Becomes
<div id="ctl00_ContentPlaceHolder1_top">
rarrarara
</div>
Consider an alternate route:
Ensure that the control you are referencing in JavaScript using the inline expression <%= (controlName).ClientID %> has its 'ClientIDMode' specifier set to a static value and then simply use the text in the ID field of that control to refer to it. I ended up using this in a recent project it works great. Please see the link below for a more detailed explanation:
Code Project - ASP.NET v4.0 Client ID Feature
Along with setting the 'ClientIDMode' specifier to "Static", I found a useful idea regarding placing text from a global resource file (in the case of language switching) into a field of a standard HTML control that does not have to run at the server level. I used this on a standard HTML button that was supposed to call a JavaScript function that would show/hide a specific div or ASP Panel. Use the GlobalResource function in the inline expression tags like so:
<input id="btnToggleFilterOptions" type="button" value="<%=GetGlobalResourceObject("SiteResource", "btnToggleFilterOption")%>" onclick="javascript:ToggleCssClass('divFilterOption','visible'); return false;" class="button submit" />
<asp:Panel ID="divFilterOption" ClientIDMode="Static" runat="server">
<asp:TextBox ID="txtFilterOption1" runat="server" />
</asp:Panel>
I know this is an old post, but it is a popular hit when searching on Google for Asp .NET and ClientID. I hope this helps somebody else out!

adding runat="server" changes the behaviour of the layout

I have a page with some controls, usercontrols etc.
when I change a div from plain <div id="foo"> to a <div id="foo" runat="server">
the layout complete changes.
why is that and how can I prevent it?
I'm using 2.0 .NET framework
Is it because .NET changes my id, which obviously I don't want?
If you're targetting the ID of the div control in CSS and then running the control at server, you'll find it no longer applies the style.
This is because ASP.NET has a built in mechanism (INamingContainer) to ensure than you don't have multiple controls named the same. It does this by adding container prefixes so you end up with:
<div id="ctl00_ctl00_myDivName" runat="server" />
The easiest way around this is to change it from working on an ID to working on a class:
<div class="myDiv" runat="server"></div>
Alternatively, I believe that XHTML requires that Divs have closing tags so use
<div runat="server">Some content</div>
When you add runat="server" to a div, the system automatically generates the ID for it. It's referred to as ID mangling. Unfortunately there isn't much that you can do in the 2.0 framework for divs that I'm aware of (without it being a pain anyway), but in 4.0 we're getting an override... On custom controls though (in 2.0) you can override the ClientID and UniqueID fields. So if you created a MyDiv class that used the div as a base and then created the ClientID/UniqueID fields you should be ok.
Your other option would be to update your CSS/javascript to use the mangled ID. It's fairly static based on the position within the page as ASP.Net uses it to find a control during postback.
Add ClientMode="static" this will make sure your id is not changed to the clientside id for your control.

Resources