Using Javascript (DOM) with ASP.NET - asp.net

I have an asp.net page with several list boxes.
I would like to include some javascript on the page that allows a user to drag individual list elements from one box to another.
On a normal web page, the script to do this is reasonably simple, however, with the element IDs generated by ASP.NET, I don't know what identifiers to have my script look up?
Any thoughts on how to do something like this?

Add a identifying CSS class to your elements and use those. i.e. jQuery has a superb support for that so you can grab all elements and loop through them to do whatever you want.

Check out the ClientId property of the Control class.
Note: The ASP.NET ListBox control inherits from Control.
Update
In reponse to the comments below, I can think of two ways to access the individual li elements of an unordered / ordered list generated by the ListBox control.
Create a custom Control that inherits from
the ListBox control and renders out an
id attribute for each li element.
Use the getElementsByTagName method
in JavaScript. MSDN even has an
example that uses the
getElementsByTagName method to get
the children of an unordered list and
displays an alert indicating the
number of children and the value of
the first child element. If the MSDN documentation isn't your thing, you can check out the MDC documentation as well.

You could either use the ClientId property as stated by paper1337
var element = document.getElementById('<%= MyDropDownList.ClientID %>');
or you could implement a AJAX Behavior using AjaxControlToolkit.
Code:
[assembly: WebResource("MyJS.js", "text/javascript")]
[ClientScriptResource("MyBehavior", "MyJS.js")]
public sealed class MyExtender : BehaviorBase {
// can be empty
}
Markup:
<asp:DropDownList runat="server" ID="DDL" />
<my:MyExtender runat="server" TargetControl="DDL" />
MyJS.js (See AjaxControlToolkit samples for details):
...
var element = this.get_element();
...

If you are on asp.net 4.0+, you can use the ClientIDMode="Static" to force asp.net to use the id you have specified. There's a nice explanation on ScottGu's blog, and the MSDN Docs for ClientIDMode are available.
You may also want to try ClientIdMode="Predictable", if you have a lot of generated elements.

Related

possible to reference CSS selector in code-behind ASP.NET

Let's say I have this HTML markup on an aspx page:
<div id = 'logo-container' class='foo'>
<img alt='logo' src ="images/foo.png" />
</div>
Pure html, not runat=server.
Is it possible, in aspx code-behind, to refer to a DOM element using CSS selectors? Could you get a reference to the IMG doing something like this:
foreach element in GetElement("#logo-container img")
{
do something with element, e.g. change a style attribute
}
No, you cannot, unfortunately. You'd be beter off doing it the intended way. If you need to access the controls in code-behind, just add the runat="server" attribute.
Why don't you want to run the controls at the server, considering that you need to access them in the code-behind? Are you worried about the auto-generated IDs? If so, you can resolve this by setting ClientIDMode to static.
If you do run the control at the server, you should be able to find the controls with that class using LINQ like this:
var ctrls = pnlControls.Controls.OfType<WebControl>().Where(i => i.CssClass == "logo-container");
Note: You can Replace WebControl with a more specific control if needed.
Short answer - No. If the control is not set to runat="server", you cannot access it from the code behind. However, you can access the element using Javascript and then call a server-side method to do whatever logic you want to do.
I feel better Solution is :
If you really want to change the style/css class you can better go for jquery and customize the way you want it.

asp.net+css+jQuery - how does it all work together?

