5

I am using ActiveForm with the afterValidate() event, however currently the afterValidate() gets triggered on any validation event. How can I differentiate between the events validateOnSubmit, validateOnBlur and validateOnChange?

Basically, I only want my afterValidate() function to get triggered on submit. Here is my code:

PHP:

<?php $form = ActiveForm::begin([
    'id' => 'register-form',
    'options' => [
        'class' => 'validate-form',
    ],
    'enableClientValidation' => true,
    'enableAjaxValidation' => false,
    'validateOnSubmit' => true,
    'validateOnBlur' => true,
    'validateOnChange' => true,
]); ?>

JS:

// JS afterValidate function
$('.validate-form').on('afterValidate', function (event, messages, errorAttributes) {
    $('.error-popup').show();

    return false;
});

HTML:

<div class="error-popup">Please review the errors in the form below.</div>

As you can see in my afterValidate() function above, an error popup is shown if there are validation errors. However I only want this to error popup to appear if there are any validation errors when the user submits the form.

If there is a validation error on blur/change then the normal inline validation should occur without any error popup.

From my understanding, beforeSubmit event is only triggered when validation has passed.

MAX POWER
  • 5,213
  • 15
  • 89
  • 141

3 Answers3

9

Yii's active form JS save some info into yiiActiveForm data property. There is submitting property that you can use to determine if the form is in validation before form submission.

$('.validate-form').on('afterValidate', function (event, messages, errorAttributes) {
    let data = $('.validate-form').data('yiiActiveForm');
    //check if we are in submission process and if there are any errors
    if (data.submitting && errorAttributes.length > 0) {
        $('.error-popup').show();
    }
});
Michal Hynčica
  • 5,038
  • 1
  • 12
  • 24
0

You can approach this the following way:

$("#register-form").on("beforeSubmit", function(event){
    $(this).yiiActiveForm('validateAttribute', 'contactform-phone');
    $(this).yiiActiveForm('validateAttribute', 'contactform-email');
    if ($(this).find('.has-error').length) {
        ...
    }
    ...
    return false;
});

The submit button triggers beforeSubmit event which in turn triggers validation of whichever fields you need. If validation results in error, you can do your JS logic associated with displaying error messages.

bds
  • 266
  • 2
  • 6
  • That's not going to work. The yii's `beforeSubmit` is only triggered when the form passes validation and it's going to be submitted. But OP needs to run his code when there are validation errors. – Michal Hynčica Jul 09 '20 at 10:26
  • As the form is filled, it is validated when the input field loses focus, so by the time the user gets to the Submit button, the validation results are already in. Unless, I guess, the user simply submits an empty form... This does work in a use-case for roughly the same scenario as described by the OP. – bds Jul 09 '20 at 11:04
  • You are right that the validation results are already in but the problem is that when there are some validation errors the `beforeSubmit` event is not triggered. So your code will only be executed when there is no validation error. – Michal Hynčica Jul 09 '20 at 11:10
0

You should find has-error class after afterValidate and show popup try the following code

$('.validate-form').on('afterValidate', function (event, messages, errorAttributes) {
        if ($('.validate-form').find('.has-error').length) {
            $('.error-popup').show();
        }
  });