ASP.Net + jQuery + jQuery验证插件+ UpdatePanel + nyroModal - 在每个字段上成功触发!

时间:2009-05-12 01:40:49

标签: jquery asp.net-ajax updatepanel jquery-validate nyromodal

我有一个表单,其中包含用户使用价格(数字)填充的输入字段列表。我已将其css类设置为“required”和“number”,以便jQuery验证插件相应地验证它们。一切都运作得很好。当每个字段不是数字或缺少值等时,会显示错误。

这整个表单实际上是在nyroModal(jQuery插件)模型弹出窗口中。但这无关紧要,它只是一个.aspx网页形式。在其中,我还使用了UpdatePanel并将所有内容放入其中,因为我的表单基本上是一个2阶段的过程。用户必须在表单的第一个“页面”上完成一些基本步骤。当验证并运行时,我只是隐藏/显示UpdatePanel中的一些元素,向用户显示表单的下一个“页面”,即上述所有价格文本框输入字段。

我使用ImageButton作为验证表单的触发点。默认情况下,如果您只是按原样保留ImageButton,.Net将在我的情况下触发回发,AJAX回发,因为它全部发生在UpdatePanel中。这也是期望的。出于显而易见的原因,我不想要一个丑陋的完整回发。

经过大量阅读后,我需要一种方法在javascript中附加.Net的PageRequestManager,这样我就可以在.Net想要回发时拦截,基于jQuery是否成功验证了表单。所以我的逻辑说:默认情况下,不允许回发,但是当jQuery成功验证表单时,设置一个变量,表示现在允许回发,然后下次回发尝试发生时,它将通过。因此向用户显示成功。

这种方法运作得相当好,但最后还有一个问题。

jQuery验证插件的validate({success})选项似乎在每个单独的字段验证成功后错误地触发,而不是整个表单。即如果我在任何一个价格输入字段中输入一个数字,这个成功选项将触发并将我的cancelPostback变量设置为false,这反过来意味着表单现在提交即使它尚未经过验证,只是因为一个字段是有效。我希望这个验证({success})选项只在整个表单验证后触发。

我是否错误地解释了这一点,实际上它正在做它的意思? 如果是这样,我怎样才能在验证整个表格时简单地将cancelPostback变量设置为true?

感谢大家提供任何见解或提醒。

我实现验证并拦截.Net回发事件的jQuery代码如下:

<script type="text/javascript">
    // By default, don't allow Postback until we've successfully validated our form on the client-side.
    var cancelPostback=true;

    // Every single time the page loads, including every single AJAX partial postback
    function pageLoad()
    {
        // Reset the value to say that "We don't allow Postbacks at this stage"..
        cancelPostback=true;

        // Attach client-side validation to the main form
        $("#<%= form1.ClientID %>").validate({ success: function() { alert('validation succeeded!'); cancelPostback = false; } });

        // Grab a reference to the Page Request Manager
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_initializeRequest(onEachRequest);

        alert("Page Load");
    }

    // Our own custom method to be attached to each new/future page request..
    function onEachRequest(sender, args)
    {
        alert("About to cancel? " + cancelPostback);
        // Check to see if we need to Cancel this Postback based on Conditional Logic within this page..
        args.set_cancel(cancelPostback);
    }
</script>

3 个答案:

答案 0 :(得分:3)

我的解决方案有问题,因为除了IE之外的所有浏览器都在jQuery验证器的submitHandler()函数之前触发了“onEachRequest”函数。我提出了一个更优雅的解决方案,如果验证失败,只需取消回发,而不是依赖于预设变量。

  Sys.Application.add_init(function() {
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_initializeRequest(onEachRequest);
  }); 

  function onEachRequest(sender, args) {
    if (args.get_postBackElement().id == <%= [YourSubmitButton].ClientID %>) {
      args.set_cancel(!$('#aspnetForm').valid());
    }
  }

答案 1 :(得分:1)

我建议查看submitHandler和invalidHandler选项。一个或另一个应该为你想要的东西工作。我认为,最好的方法是默认允许回发,并在invalidHandler中将cancelPostback设置为true。或者,您可以编写自己的submitHandler,直接调用__doPostBack并通过ImageButton替换提交。

答案 2 :(得分:1)

非常感谢tvanfosson的快速帮助。

好的更新:

我关注了越来越多的链接,最终找到了“成功”的文档。插件自己的主页上的文档是可怕的,并省略了许多关键功能:)但在官方的jQuery页面上它“更好”。 “成功”选项旨在每次成功验证单个字段时触发。所以这是设计工作,我错误地认为它只会在整个表格有效时触发。

我尝试了你的invalidHandler想法。我喜欢这个主意。我遇到的一个问题是ImageButton的回发仍然总是首先触发,所以它会在invalidHandler代码运行之前开始回发。所以回发仍然会继续,然后在此之后,invalidHandler将禁用未来的回发,不幸的是他们以错误的顺序触发。但除此之外,它表明了其他所有标志都是完美的解决方案。

然后我采用另一种方式尝试submitHandler方式,即反向。再次,这遭受了一些订单问题,因为回发将再次开火,但被阻止,然后submitHandler将允许未来的回发,但它已经太晚了,所以这个回发被错过了。您必须再次单击该按钮两次以使其继续运行。

所以最终的半便利解决方案,说实话并不是太糟糕了:

我将此行更改为:             //将客户端验证附加到主表单             $(“#&lt;%= form1.ClientID%&gt;”)。validate({submitHandler:function(){PreventPostback = false; __doPostBack('UpdatePanel1','');}});

正如您所看到的,首先切换PreventPostback变量,然后手动触发新的回发,因为第一次回发已经被阻止并且已经死掉。因此,本手册__doPostBack调用可确保在关注PreventPostback的新值时触发新的回发。

我从ImageButtons后面删除了事件方法,并在服务器端代码中创建了一个名为“DoPostBackLogic()”的新方法,该方法仅在页面回发时调用,我知道该方法必须来自此验证逻辑,因为这是我的表单上唯一可能发生的回发。然后所有的隐藏/显示/保存逻辑都在那里发生。这意味着当我手动调用__doPostBack时,我可以简单地使用UpdatePanel的ID而不用担心模仿特定的ImageButton等。

这种方式完美无缺。默认情况下禁用回发,当表单有效时,允许回传,但手动触发回发以使新值生效。

所以这基本上是你的第二个解决方案,再次感谢收听和分享! :)