首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii2 實戰筆記(六):美化 Alert/Confirm、非同步 Confirm、Session Flash 彈窗元件封裝

     編輯:PHP 相關知識

痛點:原生 Alert/Confirm 難看且同步阻塞

Yii2 GridView 刪除按鈕預設使用瀏覽器原生 confirm(),樣式無法自訂,且為同步阻塞。引入 kartik-v/yii2-dialog(基於 Bootstrap3 Dialog)可快速獲得美觀、非同步的對話框。

一、安裝與基本使用

composer require kartik-v/yii2-dialog @dev

基本用法:

use kartik\dialog\Dialog;
// Alert
Dialog::alert('訊息內容');
// Confirm(非同步,需回調)
Dialog::confirm('確定刪除?', function($result) {
    if ($result) { /* 確定邏輯 */ }
});
// Dialog
Dialog::widget(['title' => '標題', 'content' => '內容'])

二、覆寫 Yii 全域 confirm(讓 GridView 刪除也用美觀對話框)

1. 查看原始碼

vendor/yiisoft/yii2/assets/yii.js 中的 yii.confirm 可被覆寫。

2. 建立 backend/web/js/confirm.js

yii.confirm = function (message, ok, cancel) {
    krajeeDialog.confirm(message, function (data) {
        if (data) { !ok || ok(); }
        else { !cancel || cancel(); }
    });
    return false; // 取消預設點擊行為,交由回調處理
};

3. 於 AssetBundle 註冊

class AppAsset extends AssetBundle {
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = ['css/site.css'];
    public $js = ['js/confirm.js']; // 關鍵
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}

三、非同步 Confirm 的程式設計陷阱

原生 confirm() 同步回傳 true/false,程式碼可寫成:

if (confirm('刪除?')) { doDelete(); }

但 krajeeDialog.confirm 為**非同步回調**,不能這樣寫:

// 錯誤寫法:永遠不會進入 if
if (krajeeDialog.confirm('刪除?', function(r){ return r; })) { doDelete(); }

正確寫法:將後續邏輯放入回調

krajeeDialog.confirm('刪除?', function (result) {
    if (result) { doDelete(); }
});

四、Kartik GridView 內建功能(顯示全部/匯出 CSV)的 Confirm 覆寫

1. 顯示全部記錄(toggleData)

修改 vendor/kartik-v/yii2-grid/GridView.php 中 getToggleDataScript() 回傳的 JS:

$url = Url::current([$this->_toggleDataKey => $tag]);
return "$('#{$this->_toggleButtonId}').on('{$event}',function(e){
    e.preventDefault();
    krajeeDialog.confirm('{$msg}',function(data){
        if (data) { window.location.href='{$url}'; }
    });
});";

2. 匯出 CSV 提示(較複雜)

涉及 kv-grid-export.js 的 kvConfirm、notify、listenClick,建議重寫整個 JS 模組或改用自訂按鈕。

五、Session Flash 訊息:從內聯 Alert 升級為彈窗

1. Controller 設定 Flash

public function actionCreate() {
    $model = new User();
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        Yii::$app->session->setFlash('success', '建立成功');
        return $this->redirect(['index']);
    }
    return $this->render('create', ['model' => $model]);
}

2. Layout 內聯 Alert(AdminLTE 自帶)

<?= \kartik\alert\Alert::widget() ?>
// 或加入自動淡出 JS
$this->registerJs("$('.alert-success').animate({opacity:1},5000).fadeOut('slow');");

3. 封裝彈窗元件(common/widgets/Popup.php)

<?php
namespace common\widgets;

class Popup extends \yii\bootstrap\Widget {
    public $popupTypes = [
        'default' => 'BootstrapDialog.TYPE_DEFAULT',
        'info'    => 'BootstrapDialog.TYPE_INFO',
        'primary' => 'BootstrapDialog.TYPE_PRIMARY',
        'success' => 'BootstrapDialog.TYPE_SUCCESS',
        'warning' => 'BootstrapDialog.TYPE_WARNING',
        'danger'  => 'BootstrapDialog.TYPE_DANGER',
    ];
    public $sizeTypes = [
        'normal' => 'BootstrapDialog.SIZE_NORMAL',
        'small'  => 'BootstrapDialog.SIZE_SMALL',
        'wide'   => 'BootstrapDialog.SIZE_WIDE',
        'large'  => 'BootstrapDialog.SIZE_LARGE',
    ];
    public $title;
    public $size;

    public function init() {
        parent::init();
        $this->title = $this->title ?: '訊息提示';
        $this->size  = ($this->size && isset($this->sizeTypes[$this->size])) ? $this->size : 'small';

        $session = Yii::$app->session;
        $flashes = $session->getAllFlashes();
        $view = $this->getView();

        foreach ($flashes as $type => $data) {
            if (!isset($this->popupTypes[$type])) continue;
            $data = (array) $data;
            foreach ($data as $message) {
                $view->registerJs("
                    var dialogShow = BootstrapDialog.show({
                        type: {$this->popupTypes[$type]},
                        title: '{$this->title}',
                        message: '" . addslashes($message) . "',
                        size: {$this->sizeTypes[$this->size]},
                        buttons: [{
                            label: '關閉',
                            action: function(dialogItself) { dialogItself.close(); }
                        }]
                    });
                ");
                if ($type === 'success') {
                    $view->registerJs("setTimeout(function(){ dialogShow.close(); }, 3000);");
                }
            }
            $session->removeFlash($type); // 避免重複顯示
        }
    }
}

4. Layout 引用

use common\widgets\Popup;
<?= Popup::widget(['title' => '提示', 'size' => 'small']) ?>

六、小結

  • 引入 kartik-v/yii2-dialog 即刻擁有美觀、非同步對話框。
  • 覆寫 yii.confirm 讓 GridView 刪除按鈕自動套用新樣式。
  • 非同步 Confirm 必須採用回調寫法,切勿嘗試同步回傳值。
  • Flash 訊息可升級為彈窗,封裝 Popup 元件複用性高,成功訊息可自動關閉。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved