You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2中点击按钮弹出的模态框闪显后消失,无法正常显示

模态框点击后短暂显示即消失的问题解决

问题描述

点击GridView中的删除按钮时,删除确认模态框仅短暂显示就立即消失,仅留下黑色背景遮罩。

实现代码

<?PHP

use kartik\select2\Select2;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\Pjax;
use kartik\export\ExportMenu;
use kartik\grid\GridView;
/* @var $this yii\web\View */
/* @var $searchModel app\models\InstallationsSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Installations';
$this->params['breadcrumbs'][] = $this->title;
?>
<section class="content-header">
<h1><?= Html::encode($this->title) ?></h1>
 </section>
 <section class="content">
  <div class="box">
    <div class="box-body">
         <div id="statusMsg" >
            <?= Yii::$app->session->getFlash('no');?>
            <?= Yii::$app->session->getFlash('error');?>
            <?= Yii::$app->session->getFlash('success');?>
            <?= Yii::$app->session->getFlash('errors');?>
         </div>

        <div class="built" style="overflow: hidden; overflow-y: hidden; height: ?">

            <?php
            $gridColumns =[
                [
                    'class'=>'kartik\grid\SerialColumn',
                ],
                [
                    'class' => 'kartik\grid\ActionColumn',
                    'template' => '{view} {update} {delete}',
                    'buttons' => [
                        'delete' => function ($url, $model) {
                            return Html::a('<span class="glyphicon glyphicon-trash"></span>', '#', [
                                'class' => 'kv-row-select',
                                'data-id' => $model->id,
                                'data-toggle' => 'modal',
                                'data-target' => '#deleteModal',
                                'data-confirm' => false, // Disable built-in confirmation
                                'data-method' => false, // Disable data-method attribute to avoid default delete behavior
                            ]);
                        },
                    ],
                ],
                'meter_msn',
                'old_ref_no',
                [
                    'attribute' => 'm_sub_div',
                    'value' => function ($d) {
                        if(is_object($d->subdiv))
                            return $d->subdiv->name;
                        return ' - ';
                    },
                    'filter' => Select2::widget([
                        'model' => $searchModel,
                        'attribute' => 'm_sub_div',
                        'data' => \common\models\SurveyHescoSubdivision::toArrayList(),
                        'options' => ['placeholder' => 'Sub-Div'],
                        'pluginOptions' => [
                            'allowClear' => true,
                        ],
                    ]),
                ],
                'consumer_name',
                'consumer_address',
                [
                    'label' => 'Meter Installation Location',
                    'value' => function($model){
                        return $model['latitude'] . ' , ' . $model['longitude'];
                    }
                ],
                'mount_material',
                [
                    'label' => 'AMR Inst. Date',
                    'value' => function ($model) {
                        return date("d-m-Y", strtotime($model->sync_date));
                    },
                ],
                [
                    'label' => 'Install Status',
                    'value' => function ($d) {
                        return $d->istallation_status;
                    },
                    'filter' => Html::activeDropDownList($searchModel, 'istallation_status', \app\models\Installations::getInstallStatus(), ['prompt' => "Install Status", 'class' => 'form-control']),
                ],
                [
                    'label' => 'Meter Type',
                    'value' => function ($d) {
                        if(is_object($d))
                            return $d->meter_type;
                        return ' - ';
                    },
                    'filter' => Html::activeDropDownList($searchModel, 'meter_type', \app\models\Meters::getMeterTypeValues(), ['prompt' => "Meter Type", 'class' => 'form-control']),
                ],
                'electrician_name',
                [
                    'attribute' => 'created_by',
                    'value' => function ($model) {
                        if(is_object($model->user)){
                            return $model->user->username;
                        }
                        return '';
                    },
                    'filter' => Select2::widget([
                        'model' => $searchModel,
                        'attribute' => 'created_by',
                        'data' => \app\models\User::toArrayList(),
                        'options' => ['placeholder' => 'Select a User'],
                        'pluginOptions' => [
                            'allowClear' => true,
                        ],
                    ]),
                ],
            ];

            echo ExportMenu::widget([
                'dataProvider' => $dataProvider,
                'columns' => $gridColumns,
                'dropdownOptions' => [
                    'label' => 'Export All',
                    'class' => 'btn btn-info',
                ],
                'exportConfig' => [
                    ExportMenu::FORMAT_PDF => false,
                    ExportMenu::FORMAT_TEXT => false,
                    ExportMenu::FORMAT_HTML => false,
                    ExportMenu::FORMAT_CSV => false,
                ],
                'filename' => 'LESCO_Installation_Data_' . date('d-M-yy')
            ]);

            echo GridView::widget([
                'dataProvider' => $dataProvider,
                'filterModel' => $searchModel,
                'columns' => $gridColumns,
            ]);
            ?>

        </div>
    </div>
</div>
</section>

<!-- Delete Confirmation Modal -->
<div id="deleteModal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog" role="document">
    <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title">Delete Confirmation</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
            <p>Are you sure you want to delete this item?</p>
            <form id="deleteForm" method="post" action="<?= Url::to(['installations/delete']) ?>">
                <input type="hidden" name="_csrf" value="<?= Yii::$app->request->csrfToken ?>">
                <input type="hidden" id="delete-id" name="id">
                <div class="form-group">
                    <label for="delete-reason">Reason for deletion:</label>
                    <textarea class="form-control" id="delete-reason" name="delete_reason" required></textarea>
                </div>
                <input type="hidden" name="deleted_by" value="<?= Yii::$app->user->identity->id ?>">
            </form>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
            <button type="button" id="submitDelete" class="btn btn-danger">Delete</button>
        </div>
    </div>
</div>
</div>

<?PHP
$script = <<< JS
function initializeModalEvents() {
$('.kv-row-select').off('click').on('click', function() {
    console.log('Delete button clicked');
    var id = $(this).data('id');
    $('#delete-id').val(id);
    $('#deleteModal').modal('show');
    console.log('Modal shown with ID: ' + id);
});

$('#submitDelete').off('click').on('click', function(event) {
    event.preventDefault();
    var form = $('#deleteForm');
    var reason = $('#delete-reason').val().trim();

    if (reason === '') {
        alert('Reason for deletion is mandatory.');
        return false;
    }

    console.log('Submitting form');
    $.ajax({
        url: form.attr('action'),
        type: 'post',
        data: form.serialize(),
        success: function(response) {
            console.log('Form submitted successfully');
            if (response.success) {
                $('#deleteModal').modal('hide');
                $.pjax.reload({container:'#w0-pjax'});
            } else {
                alert('An error occurred while deleting the item.');
            }
        },
        error: function() {
            console.log('Form submission error');
            alert('An error occurred while deleting the item.');
        }
    });
});
}

$(document).ready(function() {
setTimeout(function() {
    $('#statusMsg').fadeOut('fast');
}, 5000); // <-- time in milliseconds

initializeModalEvents();

$(document).on('pjax:success', function() {
    initializeModalEvents();
});
});
JS;
$this->registerJs($script);
?>

问题演示

模态框闪显消失演示

解决方案

1. 阻止删除按钮的默认跳转行为

问题根源在于<a>标签的默认跳转行为(即使href="#")会触发页面hash变化,导致Bootstrap模态框自动关闭。需要在点击事件中添加event.preventDefault()阻止默认行为:

修改JavaScript中的删除按钮点击事件:

$('.kv-row-select').off('click').on('click', function(event) {
    event.preventDefault(); // 阻止a标签的默认跳转行为
    console.log('Delete button clicked');
    var id = $(this).data('id');
    $('#delete-id').val(id);
    $('#deleteModal').modal('show');
    console.log('Modal shown with ID: ' + id);
});

2. 彻底禁用ActionColumn的默认删除行为

虽然代码中设置了data-confirm=false和data-method=false,但Yii的ActionColumn可能仍会绑定默认的删除事件,可以直接在按钮生成时添加onclick="event.preventDefault();"强化阻止:

修改ActionColumn的delete按钮代码:

'delete' => function ($url, $model) {
    return Html::a('<span class="glyphicon glyphicon-trash"></span>', '#', [
        'class' => 'kv-row-select',
        'data-id' => $model->id,
        'data-toggle' => 'modal',
        'data-target' => '#deleteModal',
        'data-confirm' => false,
        'data-method' => false,
        'onclick' => 'event.preventDefault();' // 直接在标签上阻止默认行为
    ]);
},

3. 检查Pjax事件冲突

确保pjax:success事件重新绑定事件时,不会重复绑定导致冲突,当前代码中的off('click')已经处理了重复绑定问题,这部分可以保留。

完成以上修改后,点击删除按钮时,模态框会正常显示,不会再自动消失。

内容的提问来源于stack exchange,提问作者Moeez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:20:54