简体   繁体   English

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

[英]Parsley.js Dynamic messages in custom validator

I'm using a custom validator to check for date of birth, so far it has almost nothing, but I'm trying to add a dynamic message depending on the error and it's not working for me it displays the container with a blank message, any ideas? 我正在使用自定义验证程序来检查出生日期,到目前为止,它几乎没有任何内容,但是我尝试根据错误添加动态消息,并且对我不起作用,它会显示带有空白消息的容器,有任何想法吗?

Here's the piece of code the 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',
            }
        });

Another thing I've tried is setting the data-parsley-age-message="error" during the execution of the validation, but it only shows the error the second time the validation is ran. 我尝试过的另一件事是在验证执行期间设置data-parsley-age-message =“ error”,但是它仅在第二次运行验证时显示错误。

Thanks in advance. 提前致谢。

EDIT1: 编辑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;
            },
        });

A little cleaner solution (don't mind the else, it's there just for testing) but can't still make it work becasue I don't know how I can update the classes of the 3 elements on returning true. 一个更简洁的解决方案(别介意,它只是用于测试),但是由于我不知道如何在返回true时更新3个元素的类,因此仍然无法使它起作用。

EDIT 2: 编辑2:

Just using jQuery to handle the classes work, however, since I need to remove the ul (otherwise the messages will stack and I don't want that), whenever there's an error triggered AFTER another error is in there, it simply erases it. 但是,仅使用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;
            },
        });

It's not well documented, but you can return an error message from your validator by returning a rejected promise. 它的文档记录不充分,但是您可以通过返回被拒绝的承诺从验证器返回错误消息。 Check this example . 检查此示例

After too much tinkering with it, I think I got it, I have to reset all the previous parsley so it could rewrite the message if needed, even if it's the same one 经过大量修改后,我想我明白了,我必须重置所有以前的欧芹,以便即使需要时也可以重写该消息(即使是相同的消息)

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: Again, the second else is just there to test that you can throw a different message; PD:同样,第二个就是测试您是否可以抛出不同的消息。 the validation itself is irrelevant. 验证本身是不相关的。

My final work: 我的最终作品:

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;
                }
            },
        });

I then assign the validator to every field that has "birthdate_" as an id (birthdate_day, birthdate_month and birthdate_year) 然后,我将验证器分配给每个具有“ birthdate_”作为ID的字段(birthdate_day,birthatedate_month和birthdate_year)

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

Proper errorContainer for each of the fields 每个字段正确的errorContainer

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

And finally how I have my html layout 最后是我的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>

Hope this helps out anyone, it took me some time to come up with all this. 希望这对任何人有帮助,我花了一些时间来解决所有这些问题。

If you ONLY want to deal with dynamic messages, do not include a message text in your messages object, then in your validation method: 如果只想处理动态消息,则不要在message对象中,而在验证方法中包括消息文本:

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

It's as simple as that. 就这么简单。 Just read the annotated source code and it will unveil a whole host of simple features. 只需阅读带注释的源代码,它将揭示许多简单功能。

EDIT: actually I just noticed you do need something or it throws it's own error message, so you can fix that with something like: 编辑:实际上,我只是注意到您确实需要某些东西,否则它会抛出自己的错误消息,因此您可以使用以下方法解决此问题:

messages: {
    en: '...'
}

I just tested and that works fine 我刚刚测试过,效果很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM