在前一篇文章中,我們介紹了 Yii2 中 Modal 彈窗的基本用法(以建立功能為例)。實際開發中,列表頁的資料修改往往也需要使用 Modal。若是一般迴圈顯示,大多數開發者看完基本用法都能上手,但結合 GridView 時,不少人就開始感到棘手。本文將詳細說明如何解決這個問題,並針對實務中常見的三大難題提供解決方案。
首先在 GridView 的 ActionColumn 中加入更新按鈕,並指定必要的 data 屬性:
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update}',
'buttons' => [
'update' => function ($url, $model, $key) {
return Html::a('更新', '#', [
'data-toggle' => 'modal',
'data-target' => '#update-modal',
'class' => 'data-update',
'data-id' => $key,
]);
},
],
],
使用 Yii2 Bootstrap Modal 元件建立彈窗,並註冊 JavaScript 處理點擊事件:
<?php
use yii\bootstrap\Modal;
// 更新操作 Modal
Modal::begin([
'id' => 'update-modal',
'header' => '<h4 class="modal-title">更新</h4>',
'footer' => '<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>',
]);
$requestUpdateUrl = Url::toRoute('update');
$updateJs = <<<JS
$('.data-update').on('click', function () {
$.get('{$requestUpdateUrl}', { id: $(this).closest('tr').data('key') }, function (data) {
$('.modal-body').html(data);
});
});
JS;
$this->registerJs($updateJs);
Modal::end();
?>
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->renderAjax('update', [
'model' => $model,
]);
}
}
到這裡流程看似結束,但實務上常遇到三個棘手問題:
解決方法:在 Modal::begin() 時指定 options 選項的 tabindex 為 false。
Modal::begin([
// ...
'options' => [
'tabindex' => false,
],
]);
這兩個問題根源相同:$('.modal-body').html(data) 會將資料寫入所有 Modal 的 body,導致後開啟的 Modal 在資料載入前顯示舊內容;且同一頁面相同表單 ID 會導致 Select2 衝突。
// 建立按鈕
$('#create').on('click', function () {
// 避免多 Modal Select2 問題:移除異步載入的表單
$('.document-nav-form').remove();
$.get('{$requestUrl}', {}, function (data) {
$('#create-modal').find('.modal-body').html(data);
});
});
// 更新按鈕
$('.data-update').on('click', function () {
$('.document-nav-form').remove();
$.get('{$requestUpdateUrl}', { id: $(this).closest('tr').data('key') }, function (data) {
$('#update-modal').find('.modal-body').html(data);
});
});
透過 $('#create-modal').find('.modal-body') 精準定位目標 Modal,並在每次請求前 remove() 舊表單,即可徹底解決上述三大問題。
以上完整說明了 Yii2 結合 GridView 使用 Modal 彈窗的實作細節與常見坑點解法,希望能幫助大家在專案中順利應用。若有疑問歡迎留言討論。