views:

1270

answers:

5

Hello,

I am developing a user control (ascx) in ASP.NET which uses javascript for manipulating controls. Currently the javascript code is inlined and uses <%= somecontrol.ClientID %> to get the control it needs.

I want to put the javascript file in external file but from external file I cannot use the above syntax for retrieving controls. I have read about possible solutions in this and this answers but the problem is that the user control can be placed multiple times on page. This means that the Controls array (mentioned in the answers) will be rendered several times with different items. As a result the script will not be able to retrieve the id it needs. If I put <%= ClientId %> in the name of array that holds items then I will have the same problem as I am trying to solve.

Any ideas?

A: 

What about a hidden variable:

<input type="hidden" id="ClientId" value="<%=ClientId %>">

Then from your js:

$("#" + $("#ClientID").val())

Or, put the hash in:

<input type="hidden" id="ClientId" value="#<%=ClientId %>">

...

$($("#ClientID").val())
James Wiseman
If I place the control several times on the page then the hidden variable will be several too.
Giorgi
+1  A: 

The way I solve this problem is to use CSS classes or place the controls within containers with known IDs and then traverse into the container's children to get the actual controls. For example:

<asp:TextBox ID="Something" runat="server" CssClass="mycontrol" ... />

Could be accessed via:

jQuery('.mycontrol');

Or:

<div id="ControlContainer">
    <asp:TextBox ID="Something" runat="server" ... />
</div>

Could be accessed via:

jQuery("#ControlContainer input[type='text']");

The only real problem with this approach is you're tying your code to specific markup on the page, which can be a hassle if the markup changes a lot.

Rudism
I think using an alternative method to identify the controls in question, like CSS classes, is the way to go.
Jeff Siver
I do not think it is a good solution as if I place multiple controls on the same page they will have same class. Also selecting a control by class is slower compared to id.
Giorgi
You could render the "ControlContainer" parent element within the user control, and make its ID something that you specify as an attribute passed to the user control. That way it would be unique per instance on the page. Then the javascript calls in the control could pass that container ID to functions defined in the external JS file which it could use to select the specific controls within that instance's container. You are right that selecting by class is slower than selecting by ID, but the difference would probably be measured in fractions of milliseconds per operation.
Rudism
+2  A: 

Ok, a different approach, that I try to use a JavaScript-class style, and then initialize it for each control.

In the external javascript file, write your code as:

function oNameCls(ControlId1) {

    this.ControlId1 = ControlId1;

    this.DoYourWork1 = function() {
        // use the control id.
        // this.ControlId1
    }    
    this.DoYourWork2 = function() {
        // use the control id.
        // this.ControlId1
    }    

}

And on the control do the call like that.

<script language="Javascript" type="text/javascript">
    // init - create
    var <%=this.ClientID%>MyCls = new oNameCls(<%=Control1.ClientID%>);
    // do your work
    <%=this.ClientID%>MyCls.DoYourWork1();
</script>

Hope now help better.

Aristos
This will not work for me. I have considered this but I am designing a user control not a page.
Giorgi
Ok, sorry, my english is not that great, I miss that - I will update my idea... or delete for now and think again.
Aristos
I have change the idea ! This work for sure :)
Aristos
A: 

If you want to find a specific control when there could be multiple copies, this can't be done. How would the external javascript know which of the n controls you wanted?

How can rig the behavior up to a class and find the elements relative to the position of the action control, like this:

UserControl:

<div class="myControl">
  <asp:Button id="MyButton" runat="server" Text="Click Me" />
  <div style="display:none;">Show me!</div>
</div>

If you jQuery was written to be relative like this:

$(".myControl input").click(function() {
  $(this).next().slideDown();
});

In this case, it doesn't matter what the specific IDs are, as long as you can navigate the DOM relatively to the controls you need. Even if it's more complex like .closest("div").next().find(".bob").prev()...whatever you need to get there works.

Nick Craver
The javascript file is included in the user control itself, not the page.
Giorgi
@Giorgi - Wherever it comes from, it ends up on the page, make sure you're registering it and not including it every time with the user control though.
Nick Craver
@Nick, every user control and controls inside it have different clientids. What I am trying to achieve is that the javascript code processed only that control which included it.
Giorgi
A: 

hey! i got some problem I need another way( without using <%=____%>) to get controls client id in javascript

Bharat
Use a literal control on the point you won to get the clientid, and then write on your literal control, the clientid on pageload.
Aristos
hey - I think that this place is for answers not for questions....
Aristos