3

When I have this in the page markup it works fine:

<script type="text/javascript">
    function bought1()
    {
        var s = '<%= Button2.ClientID %>';
        var v = document.getElementById(s);
        v.click();
    }    
</script>

But when I have the same thing in a separate file, even though the function is executed - the value of v remains null.

I tried with a simple div and it did find the div.

Why doesn't it find the ASP.net Button?

EDIT

I even added ClientIDMode="Static" to the Button. No change.

ispiro
  • 26,556
  • 38
  • 136
  • 291
  • You checked the actual rendered html on both pages? – Darren Wainwright Jul 17 '13 at 14:49
  • @Darren I checked with IE and FF js debuggers - they both give a `null` for `v`. – ispiro Jul 17 '13 at 14:53
  • An immediate "fix" would be to give it a class and target that class. When put in a separate JS file, the `<%= Button2.ClientID %>` does **not** get evaluated because JavaScript files are not evaluated by the ASP.NET server - they are served statically. – Ian Jul 17 '13 at 14:53
  • @ispiro - i mean view the actual source. See what gets rendered for `var s = '<%= Button2.ClientID %>';` etc... – Darren Wainwright Jul 17 '13 at 14:54
  • also, as @ian says - the server tags `<% %>` won't work in a separate .js file. – Darren Wainwright Jul 17 '13 at 14:55
  • @Darren It only shows ``. – ispiro Jul 17 '13 at 14:57
  • @ispiro If you use `ClientIDMode="Static"`, then change your code to: `var s = 'Button2';` (and make sure you clear your browser's cache and reload the page) – Ian Jul 17 '13 at 14:59
  • @Ian I did change it to `'<%= Button2 %>'`. But from Win's answer, assuming it's correct, I see that that won't help. (`Button2` will of course.) Thanks. – ispiro Jul 17 '13 at 15:02
  • @ian - he meant change it to `var s = 'Button2';` and not `var s = '<%= Button2 %>';` - do this after putting `ClientIDMode="Static"` on your button – Darren Wainwright Jul 17 '13 at 15:23

4 Answers4

9

<%= Button2.ClientID %> is a server code. You cannot run server code in a separate javascript file.

If you want to access Server Control ID from separate javascript, you need to make the ClientIDMode to either preditable or static.

Here is an example.

The following is a code. It is not a good example, but I hope you get the idea.

Note: Make sure you do not have same Ids when you use ClientIDMode="Static". Otherwise, Ids will collide. For example, one in master page and one in content page.

ASPX

<script src="/JavaScript1.js"></script>
<asp:Button runat="server" ID="Button1" ClientIDMode="Static" 
    Text="I am a button" />
<div onclick="bought1()">Click Me</div>

Javascript File

function bought1() {
    var s = 'Button1';
    var v = document.getElementById(s);
    v.click();
}

enter image description here

Win
  • 61,100
  • 13
  • 102
  • 181
4

Win is correct, your separate JS file will not be rendered by ASP.net.

However, if you simply put

<script type="text/javascript">
        var s = '<%= Button2.ClientID %>';
</script>

above where you load your external file, you will load the value into a global on the page that will be accessible from any scripts loaded after it. Just make sure to give it a name that wont collide with any libraries you have loaded.

MaxPRafferty
  • 4,819
  • 4
  • 32
  • 39
2

You should Change the function like this:

function bought1(clientId)
{
    var s = clientId;
    var v = document.getElementById(s);
    v.click();
}    

and would call it in your page markup:

bought1('<%= Button2.ClientID %>')
Abbas Amiri
  • 3,074
  • 1
  • 23
  • 23
1

Alternatively, if you want to avoid the messiness of JS globals and dumping asp.net variables altogether, just wrap your button and use a queryselector (or jquery, etc) to grab it:

asp.net:

<div id="button-container">
        <asp:Button ID="button" runat="server" />
</div>

JS:

<script type="text/javascript">
    function bought1()
    {
        var v = document.querySelector("#button-container input");
        v.click();
    }    
</script>
MaxPRafferty
  • 4,819
  • 4
  • 32
  • 39
  • Or `document.getElementById("button-container").children[0]`. Good idea though :) – Ian Jul 17 '13 at 15:24
  • I mostly just like document.querySelector, heh. Also i couldn't remember if .net added any other markup around the button, but thankfully it doesn't. – MaxPRafferty Jul 17 '13 at 15:35
  • Oh I do too, I just thought for this very specific example, my example would work too, and have "better" browser support. Yeah, luckily for a button, it doesn't add extra markup, but would ruin my solution if it did. – Ian Jul 17 '13 at 15:40
  • Yep, getElementById is definitely the way to go for anybody targeting a wide audience. – MaxPRafferty Jul 17 '13 at 15:44