【问题标题】:Custom clientside validation for required at least one in array数组中至少需要一项的自定义客户端验证
【发布时间】:2014-06-23 14:10:55
【问题描述】:

我有以下自定义属性,用于验证数组是否已提交值:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class RequiredArrayAttribute : RequiredAttribute, IClientValidatable
{
    public RequiredArrayAttribute()
        : base()
    {
    }

    public override bool IsValid(object value)
    {
        var list = (IList)value;

        if (list != null && list.Count > 0)
        {
            return true;
        }

        return false;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        string errorMessage = this.ErrorMessage;

        // Get the specific error message if set, otherwise the default
        if (string.IsNullOrEmpty(errorMessage) && metadata != null)
        {
            errorMessage = FormatErrorMessage(metadata.GetDisplayName());
        }

        var clientValidationRule = new ModelClientValidationRule()
        {
            ErrorMessage = errorMessage,
            ValidationType = "requiredarray"
        };

        return new[] { clientValidationRule };
    }
}

适用于

[RequiredArray(ErrorMessage = "Please select at least one product")]
public IEnumerable<string> ProductIds { get; set; }

以及下面的js(包括在jquery.js、unobtrusive-ajax.js、validate.js和validate.unobtrusive.js之后)

(function ($) {
    $.validator.addMethod('requiredarray', function (value, element, params) {
        var selector = 'input[name=' + $(element).attr('name') + ']:checked';
        return $(selector).length > 0;
    }, 'Clientside Should Not Postback');

    $.validator.unobtrusive.adapters.addBool('requiredarray');
})(jQuery);

我尝试将 addMethod 更改为 return false; 但这仍然没有任何作用(并且我的控制台中没有错误)

我想知道是否有人能发现我在上面的代码中做错了什么。我用地址属性做了类似的事情,它工作得很好,但由于某种原因我不能让这个工作?

此外,服务器端验证工作。

验证消息的剃刀代码

@Html.ValidationMessageFor(m => m.ProductIds)

渲染复选框的示例 html:

<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" />
<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />

编辑

除此之外,我现在可以使用以下方法进行客户端验证

$.validator.addClassRules('required-group', { 'requiredarray': true });

而不是上面的validator.unobtrusive.adapters.addBool 方法。我还在复选框中添加了 required-group

但是,如果我使用它,它不会添加正确的 MVC 错误消息,只会添加上面代码中设置的 Clientside Should Not Postback。我尝试将以下属性添加到复选框:

 data-val="true" data-val-required="Please select at least one sample"

还尝试使用data-val-requiredarray,但这没有区别,所以有谁知道如何更改上述客户端规则以使其使用 MVC 错误消息

【问题讨论】:

  • 显示所有相关的渲染代码。渲染的.validate() 方法在哪里?整个表单的渲染 HTML 在哪里?
  • @Sparky MVC 处理所有验证内容,因此没有完整表单的代码,它只是很多相同的复选框,末尾有一个提交按钮
  • 我意识到这一点。但是,jQuery Validate 仍然是 JavaScript,如果不先初始化它就无法运行。初始化方法为.validate()。所以必须有 .validate() 方法在客户端某个地方呈现......也许在包含的 js 文件中。
  • 这可能不是答案。但是,为什么您要在自定义方法中构造选择器?你认为element 参数代表什么?它是选择器本身。获取给定元素,找到它的名称,然后使用该名称首先找到您已经拥有的元素,这是不必要的循环。
  • 那个选择器应该让我看到所有具有该名称的复选框都被选中。我认为元素只是当前元素被选中/未选中

标签: jquery asp.net-mvc-4 jquery-validate unobtrusive-validation


【解决方案1】:

因此,通过对 html 进行以下更改来解决此问题:

<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" data-val-required="Please select at least one sample" />
<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />

data-val-required 只需要在数组中的第一个复选框上。然后使用以下 jQuery:

(function ($) {
    $.validator.addMethod('requiredarray', function (value, element, params) {
        return $('input[name=' + $(element).attr('name') + ']:checked').length > 0;
    }, 'Please select at least one');

    $.validator.addClassRules('required-group', { 'requiredarray': true });

    var errorMessage = $('.required-group').eq(0).data('val-requiredarray');
    if (errorMessage && errorMessage !== "") {
        $.validator.messages.requiredarray = errorMessage;
    }
})(jQuery);

我已将addBool 更改为addClassRules,然后使用$.validator.messages 设置错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多