виджет_дерева_категорий

1. Добавляем виджет Select2

composer require kartik-v/yii2-widget-select2
2. Добавляем виджет
<?php

namespace backend\widgets;

use kartik\select2\Select2;
use yii\base\InvalidConfigException;
use yii\base\Model;
use yii\base\Widget;
use yii\helpers\Html;

class TreeDropDownWidget extends Widget
{
    /**
     * @var Model the data model that this widget is associated with.
     */
    public $model;
    /**
     * @var string the model attribute that this widget is associated with.
     */
    public $attribute;
    /**
     * @var string the input name. This must be set if [[model]] and [[attribute]] are not set.
     */
    public $name;

    /**
     * @var array [id=>['id'=>id,'parent_id'=>parent_id,'name'=>name]]
     */
    public $items = [];

    /**
     * @var array the HTML attributes for the input tag.
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = [];

    public $pluginOptions = [];


    /**
     * Initializes the widget.
     * If you override this method, make sure you call the parent implementation first.
     */
    public function init()
    {
        if ($this->name === null && !$this->hasModel()) {
            throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
        }
        if (!isset($this->options['id'])) {
            $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId();
        }
        parent::init();
    }

    /**
     * @return bool whether this widget is associated with a data model.
     */
    protected function hasModel()
    {
        return $this->model instanceof Model && $this->attribute !== null;
    }

    //Функция построения дерева из массива от Tommy Lacroix
    protected function getTree($dataset) {
        $tree = [];

        foreach ($dataset as $id => &$node) {
            //Если нет вложений
            if (!$node['parent_id']) {
                $tree[$id] = &$node;
            } else {
                //Если есть потомки то перебераем массив
                $dataset[$node['parent_id']]['childs'][$id] = &$node;
            }
        }
        return $tree;
    }

    protected function tplMenu($category, $str) {

        static $res = [];

        foreach ($category as $cat) {

            $res[$cat['id']] = $str . $cat['name'];

            if (isset($cat['childs'])) {
                $this->tplMenu($cat['childs'], $str . '   ');
            }
        }

        return $res;
    }

    protected function renderInputHtml()
    {
        $items = $this->tplMenu($this->getTree($this->items), '');

        if ($this->name === null)

            return Select2::widget([
                'model'=> $this->model,
                'attribute'=> $this->attribute,
                'data' => $items,
                'options' => $this->options,
                'pluginOptions' => $this->pluginOptions,

            ]);
        else
            return Select2::widget([
                'name' => $this->name,
                'data' => $items,
                'options' => $this->options,
                'pluginOptions' => $this->pluginOptions,

            ]);
    }

    public function run()
    {
        echo $this->renderInputHtml();
    }
}

3. Добавляем во view

    <?= $form->field($model, 'parent_id')->widget(TreeDropDownWidget::className(),
        [
           'items' => [
               1=>['id' => 1,'parent_id' => null, 'name' => 'Каталог'],
               2=>['id' => 2,'parent_id' => 1, 'name' => 'Одежда'],
               3=>['id' => 3,'parent_id' => 1, 'name' => 'Электроника'],
            ],
            'options' => [
                'encodeSpaces' => true,
                'prompt' => 'Выбрать..'
            ],
            'pluginOptions' => [
                'allowClear' => true
            ]
        ])
    ?>

  • виджет_дерева_категорий.txt
  • Последнее изменение: 2022/04/28 15:50
  • 127.0.0.1