views:

1323

answers:

4

I have an ASP.NET page with a number of ASP:Button instances on it. For some, I need to show a confirmation prompt and, should the user choose yes, the original postback method is called. Otherwise, the overall process is cancelled.

I've got an example running but I get inconsistent results, mainly in FF3 where I get an exception thrown:

[Exception... "Illegal operation on WrappedNative prototype object"  nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)"  location: "JS frame ::

I've looked this error up but I'm drawing a loss as to where I'm going wrong. Here's my example case. Note, for now I'm just using the css class as a lookup. Longer term I can embed the clientID of the control into my JS if it proves necessary :).

Html fragment:

<asp:Button ID="StartButton" runat="server" CssClass="startbutton" Text="Start" OnClick="OnStartClicked" />

Javascript:

$(".startbutton").each(function(){
            $(document).data("startclick", $(this).get()[0].click);
            $(this).unbind("click");
        }).click(function(){
            var oldclick = $(document).data("startclick");
            alert("hello");
            try
            {
                oldclick();
            }
            catch(err)
            {
                alert(err);
                alert(err.description);
            }
            return false;
        });

My code behind is relatively simple, the OnStart method simply executes a Response.Write

I've only just started looking into bind, unbind and trigger so my usage here is pretty much 'first time'.

Thanks for any help or advice.

S

EDIT:

This describes what I'm trying to do and also gives a run down of the kind of pitfalls:

http://www.nabble.com/onClick-prepend-td15194791s27240.html

+2  A: 

How about this?

$(document).ready( function() {
    $('.startbutton').click(function() {
        return confirm('Are you sure?');
    })
});
elo80ka
Unfortunately, the event listener set by asp.net (onclick="...") will still be called, even if you return false from a jQuery handler.
ybo
Thanks but I'm unsure how that would work with BlockUI. My understanding is that I'd have to trigger the original click event (the postback) in my 'yes/ok' handler. That the case?
Simon
@ybo: It works fine for me (ASP.NET 2.0, VS2005). When did it fail for you?@Simon: Let me take a quick look through the BlockUI documentation; I'll post some updated code.
elo80ka
@elo80ka, my bad, you're totally right, my assumption was correct only for asp:buttons UseSubmitBehaviour="false", which is not the default value. +1 to your solution.
ybo
A: 

Your problem comes from here :

$(document).data("startclick", $(this).get()[0].click);
...
var oldclick = $(document).data("startclick");
...
oldclick();

Here, you try to intercept a native event listener but there are two errors :

  1. Using unbind will not remove the native event listener, just the ones added with jQuery
  2. click is, AFAIK, a IE only method used to simulate a click, it not the event handler itself

You'll have to use onclick instead set its value to null instead of using unbind. Finally, don't store it in $(document).data(...), you'll have some problems when you add other buttons. Here is a sample code you can use :

  $("selector").each(function()
  {
    var oldclick = this.onclick;
    this.onclick = null;
    $(this).click(function()
    {
      if (confirm("yes or no ?")) oldclick();
    });
  });
ybo
I tried this by wrapping the contents of the click in a try-catch. In IE7 oldclick() raises an 'object expected' error and in FF3 I get 'TypeError: oldclick is not a function'. I put an alert on this.click and this.onclick and onclick consistently returned null. Thanks for the pointers though!
Simon
+1  A: 

I've solved my problem for IE7 and FF3.

The trick is to make the postback work as an 'onclick' via an ASP.NET attribute on the button (see below). In Javascript this gets pulled out as a function reference when you read the click in JQuery.

To make it work, you then clear the onclick attribute (after saving it) and call it later on.

My code below shows it in action. This code isn't complete as I'm part way through making this into a generic prompt for my application. Its also a bit badly laid out! But at least it shows the principle.

ASP.NET button

<asp:Button ID="StartButton" runat="server" CssClass="startbutton" Text="Start" OnClick="OnStart" UseSubmitBehavior="false" />

Javascript:

$(".startbutton").each(function(){
            $(document).data("startclick", $(this).attr("onclick"));
            $(this).removeAttr("onclick");
        }).click(function(){

            $.blockUI({ message: $('#confirm'), css: { width: '383', cursor: 'auto' } }); 

            $("#yes").click(function(){ 

                $.unblockUI();
                var oldclick = $(document).data("startclick");
                try
                {
                    oldclick();
                }
                catch(err)
                {
                    alert(err);
                    alert(err.description);
                }
            });

            $("#no").click(function(){
                $.unblockUI();
            });


            return false;
        });
Simon
A: 

for mi works: this.OnClientClick = "$.blockUI({ message: $('#ConfirmacionBOX'), css: { width: '275px' } });return false;"; This is a button (is a button class)