Yii2:Bootstrap 模态形式验证 (Ajax) - 对奇怪行为有任何见解吗?

Yii2: Bootstrap Modal Form Validation (Ajax) - any insight on strange behavior?

我一直致力于在 Yii2 中使用模态 windows 形式的表单,但我遇到了一个问题,即当表单位于内部时,标准 Yii 表单 ajax 验证不起作用一个 bootstrap 模态 window。

需要说明的是,当字段失去焦点时,会为每个字段触发 ajax 表单验证。这是标准的 Yii 表单验证,所以我通过单击进入必填字段然后单击字段外来测试模式中的表单。这会触发 Yii ajax 验证,并应在“'field' 不能为空”字段下显示红色错误消息。

同样,我的问题是 ajax 验证有时有效,有时无效。

我设法将问题与模态代码在页面上的放置位置相关联,但对我来说以下内容如何影响 ajax 中表单的验证行为毫无意义模态。

首先,我将向您展示可以正常工作的代码。 Yii 表单验证在模态 window.

中的表单上按预期工作
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use yii\grid\GridView;
use yii\bootstrap\Modal;    
?>
<div class="category-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= Html::button('Create Category', [
        'class' => 'btn btn-success btn-ajax-modal',
        'value' => Url::to('/category/create'),
        'data-target' => '#modal_category',
    ]); ?>

    <?php
    Modal::begin([
        'id' => 'modal_category',
        'header' => '<h4>Category</h4>',
    ]);
    echo '<div class="modal-content"></div>';
    Modal::end();
    ?>

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'title',
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
</div>

上面代码需要注意的地方:

1) 这是我的 category/index 视图,所以它有一个创建按钮,bootstrap 模态代码,然后是类别的 Yii gridview。

2) 创建按钮有btn-ajax-modal class。此 class 由一个 JS 函数标识,该函数使用其他按钮属性显示模态窗口并在模态中加载表单内容。按钮值属性标识应加载的模型和表单。

这是处理显示模态和加载表单的 JS 函数:

$('.btn-ajax-modal').click(function (){
    var elm = $(this),
        target = elm.attr('data-target'),
        ajax_body = elm.attr('value');

    $(target).modal('show')
        .find('.modal-content')
        .load(ajax_body);
});

所以,以上所有代码都可以完美运行,我希望这对其他人有所帮助!

但是...如果我对上面的代码进行一些非常简单的更改,ajax 表单验证将不再有效,我不知道为什么。

第一个变化:

1) 将bootstrap模态代码移至gridview代码下方,ajax验证不再起作用

<div class="category-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= Html::button('Create Category', [
        'class' => 'btn btn-success btn-ajax-modal',
        'value' => Url::to('/category/create'),
        'data-target' => '#modal_category',
    ]); ?>

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'title',    
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

    <?php //*** SEE MODAL CODE IS NOW BELOW GRIDVIEW CODE
    Modal::begin([
        'id' => 'modal_category',
        'header' => '<h4>Category</h4>',
    ]);
    echo '<div id="modalContent"></div>';
    Modal::end();
    ?>

</div>

我不明白为什么将模态代码移动到 gridview 代码下方会破坏 ajax 表单验证。模式仍会显示并加载正确的表单,但是当我将焦点移至必填字段或将焦点移开时,ajax 表单验证不会触发。

而且它变得更加奇怪......

第二次变化:

2) 不要将模态代码移动到 gridview 代码下方,只需完全删除 gridview,包括 use yii\grid\GridView;.

<?php
use yii\helpers\Html;
use yii\helpers\Url;
use yii\bootstrap\Modal;    
?>
<div class="category-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= Html::button('Create Category', [
        'class' => 'btn btn-success btn-ajax-modal',
        'value' => Url::to('/category/create'),
        'data-target' => '#modal_category',
    ]); ?>

    <?php
    Modal::begin([
        'id' => 'modal_category',
        'header' => '<h4>Category</h4>',
    ]);
    echo '<div class="modal-content"></div>';
    Modal::end();
    ?>

</div>

此更改还会导致模式中表单的 ajax 表单验证停止工作。

到底是什么?删除与 modal/form 设置完全无关的 gridview 如何导致 ajax 表单验证停止工作?

我在浏览器控制台中没有看到错误,在 Yii 调试模块中也没有错误。但由于某种原因,ajax 字段验证未显示。

抱歉拖了这么久post,但我想尽可能清楚和具体。我不确定这是否是一些奇怪的 Yii2 错误,如果我失去理智,或者对此是否有合乎逻辑的解释。

如果有任何想法、答案或建议,请分享!感谢您与我一起集思广益!

这一挑战的解决方案是确保模态 window 中的表单具有 id 属性。表单 ID 对于 Yii2 ajax 验证正常运行很重要。

Ajax 如果没有 id 属性,验证将无法进行。打开 category/_form.php 并为 ActiveForm 设置一个 id,如下所示:

<div class="category-form">
    <?php $form = ActiveForm::begin(['id' => 'create-update-category-form']); ?