Parsley.js 自定义验证器中的动态消息

Parsley.js Dynamic messages in custom validator

我正在使用自定义验证器来检查出生日期,到目前为止它几乎什么都没有,但我正在尝试根据错误添加动态消息但它对我不起作用它显示容器有一条空白消息,有什么想法吗?

这是自定义验证器的一段代码:

window.Parsley.addValidator('age', {
            validate: function(value, id){
                switch(id){
                    case 'main':
                        var day = $('#birthdate_day').val();
                        var month = $('#birthdate_month').val();
                        var year = $('#birthdate_year').val();
                        if(!day || !month || !year){

                            window.Parsley.addMessage('en', 'age','Error1 ');

                            return false;
                        } else {
                            window.Parsley.addMessage('en', 'age','Error 2');
                        }
                    break;
                }
                return true;
            },
            messages: {
                en: 'Default error',
            }
        });

我试过的另一件事是在执行验证期间设置 data-parsley-age-message="error",但它只在第二次验证时显示错误 运行.

提前致谢。

编辑 1:

 window.Parsley.addValidator('age', {
            validate: function(value, id){
                $('.birthdate_container').find('ul').remove();
                switch(id){
                    case 'main':
                        var day = $('#birthdate_day').val();
                        var month = $('#birthdate_month').val();
                        var year = $('#birthdate_year').val();
                        if(!day || !month || !year){
                            return $.Deferred().reject("One of them is blank");
                        } else if(day > 2 || month > 2 || year < 2016){
                            return $.Deferred().reject("Else test of another message");
                        } else {
                            return true;
                        }
                    break;
                }
                return true;
            },
        });

一个更简洁的解决方案(不要介意其他,它只是用于测试)但仍然无法使其工作,因为我不知道如何更新 3 的 类返回 true 的元素。

编辑 2:

只是使用 jQuery 来处理 类 工作,但是,因为我需要删除 ul(否则消息会堆叠,我不希望这样),只要出现错误在出现另一个错误后触发,它只是将其删除。

window.Parsley.addValidator('age', {
            validate: function(value, id){
                $('.birthdate_container').find('ul').remove();
                switch(id){
                    case 'main':
                        var day = $('#birthdate_day').val();
                        var month = $('#birthdate_month').val();
                        var year = $('#birthdate_year').val();
                        if(!day || !month || !year){
                            $('.birthdate_container').find('.parsley-success').removeClass('parsley-success').addClass('parsley-error');
                            return $.Deferred().reject("Un campo es blanco");
                        } else if(day > 2 || month > 2 || year < 2016){
                            $('.birthdate_container').find('.parsley-success').removeClass('parsley-success').addClass('parsley-error');
                            return $.Deferred().reject("dia > 2 o mes > 2 o años < 2016");
                        } else {
                            $('.birthdate_container').find('.parsley-error').removeClass('parsley-error').addClass('parsley-success');
                            return true;
                        }
                    break;
                }
                return true;
            },
        });

它没有很好的记录,但您可以通过 return 拒绝承诺来 return 来自验证器的错误消息。检查 this example.

经过多次修改,我想我明白了,我必须重置所有以前的欧芹,以便它可以在需要时重写消息,即使是同一个消息

window.Parsley.addValidator('age', {
            validate: function(value, id){
                switch(id){
                    case 'main':
                        var container = $('.birthdate_container');
                        container.find('ul').remove();
                        var day = $('#birthdate_day');
                        day.parsley().reset();
                        var month = $('#birthdate_month');
                        month.parsley().reset();
                        var year = $('#birthdate_year');
                        year.parsley().reset();

                        if(day.val() === '' || month.val() === '' || year.val() === ''){
                            container.find('.dropdown').removeClass('parsley-success').addClass('parsley-error');
                            return $.Deferred().reject("Un campo es blanco");
                        } else if(day.val() > 2 || month.val() > 2 || year.val() < 2016){
                            container.find('.dropdown').removeClass('parsley-success').addClass('parsley-error');
                            return $.Deferred().reject("dia > 2 o mes > 2 o años < 2016");
                        } else {
                            container.find('.dropdown').removeClass('parsley-error').addClass('parsley-success');
                            return true;
                        }
                    break;
                }
                return true;
            }
        });

PD:同样,第二个 else 只是为了测试您是否可以抛出不同的消息;验证本身无关紧要。

我的最终作品:

