yiisoft / yii2-bootstrap4

Yii 2 Bootstrap 4 Extension
https://www.yiiframework.com/
BSD 3-Clause "New" or "Revised" License
216 stars 106 forks source link

ActiveForm horizontal doesn't show validation error messages #122

Closed ricpelo closed 5 years ago

ricpelo commented 5 years ago

What steps will reproduce the problem?

<?php $form = ActiveForm::begin([
    'id' => 'login-form',
    'layout' => 'horizontal',
]); ?>

    <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <?= $form->field($model, 'rememberMe')->checkbox() ?>

    <div class="form-group">
        <div class="col-sm-offset-1 col-sm-11">
            <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
        </div>
    </div>

<?php ActiveForm::end(); ?>

What's expected?

Form validation shows error messages in red color when empty fields ('Username can't be blank' and so on).

What do you get instead?

No error messages are shown.

Additional info

Q A
Yii vesion 2.0.17
PHP version 7.1.27
Operating system Ubuntu 18.04.2 LTS
ricpelo commented 5 years ago

With the following code I'm able to workaround the issue and show the error message next to the form field:

<?php $form = ActiveForm::begin([
    'id' => 'login-form',
    'layout' => 'horizontal',
    'fieldConfig' => [
        'inputOptions' => ['class' => 'col-sm-4 form-control'],
        'horizontalCssClasses' => ['error' => 'col-sm-6 col-form-label'],
        'template' => "{label}\n{input}\n{error}\n{hint}",
    ],
]); ?>

    <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <?= $form->field($model, 'rememberMe', [
        'labelOptions' => ['class' => 'col-sm-12'],
    ])->checkbox() ?>

    <div class="form-group">
        <div class="col-sm-offset-1 col-sm-11">
            <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
        </div>
    </div>

<?php ActiveForm::end(); ?>

The problem is in the default template for ActiveFields when the form is horizontal:

https://github.com/yiisoft/yii2-bootstrap4/blob/bb007ceb0890e692efb0b1ee23ce6b476318631e/src/ActiveField.php#L424

We need to remove {beginWrapper} and {endWrapper} from the template, as I do in the above code.

machour commented 5 years ago

@ricpelo could you open a PR for this as well? It would be of great help.

simialbi commented 5 years ago

I can't reproduce that: http://demo.karlen.li/web/site/contact With the following setup:

Q A
Yii vesion 2.0.17
Yii bootstrap 4 version 2.0.1
PHP version 5.6.33
Operating system Linux/SuSE

Code:

<?php $form = ActiveForm::begin([
    'id'     => 'contact-form',
    'layout' => ActiveForm::LAYOUT_HORIZONTAL
]); ?>
    <?=$form->field($model, 'name')->textInput(['autofocus' => true])?>
    <?=$form->field($model, 'email')?>
    <?=$form->field($model, 'subject')?>
    <?=$form->field($model, 'body')->textarea(['rows' => 6])?>
    <?=$form->field($model, 'verifyCode')->widget(Captcha::className(), [
        'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
    ])?>
    <div class="form-group">
        <?=Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button'])?>
    </div>
<?php ActiveForm::end(); ?>
ricpelo commented 5 years ago

@simialbi Yes, you're right. However, in your live demo the error message for the verification code (captcha) doesn't show. This is because <div class="invalid_feedback">... is not a sibling of <input> due to the template value. See the CSS:

.was-validated .form-control:invalid ~ .invalid-feedback,
.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,
.form-control.is-invalid ~ .invalid-tooltip {
  display: block;
}
simialbi commented 5 years ago

@ricpelo Yes you are right. That's because of the template override. This form of my live demo is a copy from the bs3 optimized template. I removed the old bs3 template from params and then it (does not look nice but) works as well:

<?=$form->field($model, 'verifyCode')->widget(Captcha::className(), [
//   'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
])?>
ricpelo commented 5 years ago

@simialbi Great! This is my current solution that IMO it's nicer and closer to the BS3 look & feel:

<?= $form->field($model, 'verifyCode', [
    'labelOptions' => ['style' => 'display: block']
])->widget(Captcha::className(), [ 
    'imageOptions' => ['class' => 'col-xl-4', 'style' => 'padding: 0'],
    'options' => ['class' => 'form-control col-xl-7', 'style' => 'display: inline'],          
]) ?>
ricpelo commented 5 years ago

The above solution is for a non-horizontal layout. With an horizontal layout, I can have the following solution:

<div class="row">
    <div class="col-xl-8">
        <?php $form = ActiveForm::begin([                                                                 
            'id' => 'contact-form',
            'layout' => 'horizontal',
            'fieldConfig' => [
                'horizontalCssClasses' => ['label' => 'col-sm-2'],
            ],
        ]); ?>

            <?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?>
            <?= $form->field($model, 'email') ?>
            <?= $form->field($model, 'subject') ?>
            <?= $form->field($model, 'body')->textarea(['rows' => 6]) ?>
            <?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
                'imageOptions' => ['class' => 'col-sm-3', 'style' => 'padding: 0'],
                'options' => ['class' => 'form-control col-sm-7', 'style' => 'display: inline'],
            ]) ?>

            <div class="form-group">
                <?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
            </div>

        <?php ActiveForm::end(); ?>
    </div>
</div>

2019-03-27-125441_1280x987_scrot

ricpelo commented 5 years ago

According to this, I'm going to close this issue because it doesn't seem to be a bug, but my fault. Thanks to everybody!