I would like to understand how can I use jQuery to work with asp.net and css.
When I'm writing asp.net code and for example I'm adding to a page DropDownList, I can't see it in the source when I'm opening source of a page in web browser. Instead of dropdownlist I can see select tag. When does the "magic" is done to change asp.net tag to select?
What is more I can't see my CSS classes names added to asp.net tags. There are some kind of differen CSS class names. But when I'm opening developer tools in IE, I can see CSS class names, which are same as in my definition.
And the last thing. What names of a tags sould I use in jQuery to traverse page which was developed in asp.net. Shoud I use a tags which I see in the source code of a page in a browser or can I ask jQuery about asp.net tags? What about CSS classes? Why I can't see them in a source of a page in a browser? Can use my names of a CCS classes under jQuery queries?
Please, can anybody explain me how does this three technologies work together?
When does the "magic" is done to change asp.net tag to select?
Most of "magic" you're wondering about is done by ASP.NET controls, which are designed to generate the markup that is sent to the browser.
When a request is received, the application iterates over each control, calling its Render method (inherited from the Control class), which allows each control to generate the markup they represent.
Following your example, the DropDownList control generates a <select> tag. As a ListControl, it uses the ListItem controls to create the <option> tags within.
Another would be the GridView, which generates a <table> using GridViewRow controls for <tr> and various HTML Controls, such as TableCell for <td> and <th>, to create the rest of the markup.
Shoud I use a tags which I see in the source code of a page in a browser or can I ask jQuery about asp.net tags?
No, jQuery/JavaScript have no knowledge of server-side control names, only the markup they generate. So, rather than searching for $('DropDownList'), you'd search for $('select').
What is more I can't see my CSS classes names added to asp.net tags. There are some kind of differen CSS class names.
By "CSS Names," do you mean IDs? I'm sorry to ask, but CssClass attributes shouldn't change in value from server-side to client-side, just in name -- CssClass to just class.
IDs, on the other hand, are prefixed to ensure their uniqueness throughout the page, including a prefix of the MasterPage and ContentPlaceHolder names, if they're used. For this reason, I'd steer away from trying to use IDs to apply CSS to server-side controls, using classes instead.
Now, the end of the ID should remain as the ID you gave in server-side, so you should still be able to find the element in jQuery using the Attribute Ends With Selector [name$='value']:
# ASP
<asp:DropDownList ID="AnyGivenDropDown" runat="server" />
# HTML (generated)
<select id="ctl00_PageContents_AnyGivenDropDown"></select>
# JavaScript
$('select[id$="_AnyGivenDropDown"]');
Otherwise, I'd stick to classes to find the controls you're looking for:
# ASP
<asp:DropDownList ID="AnyGivenDropDown" CssClass="anygiven" runat="server" />
# HTML (generated)
<select id="ctl00_PageContents_AnyGivenDropDown" class="anygiven"></select>
# JavaScript
$('select.anygiven');
# CSS
.anygiven { }
The "magic" happens in the render event of the asp.net page lifecycle. Asp.net server controls all render as standard html element(s). The most important difference is that you can access them and their values on the server side. WebControls also have a CssClass property that when rendered becomes the class attribute of the HTML element.
The id can be a bit tricky when working with jQuery and CSS. This is because depending on the controls hierarchy they may have a clientID such as ctl100_containerID_myControl instead of myControl. To overcome this in jQuery when you reference a control you can refrence it by its ClientID like so:
$('#<%=myControlID.ClientID%>')
This is serverside that will write the client side ID of the control after it is rendered.
ASP.NET: High-level web development framework. When you create a web form in .NET, the framework will work together with the IIS handlers and create (hopefully) valid HTML that will work with your server-side code during postbacks.
JQUERY: This will allow you to perform client-side scripting such as calculation, validation, and most notably AJAX, etc. This is basically just a wrapper for a simpler and easier-to-read version of javascript.
CSS: Takes the HTML and makes it pretty.
All three technologies work very well together if you know what you're doing.
I'm not sure if that's what you're looking for, but it sounds like you might want to invest in some beginner's literature.

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);
});

Allowing any property/attribute on a server/usercontrol

I've noticed that on most, if not all, standard web controls in the System.Web.UI.WebControls namespace, you can add any properties you want to them without crashing the page.
Take the asp:Button control for an example.
This code is perfectly valid:
<form runat="server">
<asp:Button runat="server" Text="Test button" crapAttribute="crapValue" />
</form>
Now, I've got a custom server control which crashes if I add arbitrary attributes to it. It only accepts attributes which have a corresponding public property defined.
The error I get is something like this "The control does not have a public property named "crapAttribute" ".
I would like my custom controls to accept any attribute without crashing. What do I need to do for that to work?
I've looked at the standard controls in Reflector and they do have all kinds of attributes and stuff but there was nothing that I saw which immediately caught my eye.
My custom controls are inheriting from WebControl for what it's worth.
You don't have to do anything in particular to allow arbitary attributes to be added the control markup. Things deriving from WebControl would normally scoop up these attributes and dump them in the Attributes collection.
I can't think of reason why this would fail. You would have to remember to render the Attributes collection in your implementation of Render if you have one.
Can you add a simple example of the code of a new control that fails to your question?
One way of doing it is adding the custom property in code behind
myCustomControl.Attributes.Add("customproperty", "value");
This should do the job for you.
However, I am interested in knowing how to do it in the server control itself.

should every element with runat=server have an id attribute?

I have inherited an asp.net website to maintain
when looking at the aspx page, almost every element with runat=server don't have id attribute defined.
should I go through every element and add one?
Unless the control is inside a repeating control it should have a unique ID attribute assigned to it. Here is some MSDN documentation on how to add server controls to an ASPX page.
You only need to give them ids if you're going to reference them in your code. If you're not referencing them at all you might wonder why they are .net controls and not just html elements.
ASP will assign an unique ID if you don't. Sometimes I don't bother when I won't be manipulating it.
Speaking specifically to your situation of having inherited an app, it's not a pressing issue. ASP.NET will automatically generate IDs for them at runtime.
Generally, aiming to replace those controls with HTML elements (as someone else mentioned) is a good idea. Do be careful though. Just because an element doesn't have an ID doesn't mean it's not being referenced on the server side at runtime.
You don't need to set IDs to the controls you don't reference. ASP.NET will do it for you. That's it.
This does NOT automatically mean, they can be replaced with HTML controls. Having a control with runat="server" without having an ID set is perfectly reasonable.
e.g.:
<asp:ListView runat="server" DataSourceID="someDataSource">

Resources