【问题标题】:Re-enable custom unobtrusive validator after loading form via Ajax通过 Ajax 加载表单后重新启用自定义不显眼的验证器
【发布时间】:2013-12-31 15:57:46
【问题描述】:

我在局部视图上有一个 ajax 表单,它使用自定义的非侵入式验证器作为非/或样式验证器 (described here)。在未通过 ajax 调用加载的表单上使用时,我的自定义验证器工作正常。但是,此部分是通过 @Ajax.ActionLink 调用加载的,该调用将部分加载到包含视图中。

包含视图:

<div id="form-container">
    @Html.Action("Login", "MyController") //Initial state. Loads Login.cshtml partial view
</div>

Login.cshtml 部分:

//contains markup for login form fields, but also this link to the signup partial (Signup.cshtml) 
@Ajax.ActionLink("click here", "Signup", "MyController", 
    new AjaxOptions
    {
        OnSuccess = "initializeValidation();", 
        InsertionMode = InsertionMode.Replace, 
        UpdateTargetId = "form-container"
    })

Signup.cshtml 部分:

@model SignupViewModel
<div>
    @using (Ajax.BeginForm("Signup", "MyController", new AjaxOptions
                            {
                                OnSuccess = "initializeValidation();",
                                InsertionMode = InsertionMode.Replace, 
                                UpdateTargetId = "form-container"
                            }))
    {
    <p>
        @Html.LabelFor(m=>m.Username)
        @Html.EditorFor(m=>m.Username)
        @Html.ValidationMessageFor(m=>m.Username)
    </p>
    <p>               
        @Html.LabelFor(m=>m.Email)
        @Html.EditorFor(m=>m.Email)
        @Html.ValidationMessageFor(m=>m.Email)
    </p>        
    <input type="submit" value="Next"/>
    }
</div>

我的 javascript 方法 initializeValidation() 具有以下代码来重置不显眼的验证:

$('form').removeData("validator");
$('form').removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse('form');

我遇到的问题是自定义验证器不适用于通过@Ajax.ActionLink 加载的表单。我查看了this questionthis question,它们正确地重置了标准的非侵入式验证方法,但我不知道如何重置自定义方法。自定义验证方法及其不显眼的适配器配置如下代码

$.validator.addMethod("eitherorrequired", function (value, element, params) {
    var otherValue = $(params).val();
    return value != "" || otherValue != "";
});
$.validator.unobtrusive.adapters.add("eitherorrequired", ["dependentproperty"], function (options) {
    options.rules["eitherorrequired"] = "#" + options.params.dependentproperty;
    options.messages["eitherorrequired"] = options.message;
});

我已经尝试在 initializeValidation() 方法中包含它,但它仍然不起作用。

【问题讨论】:

  • 曾经调用过initializeValidation 函数吗?
  • 是的,我已经在其中放入了 console.log 语句,并且在加载新部分时肯定会调用它。
  • 我认为问题在于与任何输入控件关联的验证没有自定义验证器的 data-val 属性。一种解决方案是使用流利的并尝试从模型验证器或手动注入客户端验证为该输入创建此 data-val 属性。
  • 您的输入字段是否在Html.BeginFormAjax.BeginForm 内?里面一样偏吗?或者是部分之外的表单声明,您只刷新输入字段而不是整个表单?
  • @DarinDimitrov 输入字段位于部分的 Ajax.BeginForm 语句中。 BeginForm 方法的 AjaxOptions 参数引用包含视图中的 UpdateTargetId,而不是局部视图本身。

标签: jquery asp.net-mvc asp.net-mvc-3 validation unobtrusive-validation


【解决方案1】:

事实证明,我的自定义验证器方法没有考虑到我的输入元素的名称中带有下划线的事实(因为我的视图模型类有一个属性暴露了另一个对象,该对象包含表示表单域)。

我的视图模型是这样的:

public class MyViewModel
{
    public Info Step1 { get; set; }

    public class Info
    {
         public string Property1 { get; set; }

         [EitherOrRequired(DependentProperty="Property1")]
         public string Property2 { get; set; }
    }
}

这会产生 ID 为 Step1_Property1Step1_Property2 的输入元素。问题是 Step1_Property2 输入的 data-val-dependentproperty 设置为“Property1”(视图模型中的属性值),因此自定义验证器方法会查找不存在的依赖属性。为了克服这个问题,我修改了自定义验证器函数,以确保依赖属性与当前属性具有相同的前缀。

$.validator.addMethod("eitherorrequired", function(value, element, params) {
    var name = $(element).attr('name').replace('#', '');
    var i = name.lastIndexOf('.');
    if (i > -1) {
        params = '#' + name.substr(0, i).replace('.', '_') + '_' + params.replace('#', '');
    }
    var otherValue = $(params).val();
    return value != "" || otherValue != "";
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多