1. Добавляем виджет Select2 composer require kartik-v/yii2-widget-select2 2. Добавляем виджет ['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 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 ] ]) ?>