Click here to Skip to main content
15,891,765 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm using a jQuery watermark plugin (watermark-1.2.jquery.min.js) to make textboxes have watermark text (e.g., the textbox will read as "First Name", but gets cleared when the user clicks the textbox). It's working fine for the most part, except for one niggling issue.

I have a few validators (e.g., RequiredFieldValidator) on the textboxes with EnableClientScript set to true. This means that when the textboxes don't contain valid data, an AJAX postback does not occur (say, when I click a button in the same validation group). Lucky for me, the watermark plugin clears the watermark before postback. However, that is a problem when validation fails and the postback is prevented, as the plugin clears the watermark even though a postback didn't occur.

I am hoping there is a JavaScript event ASP.NET provides so I can intercept a failed client-side validation and re-enable the watermark.

Note that I'm currently using add_pageLoaded to detect a page load after an AJAX postback and that is working fine. I just need to figure out how to call some code when the a button is clicked but the postback is aborted.

In the worst case, I can just disable client-side validation, but I'd rather not do that.

EDIT: Here is some sample code to demonstrate the issue (you can ignore the giant block of JavaScript, as I just embedded that so you can run this without external dependencies):
ASP.NET
<%@ Page Language="vb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
  <title>Sample of Blocked Ajax Postback Issue</title>
</head>
<body>
  <form runat="server">
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
    <!-- Contents of watermark-1.2.jquery.min.js -->
    <script type="text/javascript">
      (function (a) {
        var b = { init: function (c) {
          var d = this; return this.each(function (f) {
            var e = { watermarkText: "Enter Text", watermarkCss: "watermarkCss", disableAutocomplete: false };
            f === 0 && a(document.forms).bind("submit.watermark", d, b.formSubmit);
            c && a.extend(e, c); if (a(this).val().length === 0) e.isWatermarked = true;
            if (e["disableAutocomplete"] === true) a(this).attr("autocomplete", "off");
            else a(this).removeAttr("autocomplete");
            a(this).data("settings", e).bind("keypress.watermark", b.keypressProcessing).bind("focus.watermark",
            b.focusProcessing).bind("blur.watermark", b.blurProcessing).blur()
          })
        }, keypressProcessing: function () {
          var b = a(this).data("settings"); b.isWatermarked = false
        }, focusProcessing: function () {
          var b = a(this).data("settings");
          (a(this).val().length == 0 || a(this).val() == b.watermarkText && b.isWatermarked) &&
          a(this).val("").removeClass(b.watermarkCss)
        },
        blurProcessing: function () {
          var b = a(this).data("settings"); if (a(this).val().length == 0) {
            a(this).val(b.watermarkText).addClass(b.watermarkCss); b.isWatermarked = true
          }
        }, formSubmit: function (b) {
          a.each(b.data, function () {
            var b = a(this).data("settings"); a(this).val() == b.watermarkText && b.isWatermarked &&
            a(this).val("")
          })
        }
      }; a.fn.watermark = function (c) {
        if (b[c]) return b[c].apply(this, Array.prototype.slice.call(arguments, 1));
        else if (typeof c === "object" || !c) return b.init.apply(this, arguments);
            else a.error("Method " + c + " does not exist on watermark.") } })(jQuery)
    </script>
    <asp:ScriptManager runat="server" ID="mainManager" EnablePartialRendering="true" />
    <asp:UpdatePanel runat="server" UpdateMode="Conditional">
      <ContentTemplate>
        <p>
          <asp:TextBox ID="txtEmail" runat="server" />
          <asp:RequiredFieldValidator runat="server" ControlToValidate="txtEmail" Display="Dynamic"
            EnableClientScript="true" Text="*" ValidationGroup="Group1" />
          <asp:RegularExpressionValidator runat="server" ControlToValidate="txtEmail" Display="Dynamic"
            EnableClientScript="true" Text="*" ValidationGroup="Group1" ValidationExpression=".+@.+\..+" />
        </p>
        <p>
          <asp:Button ID="btnSubmit" runat="server" Text="Submit" ValidationGroup="Group1" />
        </p>
      </ContentTemplate>
    </asp:UpdatePanel>
    <script type="text/javascript">
      Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () {
        $("#" + "<%= txtEmail.ClientID %>").watermark({
          watermarkText: "Email",
          watermarkCss: "active_watermark"
        });
      });
    </script>
  </form>
</body>
</html>
Posted
Updated 26-Apr-12 13:32pm
v2
Comments
Peter_in_2780 26-Apr-12 18:48pm    
If I understand (and at this time of the morning it's an extra big IF!) your postback is blocked by a failing validator. Can you hook into the fail path in the validator to do your thing?
AspDotNetDev 26-Apr-12 19:37pm    
The "hook into the fail path" is the thing I'm having trouble figuring out how to do. I'm using an ASP.NET validator, and I'm not sure if there is a way to register for a fail event on an attempted postback. I updated my question with some sample code for your reference. I suppose I could create a custom client-side validator, but that seems like a lot of work for something that seems so simple.
Peter_in_2780 26-Apr-12 19:44pm    
Sorry, I don't do (or even read) ASP, so I can't make any concrete suggestion. My comment was more philosophical, in case you had a mental block about where to put something. Hopefully our discussion will catch the attention of someone who can help.

1 solution

Kind of crazy, and I highly don't recommend this as a final solution, but might give you some ideas:

override the javascript WebForm_DoPostBackWithOptions function.

<script type="text/javascript">
    //<![CDATA[
    var oldDoPostBack = WebForm_DoPostBackWithOptions;
    WebForm_DoPostBackWithOptions = function(options) {
        if (Page_ClientValidate(options.validationGroup))
        {
            options.validation = false;     // Don't validate twice
            oldDoPostBack(options);         // Call original post back function
        }
        else
        {
            alert("Validation Failed");
        }
    };
    //]]>
</script>


Maybe put this in the same script block as your add_pageLoaded code.
 
Share this answer
 
Comments
AspDotNetDev 29-Apr-12 17:18pm    
An interesting approach that gets my 5. However, it is still a bit too intrusive and inelegant for my tastes, so I will probably just do a an AJAX postback rather than use client-side validation. Still, your solution may be viable for somebody who must use client-side validation.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900