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">×</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
相关产品推荐
相关产品推荐

