ASP.Net+;jQuery+;jQuery验证插件+;UpdatePanel+;nyroModal-成功向每个战场开火!

ASP.Net+;jQuery+;jQuery验证插件+;UpdatePanel+;nyroModal-成功向每个战场开火!,jquery,asp.net-ajax,updatepanel,jquery-validate,nyromodal,Jquery,Asp.net Ajax,Updatepanel,Jquery Validate,Nyromodal,我有一个表单,其中包含用户用价格(数字)填充的输入字段列表。我已经将它们的css类设置为“required”和“number”,以便jQuery验证插件相应地验证它们。所有这些都非常有效。当每个字段不是数字或缺少值等时,将显示错误 整个表单实际上位于nyroModal(jQuery插件)模型弹出窗口中。但这不重要,不管怎样,它只是一个.aspx web表单。在其中,我还使用了UpdatePanel并将所有内容都放在其中,因为我的表单本质上是一个两阶段的过程。用户必须在表单的第一个“页面”上完成一

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

整个表单实际上位于nyroModal(jQuery插件)模型弹出窗口中。但这不重要,不管怎样,它只是一个.aspx web表单。在其中,我还使用了UpdatePanel并将所有内容都放在其中,因为我的表单本质上是一个两阶段的过程。用户必须在表单的第一个“页面”上完成一些基本步骤。当验证并运行时,我只需隐藏/显示UpdatePanel中的一些元素,向用户显示表单的下一个“页面”,即上面描述的所有price textbox输入字段

我使用ImageButton作为验证表单的触发点。默认情况下,如果您只保留ImageButton的原样,.Net将触发回发,在我的例子中是AJAX回发,因为它都发生在UpdatePanel中。这也是我们想要的。我不想要一个丑陋的完整的回发,原因很明显

在大量阅读之后,我需要一种用javascript连接到.Net的PageRequestManager的方法,以便在.Net想要执行回发时,根据jQuery是否成功验证了表单进行拦截。因此,我的逻辑是:默认情况下,不允许回发,但当jQuery成功验证表单时,设置一个变量,表示现在允许回发,然后下次回发尝试时,它将通过。并因此向用户显示成功

这一切都相当顺利,但还有最后一个问题

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

//默认情况下,在客户端成功验证表单之前,不允许回发。
var cancelPostback=true;
//每次加载页面时,包括每次AJAX部分回发
函数pageLoad()
{
//重置该值,表示“我们在此阶段不允许回发”。。
取消回发=真;
//将客户端验证附加到主窗体
$(“#”).validate({success:function(){alert('validation successed!');cancelPostback=false;}});
//获取对页面请求管理器的引用
var prm=Sys.WebForms.PageRequestManager.getInstance();
prm.添加初始化请求(onEachRequest);
警报(“页面加载”);
}
//我们自己的自定义方法将附加到每个新的/未来的页面请求。。
函数onEachRequest(发送方,参数)
{
警报(“即将取消?”+取消回发);
//检查是否需要基于此页面中的条件逻辑取消此回发。。
参数设置\取消(取消回发);
}

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

感谢heaps tvanfosson的及时帮助

Ok更新:

我跟踪了越来越多的链接,最终找到了“成功”的文档。插件自己主页上的文档很糟糕,并且省略了许多关键特性:)但是在官方jQuery页面上它“更好”。“成功”选项意味着每次成功验证单个字段时都会触发。所以这是设计的,我错误地认为它只有在整个表单有效时才会触发

我试过你的想法。我喜欢这个主意。我遇到的一个问题是ImageButton的回发始终会首先触发,因此它会在invalidHandler代码运行之前开始回发。因此回发仍将继续,然后,invalidHandler将禁用未来的回发,不幸的是,它们以错误的顺序发射。但除此之外,它还显示出了其他一切完美解决方案的迹象

然后我走了另一条路,尝试服从者的方式,即相反的方式。同样,这也遇到了一些顺序问题,因为回发将首先再次启动,但被阻止,然后submitHandler将允许将来的回发,但已经太晚了,因此此回发被错过。你必须再按两次按钮才能启动它

所以最后一个半笨拙的解决方案,老实说也不算太糟,是:

我将此行更改为: //将客户端验证附加到主窗体 $(“#”).validate({submitHandler:function(){PreventPostback=false;u doPostBack('UpdatePanel1','');})

如您所见,首先切换PreventPostback变量,然后触发
  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());
    }
  }