window.Parsley.addValidator('age', {
            validate: function(value, id, instance){
                var container = instance.$element.closest('.form-item');
                container.find('ul').remove();
                var msg = '';
                var day = container.find('select').filter(function() {return this.id.match(/\w*birthdate_day/);});
                var month = container.find('select').filter(function() {return this.id.match(/\w*birthdate_month/);});
                var year = container.find('select').filter(function() {return this.id.match(/\w*birthdate_year/);});
                day.parsley().reset();
                month.parsley().reset();
                year.parsley().reset();
                var helpContainer = '<ul class="parsley-errors-list filled"><li class="parsley-age"></li></ul>';

                if(value === ''){
                    container.find('select').parent().addClass('parsley-error');
                    msg = "This field is required";

                }
                /* Take several notes here
                1) I wrap my select in a div, for stylying purposes, so I check the default placeholder, when something is selected
                    this placeholder is changed with the value of the select (this is not shown here, it's done elsewhere)
                2) I use DD - MM - YYYY as placeholders, if any of these place holders are already showing in the div,
                    then I don't validate them because they are still 'clean'
                3) If the user clicks the submit button though, I set a js variable with this action and then validate the value anyways
                    because I don't allow blank dates, however, I can't use the parsley-required feature as it messes up my validation
                */
                else if(obj.action !== 'submit' && (day.parent().attr('data-placeholder') === 'DD' ||
                    month.parent().attr('data-placeholder') === 'MM' ||
                    year.parent().attr('data-placeholder') === 'YYYY'))
                {
                    container.find('select').parent().removeClass('parsley-error')
                    container.find('select').filter(function(){ return this.value}).parent().addClass('parsley-success');
                    return true;
                }
                else if(day.val() === '' || month.val() === '' || year.val() === '') {
                    container.find('select').parent().addClass('parsley-error');
                    msg = "This field is required";
                }
                /*
                I have another validation process past this point that uses a different error, but I'll point out the very basic
                which is just make some other validation and fill the message you want to display.

                Let's assume you want the person not to be underage and you control that in your form somehow
                */
                else if (!underageAllowed){
                    var bdate =  String("00" + day.val()).slice(-2) + "/" + String("00" + month.val()).slice(-2) + "/" + year.val();
                    var tdate = moment(); // Today
                    bdate = moment(bdate,'DD/MM/YYYY');
                    var age = tdate.diff(bdate, 'years');
                    if(age < 18){
                        container.find('select').parent().addClass('parsley-error');
                        msg = "Only people with over 18 years old are allower";
                    }
                }                   

                if(msg !== ''){
                    if(obj.action === 'submit'){
                        container.append(helpContainer);
                        container.find('.parsley-age').html(msg)
                    }
                    return $.Deferred().reject(msg);
                } else {
                    container.find('select').filter(function(){ return this.value}).parent().addClass('parsley-success');
                    return true;
                }
            },
        });

然后我将验证器分配给每个以 "birthdate_" 作为 id 的字段(birthdate_day、birthdate_month 和 birthdate_year)

    $("[id^='birthdate_']").attr('data-parsley-age','true')
            .attr('data-parsley-trigger', "change")
            .attr('data-parsley-validate-if-empty', "true");

每个字段的正确 errorContainer

$('#main_form').parsley({
            errorsContainer: function(el){
                if(el.$element.is('[data-parsley-age]'))
                    return el.$element.closest('.form-item');
            },

最后是我的 html 布局

<div class="form-item">
<label>Date of birth</label>
<div class="dropdown" data-placeholder="DD">
    <select id="birthdate_day" name="birthdate_day">
        <option value="">-</option> //If user selects this, the validation throws error for all the fields
        //Options 1 through 31
    </select>
</div>
<div class="dropdown" data-placeholder="MM">
    <select id="birthdate_month" name="birthdate_month">
        <option value="">-</option>  //If user selects this, the validation throws error for all the fields
        //Options 1 through 12
    </select>
</div>
<div class="dropdown" data-placeholder="YYY">
    <select id="birthdate_year" name="birthdate_year">
        <option value="">-</option> //If user selects this, the validation throws error for all the fields
        //Options 1 through 12
    </select>
</div>

希望这对任何人都有帮助,我花了一些时间才想出这一切。

如果您只想处理动态消息,请不要在您的消息对象中包含消息文本,然后在您的验证方法中:

instance.addError('en', {message: 'Hello World'});

就这么简单。只需阅读带注释的源代码,它将揭示一整套简单的功能。

编辑:实际上我只是注意到你确实需要一些东西或者它会抛出它自己的错误消息,所以你可以用类似的东西来修复它:

messages: {
    en: '...'
}

我刚测试过,效果很好