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

Yii2 DropDownList 下拉選單實戰:新增/編輯分類時動態排除自身 ID

     編輯:PHP 綜合知識

Yii2 DropDownList 是表單下拉選單常用元件。本文以「無限分類管理」為例,示範新增時顯示全部分類、編輯時自動排除當前分類 ID (防止選自己當父分類),完整涵蓋控制器資料準備、視圖渲染、ArrayHelper 轉換與提示文字設定。

資料庫結構 (category)

CREATE TABLE `category` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `pid` INT(11) DEFAULT 0 COMMENT '父分類ID',
  `title` VARCHAR(100) NOT NULL COMMENT '分類標題',
  `name` VARCHAR(100) NOT NULL COMMENT '分類別名',
  `keywords` VARCHAR(255) DEFAULT '',
  `description` VARCHAR(255) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

控制器動作 (CategoryController)

namespace backend\controllers;
use Yii;
use common\models\Category;
use yii\web\Controller;
use yii\web\NotFoundHttpException;

class CategoryController extends Controller {
    public function actionCreate() {
        $model = new Category();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
        return $this->render('form', ['model' => $model]);
    }

    public function actionUpdate($id) {
        $model = $this->findModel($id);
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
        return $this->render('form', ['model' => $model]);
    }

    protected function findModel($id) {
        if (($model = Category::findOne($id)) !== null) return $model;
        throw new NotFoundHttpException('頁面不存在');
    }
}

視圖檔案 (views/category/_form.php)

<?php
use common\models\Category;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model common\models\Category */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="category-form">
    <?php $form = ActiveForm::begin(); ?>

    <?=
    $form->field($model, 'title')
        ->textInput(['maxlength' => 100])
        ->label('分類標題')
    ?>

    <?=
    $form->field($model, 'name')
        ->textInput(['maxlength' => 100])
        ->label('分類別名')
    ?>

    <?php
    // 關鍵邏輯:編輯時排除自身 ID
    if (!$model->isNewRecord) {
        $categories = Category::find()
            ->where(['!=', 'id', $model->id])
            ->all();
    } else {
        $categories = Category::find()->all();
    }
    $cateList = ArrayHelper::map($categories, 'id', 'title');
    ?>

    <?=
    $form->field($model, 'pid')
        ->dropDownList($cateList, [
            'prompt' => '請選擇父分類', // 預設提示選項
            'class' => 'form-control'
        ])
        ->label('父分類')
    ?>

    <?=
    $form->field($model, 'keywords')
        ->textarea(['maxlength' => 255])
        ->label('分類關鍵詞')
    ?>

    <?=
    $form->field($model, 'description')
        ->textarea(['maxlength' => 255])
        ->label('分類描述')
    ?>

    <div class="form-group">
        <?= Html::submitButton(
            $model->isNewRecord ? '建立' : '更新',
            ['class' => $model->isNewRecord ? 'btn btn-success btn-block' : 'btn btn-primary btn-block']
        ) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

關鍵點解析

程式碼說明
$model->isNewRecord判斷是新增還是編輯,決定是否排除自身
->where(['!=', 'id', $model->id])SQL 條件排除當前分類,避免循環引用
ArrayHelper::map($models, 'id', 'title')將 ActiveRecord 陣列轉為 [id => title] 鍵值陣列,供 dropDownList 使用
'prompt' => '請選擇父分類'產生 <option value="">請選擇父分類</option>,value 為空字串
'empty' => '無父分類'替代寫法,語意相同,prompt 為 Yii2 2.0.11+ 推薦

進階:遞迴縮排顯示層級

若需在下拉選單顯示層級縮排 (如 `└─ 子分類`),可在查詢後用遞迴函式處理:

function buildTree(array $cats, $pid = 0, $level = 0) {
    $result = [];
    foreach ($cats as $cat) {
        if ($cat['pid'] == $pid) {
            $cat['title'] = str_repeat('└─ ', $level) . $cat['title'];
            $result[$cat['id']] = $cat['title'];
            $result += buildTree($cats, $cat['id'], $level + 1);
        }
    }
    return $result;
}
$allCats = Category::find()->asArray()->all();
$cateList = buildTree($allCats);

常見問題排查

  • ❌ 下拉選單空白 → 檢查 $cateList 是否為空陣列、ArrayHelper::map 鍵名是否正確。
  • ❌ 編輯時仍可選自己 → 確認 $model->isNewRecord 判斷正確、where(['!=', 'id', $model->id]) 生效。
  • ❌ 儲存後 pid 為 0 → 表單 name 屬性正確、模型 pid 屬性存在、驗證規則允許空值。

相關專題:《Yii 框架入門及常用技巧總結》、《PHP 優秀開發框架總結》。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved