5
votes

So i have a ASP.NET 4 Custom Control called "SafeClickButton" which is designed to override the default behaviour of the client-side click (OnClientClick).

Essentially i'm trying to disable the button on click, then do any existing functionality (validation, postback, etc).

It looks to be correctly rendering the HTML (onclick="this.disabled=true;__doPostback...), and it is disabling correctly, but the problem is with the page validation. If any validation on the page has failed, its posting back and THEN showing the validation errors (where it should be done on client side without requiring a postback).

Here's the code for the custom control.

public class SafeClickButton : Button
    {
        public override string OnClientClick
        {
            get
            {
                return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(this, string.Empty));
            }
            set
            {
                base.OnClientClick = value;
            }
        }

        protected override PostBackOptions GetPostBackOptions()
        {
            PostBackOptions options = new PostBackOptions(this, string.Empty) {ClientSubmit = true};
            if (Page != null)
            {
                if (CausesValidation && (Page.GetValidators(ValidationGroup).Count > 0))
                {
                    options.PerformValidation = true;
                    options.ValidationGroup = ValidationGroup;
                }
                if (!string.IsNullOrEmpty(PostBackUrl))
                {
                    options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl));
                }
            }
            return options;  
        }
    }

What am i doing wrong?

EDIT

Okay so i found part of the problem:

return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(this, string.Empty));

Will not apply the dervied behaviour of the postbackoptions.

So i changed it to this:

return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(GetPostBackOptions()));

Now the validation is getting fired properly on the client side, but the button isn't re-enabled, FML =)

I think i need to be even smarted now, and say "If validation fails, re-enable button".

Any ideas?

1

1 Answers

3
votes

You should be able to just add the Page_ClientValidate method inline. I have never tried this so it might not work:

return string.Format("if (Page_ClientValidate()) { this.disabled=true; {0} } else return false;",
   Page.ClientScript.GetPostBackEventReference(this, string.Empty));

You might have to mess with it or add some checks to support GroupValidation but I think this will get you on the right path.

EDIT: I have updated the answer and moved you disable into the if so it only gets disabled when Page_ClientValidate fails.

Check out this link as it is doing what you are looking for I think and illustrates what I was meaning with the Page_ClientValidate:

http://msmvps.com/blogs/anguslogan/archive/2004/12/22/27223.aspx