How can I replace a function name using JavaScript and have it be recognized as a function?

1.7k views Asked by At

I am trying to replace the JavaScript onclick event handler in ASP.NET that is added to a button control when using validation controls. This is what is output into the HTML from ASP.NET in this scenario:

<input type="image" name="ibSubmit1" id="ibSubmit1" src="button-green-submit.gif" onclick="showProgress1();WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;ibSubmit1&quot;, &quot;&quot;, true, &quot;Group1&quot;, &quot;&quot;, false, false))" style="border-width:0px;" />

I have looked pretty estensively, and unfortunately there doesn't seem to be a way to modify the function server side before it is injected into the page.

Since I am developing a control and desire it to be non-invasive and self contained, and I am interested in obtaining the validationGroup parameter of the WebForm_PostBackOptions object, it seems that the easiest solution would be to use JavaScript to replace the WebForm_DoPostBackWithOptions function name with my custom wrapper function and leave all of the rest of the parameter information intact - then I can extract the information I am interested in, call my custom functions, and then forward the call on to WebForm_DoPostBackWithOptions.

NOTE: I am using jQuery to build my custom function, so if there is an easier way to do this with jQuery it is an option I will consider.

Here is the code I tried to replace the onclick event handler (not working):

    $('[onclick*=WebForm_DoPostBackWithOptions]').each(function() {
        var txt = this.onclick;
        txt = txt + '';
        txt = txt.replace('WebForm_DoPostBackWithOptions','ml_DoPostBackWithOptions');
        this.onclick = eval(txt);
    });

Using alert(), I verified that the text is being changed correctly, however whether or not I use the eval() function, the onclick handler doesn't seem to recognize it as JavaScript.

I thought of using a regular expression to get the validationGroup value, but this seems like it will be far more elegant and flexible if I can get it working...

Note: If there is a way for my control to interrogate the page it is on to find all of the buttons that will post back (regardless of what type of buttons they are) so I can retrieve the property server-side, this is also something I will consider.

3

There are 3 answers

7
Guffa On BEST ANSWER

The attribute value is wrapped in a function when the HTML is parsed, so it would be tricky to get the original string back. You can get the string representation of the function, but then you would have to parse out the code inside the function.

Why not just redefine the function that is called? Put this at the end of the page:

<script type="text/javascript">

(function(){

  // keep the original
  var previous = WebForm_DoPostBackWithOptions;

  WebForm_DoPostBackWithOptions = function(options) {
    // do what you want with the options here
    // then call the original
    previous(options);
  }

})();

</script>
0
Brian Mains On

Typically, in ASP.NET, to disable this for a button, you do:

And this gets passed to the client-side onclick, and the return false; prevents the default implementation. That's how to do it from the server; from the client, you need to wipe out the onclick altogether and reimplement it.

I don't know that I understand what you are trying to do... why are you doing it this way? Are you doing it to pass back extra data? If so, there are other ways to implement...

5
Daniel Dyson On

If you are just trying to insert functionality to the click event, then you can use the click() function of jQuery. It adds the function call to the start of the click event and then allows the default behaviour to occur, in this case a form submission:

 $(function() {
    $('[onclick*=WebForm_DoPostBackWithOptions]').click(function(event) {  

        //call your custom functions here and then do nothing, the 
        //default click event will still occur. If you don't want it to
        //propagate, call event.preventDefault();

        var txt = this.onclick;
        txt = txt + '';
        txt = txt.replace('WebForm_DoPostBackWithOptions','ml_DoPostBackWithOptions');
        setTimeout(txt,0);

        //event.preventDefault();  
        //or
        //event.stopPropagation();  
    });
 });

Note that in the example that you have given, showProgress1(); will get called twice.