Yii 2 редактируемое дерево категорий
1. установим расширение
composer require --prefer-dist leandrogehlen/yii2-treegrid "*"
2. DDL таблицы
CREATE TABLE `tree` ( `id` INTEGER(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) COLLATE utf8_general_ci NOT NULL COMMENT 'имя', `url` VARCHAR(255) COLLATE utf8_general_ci DEFAULT NULL COMMENT 'путь', `tree_id` INTEGER(11) DEFAULT NULL COMMENT 'предок', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `id` (`id`) USING BTREE, UNIQUE KEY `name` (`name`) USING BTREE, UNIQUE KEY `url` (`url`) USING BTREE, KEY `tree_id` (`tree_id`) USING BTREE, CONSTRAINT `treee_fk1` FOREIGN KEY (`tree_id`) REFERENCES `tree` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=14 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' ;
3. \views\tree\index.php
<?php use yii\helpers\Html; use yii\grid\GridView; /* * *ext** */ use leandrogehlen\treegrid\TreeGrid; /* @var $this yii\web\View */ /* @var $searchModel app\modules\rpg\models\TreeSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = 'Trees'; $this->params['breadcrumbs'][] = $this->title; ?> <div class="tree-index"> <h1><?= Html::encode($this->title) ?></h1> <?php // echo $this->render('_search', ['model' => $searchModel]); ?> <p> <?php if ($dataProvider->count == 0) echo Html::a('Создать корневой элемент', ['add'], ['class' => 'btn btn-success']); ?> </p> <?= TreeGrid::widget([ 'dataProvider' => $dataProvider, 'keyColumnName' => 'id', 'showOnEmpty' => FALSE, 'parentColumnName' => 'tree_id', 'columns' => [ 'name', ['class' => 'yii\grid\ActionColumn', 'template' => '{view} {update} {delete} {add}', 'buttons' => [ 'add' => function ($url, $model, $key) { return Html::a('<span class="glyphicon glyphicon-plus"></span>', $url); }, ] ] ] ]); ?> </div>Если таблица пустая, тосоздаем корневой элемент
Создаем кнопку add для добавления потомка
4. models\Tree.php
<?php namespace app\modules\rpg\models; use Yii; /** * This is the model class for table "tree". * * @property integer $id * @property string $name * @property string $url * @property integer $tree_id * * @property Tree $tree * @property Tree[] $trees */ class Tree extends \yii\db\ActiveRecord { /** * @inheritdoc */ public static function tableName() { return 'tree'; } /** * @inheritdoc */ public function rules() { return [ [['name'], 'required'], [['tree_id'], 'integer'], [['name', 'url'], 'string', 'max' => 255], [['name'], 'unique'], [['url'], 'unique'], [['url'], 'default', 'value' => null], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'name' => 'имя', 'url' => 'путь', ]; } public function myname($id) { $model = Tree::find() ->where(['id' => $id]) ->one()->name; return $model; } /** * @return \yii\db\ActiveQuery */ public function getTree() { return $this->hasOne(Tree::className(), ['id' => 'tree_id']); } /** * @return \yii\db\ActiveQuery */ public function getTrees() { return $this->hasMany(Tree::className(), ['tree_id' => 'id']); } }
Немного поправил правило для сохранения NULL а не пустой строки
Создал функцию для имени
5. controllers\TreeController.php
<?php namespace app\modules\rpg\controllers; use Yii; use app\modules\rpg\models\Tree; use app\modules\rpg\models\TreeSearch; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; /* * *ext** */ use yii\data\ActiveDataProvider; /** * TreeController implements the CRUD actions for Tree model. */ class TreeController extends Controller { public function behaviors() { return [ 'verbs' => [ 'class' => VerbFilter::className(), 'actions' => [ 'delete' => ['post'], ], ], ]; } /** * Lists all Tree models. * @return mixed */ public function actionIndex() { $query = Tree::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); return $this->render('index', [ 'dataProvider' => $dataProvider ]); } /** * Displays a single Tree model. * @param integer $id * @return mixed */ public function actionView($id) { return $this->render('view', [ 'model' => $this->findModel($id), ]); } /** * Creates a new Tree model. * If creation is successful, the browser will be redirected to the 'view' page. * @return mixed */ public function actionCreate() { $model = new Tree(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } else { return $this->render('create', [ 'model' => $model, ]); } } public function actionAdd() { $model = new Tree(); $model->loadDefaultValues(); $id = Yii::$app->request->get('id'); $model->tree_id = $id; if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['index']); } else { return $this->render('create', [ 'model' => $model, ]); } } /** * Updates an existing Tree model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id * @return mixed */ public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } else { return $this->render('update', [ 'model' => $model, ]); } } /** * Deletes an existing Tree model. * If deletion is successful, the browser will be redirected to the 'index' page. * @param integer $id * @return mixed */ public function actionDelete($id) { $this->findModel($id)->delete(); return $this->redirect(['index']); } /** * Finds the Tree model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. * @param integer $id * @return Tree the loaded model * @throws NotFoundHttpException if the model cannot be found */ protected function findModel($id) { if (($model = Tree::findOne($id)) !== null) { return $model; } else { throw new NotFoundHttpException('The requested page does not exist.'); } } }
В index передаются данные для дерева
В add указывается предок
Удаление происходит каскадно за счет внешнего ключа
Исходники https://github.com/des1roer/yii2tree
Комментарии
Отправить комментарий