kartik树视图在每个节点上显示不同的视图单击 [英] kartik tree view show different views on each node click

查看:119
本文介绍了kartik树视图在每个节点上显示不同的视图单击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Yii2.我使用 kartik树管理器创建了一棵树.默认情况下,在每个节点上单击都会显示IDname等.但是我想显示其他数据.下面是我的代码

 <?=
        TreeView::widget([
            'query' => \common\models\MdcNode::find()->addOrderBy('root, lft'),
            'headingOptions' => ['label' => 'Root'],
            'rootOptions' => ['label'=>'<span class="text-primary">Root</span>'],
            'topRootAsHeading' => true, // this will override the headingOptions
            'fontAwesome' => true,
            'isAdmin' => false,
            //'nodeView' => '',
            'toolbar'           => [
                TreeView::BTN_REFRESH => false,
                TreeView::BTN_CREATE => false,
                TreeView::BTN_CREATE_ROOT => false,
                TreeView::BTN_REMOVE => false,
                TreeView::BTN_SEPARATOR => false,
                TreeView::BTN_MOVE_UP => false,
                TreeView::BTN_MOVE_DOWN => false,
                TreeView::BTN_MOVE_LEFT => false,
                TreeView::BTN_MOVE_RIGHT => false,

            ],
        'showIDAttribute' => false,
            'showTooltips' => false,

            'showNameAttribute' => false,
            'softDelete' => false,
            'cacheSettings' => ['enableCache' => true]
        ]);
        ?>

查看

更新1

一些RnD之后,我发现详细信息窗口在<div id="w0-detail" class="kv-detail-container">

在我的JS中,我试图将其隐藏$('#w0-detail').hide();.现在,我想基于单击的不同节点来显示视图.

更新2

按照@Addi的答案,我已经更新了代码

 <?=
    TreeView::widget([
        'query' => \common\models\MdcNode::find()->addOrderBy('root, lft'),
        'headingOptions' => ['label' => 'Root'],
        'rootOptions' => ['label'=>'<span class="text-primary">Root</span>'],
        'topRootAsHeading' => true, // this will override the headingOptions
        //'displayValue' => 1,        // initial display value
        'isAdmin' => false,
        'fontAwesome' => true,
        //'nodeView' => '',
        //show => none removes the iconType etc setting under details
        'iconEditSettings'=>['show'=>'none'],

        'toolbar' =>
            [
            TreeView::BTN_REFRESH => false,
            TreeView::BTN_CREATE => false,
            TreeView::BTN_CREATE_ROOT => false,
            TreeView::BTN_REMOVE => false,
            TreeView::BTN_SEPARATOR => false,
            TreeView::BTN_MOVE_UP => false,
            TreeView::BTN_MOVE_DOWN => false,
            TreeView::BTN_MOVE_LEFT => false,
            TreeView::BTN_MOVE_RIGHT => false,
        ],

        'showIDAttribute' => false,
        'showTooltips' => false,

        'showNameAttribute' => false,
        'softDelete' => false,
        'cacheSettings' => ['enableCache' => true],
        //removing the detail below removes the second column of view(s) 1 - 5. Section 5 is being used to render the extra data. See frontend\config\main.php later.
        'mainTemplate'=>'<div class="row">
                        <div class="col-sm-3">
                            {wrapper}
                        </div>
                        <div class="col-sm-9">
                            {detail}
                        </div>
                     </div>',
        'treeViewSettings'=> [
        'nodeView' => '@kvtree/views/_form',
        'nodeAddlViews' => [
            1 => '',
            2 => '',
            3 => '',
            4 => '',
            5 => '',
    ]]

    ]);
    ?>

现在我出现错误Setting unknown property: kartik\tree\TreeView::treeViewSettings.我不知道为什么显示此错误.我一定想念一些我不知道的东西,并且坚持下去

任何帮助将不胜感激.

解决方案

以下结果是不需要进行的,不需要js隐藏细节.通过隐藏细节,将不会显示nodeAddlViews.这些节点包含在{detail}中.如果要取消隐藏详细信息,则可以在5个nodeAddlViews之一中显示额外的数据.

frontend \ views \ krajeeproducttree \ index.php

<?php
use yii\helpers\Html;
use kartik\tree\TreeView;
use frontend\models\KrajeeProductTree;

$this->title = Yii::t('app','Houses');
$this->params['breadcrumbs'][] = $this->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app','Index'), 'url' => ['krajeeproducttree/index']];
$this->params['breadcrumbs'][] = ['label' => Yii::t('app','Refresh Database with active houses'), 'url' => ['krajeeproducttree/populate']];
?>
<div class="krajeeproducttree-index">

    <h1><?= Html::encode($this->title) ?></h1>
    
<?php  
    echo TreeView::widget([
        // single query fetch to render the tree
        'query' => KrajeeProductTree::find()->addOrderBy('root, lft'), 
        'headingOptions' => ['label' => 'Categories'],
        'fontAwesome' => true,      // optional
        'isAdmin' => false,         // optional (toggle to enable admin mode)
        'displayValue' => 1,        // initial display value
        'softDelete' => true,       // defaults to true
        'cacheSettings' => [        
            'enableCache' => true   // defaults to true
        ],
        'hideTopRoot'=>true,
        'treeOptions' => ['style' => 'height:1000px width:900px' ],
        //more detail can be added to the node
        'nodeLabel' => function($node) {
                             return $node->name;
                       },
        //disable the toolbar completely                       
        'toolbar'           => [
                TreeView::BTN_REFRESH => false,
                TreeView::BTN_CREATE => false,
                TreeView::BTN_CREATE_ROOT => false,
                TreeView::BTN_REMOVE => false,
                TreeView::BTN_SEPARATOR => false,
                TreeView::BTN_MOVE_UP => false,
                TreeView::BTN_MOVE_DOWN => false,
                TreeView::BTN_MOVE_LEFT => false,
                TreeView::BTN_MOVE_RIGHT => false,
            ],                 
        'showIDAttribute' => false,
        'showTooltips' => false,
        'showNameAttribute' => false,
        'softDelete' => false,
        'cacheSettings' => ['enableCache' => true],
        //show => none removes the iconType etc setting under details                       
        'iconEditSettings'=>['show'=>'none'],
        //remove the form buttons
        'showFormButtons'=>false,
        'breadcrumbs'=>[//'depth'=>null,
                        'glue'=>'&raquo;',
                        'activeCss'=>'kv-crumb-active',
                        'untitled'=>'Untitled'
                       ],
        //removing header below removes the search button and header                       
        //'wrapperTemplate'=>'{header}{tree}{footer}',         
        'wrapperTemplate'=>'{tree}',
        //removing the detail below removes the second column of view(s) 1 - 5. Section 5 is being used to render the extra data. See frontend\config\main.php later.
        'mainTemplate'=>'<div class="row">
                            <div class="col-sm-3">
                                {wrapper}
                            </div>
                            <div class="col-sm-9">
                                {detail}
                            </div>
                         </div>'                       
    ]); 
?>
</div>

我发现上面的Treeview设置仍然使{Detail}的面包屑部分保持打开状态,并且保存和重置按钮仍处于启用状态.

下面的模型中的isDisabled部分对于不访问与vendor \ kartik-v \ yii2-tree-manager \ src \ views_form.php的内置面包屑部分相关联的保存和重置按钮具有特别重要的意义. 184),如下所示:

if ($node->isDisabled()) {
        $inputOpts['disabled'] = true;
    } 

frontend \ models \ krajeeproducttree.php

<?php
namespace frontend\models;

use Yii;
 
class KrajeeProductTree extends \kartik\tree\models\Tree
{
    public static function getDb()
    {
        return \frontend\components\Utilities::userdb();
    }
       
    public static function tableName()
    {
        return 'works_krajee_product_tree';
    }
    
    public function isDisabled()
    {
        //so if the user is an admin he will be able to edit the tree otherwise the tree will be disabled
        //but the nodes will be clickable and section 5 will be available.
        if (Yii::$app->user->can('Manage Admin')) {
            return false;
        } else { return true; }
    }
    
    public function rules()
    {
        return [
            [['product_id','productcategory_id','productsubcategory_id'],'integer'],
            [['product_id','productcategory_id','productsubcategory_id'],'default','value'=>null], 
            [['product_id','productcategory_id','productsubcategory_id'],'safe']
        ];
    }
}

上面的模型反映了3个外键的添加,每个外键在其各自的表中已添加到Krajeeproducttree表中.

下面的控制器从这3个表中构建一棵树.每次用户单击刷新面包屑,都会重建树.

frontend \ controllers \ KrajeeproducttreeController.php

<?php

namespace frontend\controllers;

use frontend\models\KrajeeProductTree;
use frontend\models\Productcategory;
use frontend\models\Productsubcategory;
use frontend\models\Product;
use kartik\tree\Controllers\NodeController;
use yii\filters\VerbFilter;

class KrajeeproducttreeController extends NodeController
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                   // 'delete' => ['POST'],
                ],
            ],
           'access' => 
                            [
                            'class' => \yii\filters\AccessControl::className(),
                            'only' => ['index','populate'],
                            'rules' => [
                            [
                              'allow' => true,
                              'roles' => ['@'],
                            ],
                            [
                              'allow' => false,
                              'roles' => ['?'],
                            ],  
                            [
                              'allow' => true,
                              'verbs' => ['POST']
                            ],  
                            ],
            ], 
        ];
    }
        
    public function actionIndex()
    {
        return $this->render('index');      
    }
    
    public function actionPopulate()
    {
        //remove all data in the database
        KrajeeProductTree::deleteAll();
        //rebuild the database given data from productcategory ie. postcode, productsubcategory ie. street, product ie. house
        //create the root and call it Run
        $root = new KrajeeProductTree(['name'=>'Run']);
        $root->makeRoot();
        //create the postcode nodes
        $allpostcodes =[];
        $allpostcodes = Productcategory::find()->orderBy('id')->all();
        foreach ($allpostcodes as $key => $value)
        {
            $newpostcodenode = new KrajeeProductTree(['name'=>$allpostcodes[$key]['name']]);
            $newpostcodenode->productcategory_id = $allpostcodes[$key]['id']; 
            $newpostcodenode->prependTo($root);
            $allstreets = [];
            $allstreets = Productsubcategory::find()
                        ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                        ->all();
            //create the street nodes associated with this new node
            $allhouses = [];
            foreach ($allstreets as $key => $value)
            {
                $newstreetnode = new KrajeeProductTree(['name'=>$allstreets[$key]['name']]);
                $newstreetnode->productsubcategory_id = $allstreets[$key]['id'] ;
                $newstreetnode->prependTo($newpostcodenode);
                $allhouses = Product::find()
                        ->where(['productsubcategory_id'=>$allstreets[$key]['id']])
                        ->andWhere(['productcategory_id'=>$allstreets[$key]['productcategory_id']])
                        ->andWhere(['isactive'=>1])
                        ->all();
                //create the house nodes associated with this new steet node
                foreach ($allhouses as $key => $value)
                {
                    $newhousenode = new KrajeeProductTree(['name'=>$allhouses[$key]['productnumber']]);
                    $newhousenode->product_id = $allhouses[$key]['id'];
                    $newhousenode->prependTo($newstreetnode);
                }  
            }  
        }      
        return $this->render('index'); 
    }     
}

frontend \ config \ main.php在模块"部分下.

'treemanager' =>  [
        'class' => 'kartik\tree\Module',
        'treeViewSettings'=> [
            'nodeView' => '@kvtree/views/_form',    
            'nodeAddlViews' => [
                1 => '',
                2 => '',
                3 => '',
                4 => '',
                5 => '@app/views/krajeeproducttree/product',
        ]]    
       ],

正如Kartik-v所提到的,如果视图在frontend \ config \ main.php中的treeViewSettings下列出,则该视图将继承$ node变量.

frontend \ views \ krajeeproducttree \ product.php

<?php
   use Yii;
   use yii\helpers\Url;
   use yii\helpers\Html;
?>
<div class="krajeeproducttree-product">
    <br>
        <?php
          if ($node->product_id > 0){
            echo Html::a('<h4>View House Details: ' .$node->name. '</h4>',Url::toRoute(['/product/view','id'=>$node->product_id]));
          }         
          if ($node->productsubcategory_id > 0){
            echo Html::a('<h4>View Street Details: ' .$node->name. '</h4>',Url::toRoute(['/productsubcategory/view','id'=>$node->productsubcategory_id]));
          }         
          if ($node->productcategory_id > 0){
            echo Html::a('<h4>View Postcode Details: ' .$node->name. '</h4>',Url::toRoute(['/productcategory/view','id'=>$node->productcategory_id]));
          }         
        ?>
    <br>
</div>

希望这会对您或将来的某人有所帮助.

对费萨尔的回应: 令人困惑...是的,仅当您在扩展模型中具有指向其表的外键时,product.php才有用,以便您可以将带有URL的节点链接到与表关联的控制器/操作/ID.我这样做是为了避免在单击每个节点时显示大量信息.

这是没有外键的控制器:

public function actionPopulate()
        {
            //remove all data in the database
            KrajeeProductTree::deleteAll();
            //rebuild the database given data from productcategory ie. postcode, productsubcategory ie. street, product ie. house
            //create the root and call it Run
            $root = new KrajeeProductTree(['name'=>'Run']);
            $root->makeRoot();
            //create the postcode nodes
            $allpostcodes =[];
            $allpostcodes = Productcategory::find()->orderBy('id')->all();
            foreach ($allpostcodes as $key => $value)
            {
                $newpostcodenode = new KrajeeProductTree(['name'=>$allpostcodes[$key]['name']]);
                $newpostcodenode->prependTo($root);
                $allstreets = [];
                $allstreets = Productsubcategory::find()
                            ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                            ->all();
                //create the street nodes associated with this new node
                $allhouses = [];
                foreach ($allstreets as $key => $value)
                {
                    $newstreetnode = new KrajeeProductTree(['name'=>$allstreets[$key]['name']]);
                    $newstreetnode->prependTo($newpostcodenode);
                    $allhouses = Product::find()
                            ->where(['productsubcategory_id'=>$allstreets[$key]['id']])
                            ->andWhere(['productcategory_id'=>$allstreets[$key]['productcategory_id']])
                            ->andWhere(['isactive'=>1])
                            ->all();
                    //create the house nodes associated with this new steet node
                    foreach ($allhouses as $key => $value)
                    {
                        $newhousenode = new KrajeeProductTree(['name'=>$allhouses[$key]['productnumber']]);
                        $newhousenode->prependTo($newstreetnode);
                    }  
                }  
            }      
            return $this->render('index'); 
        }

您将注意到子节点位于ie之前. prependTo父节点.您可以对要为其创建树的模块中的所有模型执行此操作.您还将注意到控制器是从NodeController扩展的.

这是表格本身的格式.

产品类别,即邮政编码具有一个ID自动递增字段.产品分类即街道上还有一个ID自动递增字段.另外,Productsubcategory具有指向Productcategory表的外键productcategory_id.

产品表,即房屋有其id自动递增字段.此外,它具有两个外键,即.指向Productsubcategory表的productsubcategory_id.它还具有指向Productcategory表的外键productcategory_id.

此结构有助于链接这三个级别,并使用以上链接中上述模型中使用的Yii2关系建模结构.

每条街道都链接到一个邮政编码,即.表中的productcategory_id Productsubcategory(街道)与Productcategory表的ID字段相同, 此结构还有助于检索每个节点的数据.因此,控制器中的以下代码链接了两个级别:

$allstreets = Productsubcategory::find()
                            ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                            ->all();

在frontend \ config \ main.php下,您已经添加了nodeView,这是否必要?我也无法在您的代码中找到... krajeeproducttree/product.

nodeView是一个别名,该别名与指向呈现细节的视图的路径连接在一起,可以在vendor \ kartik-v \ yii2-tree-manager \ src \ Module的第81行中找到.如果未在config \ main.php下提及,则默认值为'@ kvtree/views/_form'. 此_form已扩展可以修改_form并插入到模型的视图下,但是必须正确地使用别名,例如@app \ views \ krajeeproducttree \ _form.php./p>

现在我遇到一个错误,正在设置未知属性:kartik \ tree \ TreeView :: treeViewSettings ...

treeViewSettings不是\ vendor \ kartik-v \ yii2-tree-manager \ src \ TreeView下列出的变量,但是在第137行上,存在nodeView而在第153行上存在nodeAddlViews,因此您可以单独使用这些变量. IE.不在您选择构建的每个单独的Tree的treeViewSettings中.

我也找不到您代码中的..... krajeeproducttree/product ...

是的,可以预期,控制器KrajeeproductreeController将具有一个名为product的操作,以调用产品视图product.php.通常这是预期的,但是如果在为nodeAddlViews创建的任何视图中执行var_dump($ node),则将获得$ node的数组.通常,您必须在控制器中将参数与渲染一起传递.

return $this->render('index', [
            'node' => $node
        ]); 

但是Krajee在这里提到了您正在自动获取该信息的事实.

上面的每个视图都将直接接收并读取与上面的nodeView部分中提到的参数相同的参数(例如,这些参数将以$ node,$ modelClass,$ action等形式提供给视图.)此外,视图还将接收$ form参数,该参数是ActiveForm实例(来自kartik-v/yii2-widget-activeform).

因此,无需采取任何措施. $ node的值在这里生成:

供应商文件夹中TreeView中的第1211行

public function renderDetail()
    {
        /**
         * @var Tree $modelClass
         * @var Tree $node
         */
        $modelClass = $this->query->modelClass;
        $node = $this->displayValue ? $modelClass::findOne($this->displayValue) : null;
        if (empty($node)) {
            $node = new $modelClass;
        }

呈现细节时会创建$ node值.

I am working on Yii2. I have created a tree using kartik tree manager. By default on each node click it shows me ID, name etc. But I want to show other data. Below is my code

 <?=
        TreeView::widget([
            'query' => \common\models\MdcNode::find()->addOrderBy('root, lft'),
            'headingOptions' => ['label' => 'Root'],
            'rootOptions' => ['label'=>'<span class="text-primary">Root</span>'],
            'topRootAsHeading' => true, // this will override the headingOptions
            'fontAwesome' => true,
            'isAdmin' => false,
            //'nodeView' => '',
            'toolbar'           => [
                TreeView::BTN_REFRESH => false,
                TreeView::BTN_CREATE => false,
                TreeView::BTN_CREATE_ROOT => false,
                TreeView::BTN_REMOVE => false,
                TreeView::BTN_SEPARATOR => false,
                TreeView::BTN_MOVE_UP => false,
                TreeView::BTN_MOVE_DOWN => false,
                TreeView::BTN_MOVE_LEFT => false,
                TreeView::BTN_MOVE_RIGHT => false,

            ],
        'showIDAttribute' => false,
            'showTooltips' => false,

            'showNameAttribute' => false,
            'softDelete' => false,
            'cacheSettings' => ['enableCache' => true]
        ]);
        ?>

View

Update 1

After some RnD I have found that the detail window is under <div id="w0-detail" class="kv-detail-container">

In my JS I have tried to hide it $('#w0-detail').hide();. Now I want to show the view on based on different nodes clicked.

Update 2

As per @Addi answer, I have updated my code

 <?=
    TreeView::widget([
        'query' => \common\models\MdcNode::find()->addOrderBy('root, lft'),
        'headingOptions' => ['label' => 'Root'],
        'rootOptions' => ['label'=>'<span class="text-primary">Root</span>'],
        'topRootAsHeading' => true, // this will override the headingOptions
        //'displayValue' => 1,        // initial display value
        'isAdmin' => false,
        'fontAwesome' => true,
        //'nodeView' => '',
        //show => none removes the iconType etc setting under details
        'iconEditSettings'=>['show'=>'none'],

        'toolbar' =>
            [
            TreeView::BTN_REFRESH => false,
            TreeView::BTN_CREATE => false,
            TreeView::BTN_CREATE_ROOT => false,
            TreeView::BTN_REMOVE => false,
            TreeView::BTN_SEPARATOR => false,
            TreeView::BTN_MOVE_UP => false,
            TreeView::BTN_MOVE_DOWN => false,
            TreeView::BTN_MOVE_LEFT => false,
            TreeView::BTN_MOVE_RIGHT => false,
        ],

        'showIDAttribute' => false,
        'showTooltips' => false,

        'showNameAttribute' => false,
        'softDelete' => false,
        'cacheSettings' => ['enableCache' => true],
        //removing the detail below removes the second column of view(s) 1 - 5. Section 5 is being used to render the extra data. See frontend\config\main.php later.
        'mainTemplate'=>'<div class="row">
                        <div class="col-sm-3">
                            {wrapper}
                        </div>
                        <div class="col-sm-9">
                            {detail}
                        </div>
                     </div>',
        'treeViewSettings'=> [
        'nodeView' => '@kvtree/views/_form',
        'nodeAddlViews' => [
            1 => '',
            2 => '',
            3 => '',
            4 => '',
            5 => '',
    ]]

    ]);
    ?>

Now I am getting an error Setting unknown property: kartik\tree\TreeView::treeViewSettings. I don't know why this error is showing. I must be missing something that I don't know and I am stuck to it

Any help would be highly appreciated.

解决方案

The following results were made without the need for js to hide the detail. By hiding the detail the nodeAddlViews will not be displayed. These nodes are contained in the {detail}. If you were to unhide the detail you would reveal the extra data in one of the 5 nodeAddlViews.

frontend\views\krajeeproducttree\index.php

<?php
use yii\helpers\Html;
use kartik\tree\TreeView;
use frontend\models\KrajeeProductTree;

$this->title = Yii::t('app','Houses');
$this->params['breadcrumbs'][] = $this->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app','Index'), 'url' => ['krajeeproducttree/index']];
$this->params['breadcrumbs'][] = ['label' => Yii::t('app','Refresh Database with active houses'), 'url' => ['krajeeproducttree/populate']];
?>
<div class="krajeeproducttree-index">

    <h1><?= Html::encode($this->title) ?></h1>
    
<?php  
    echo TreeView::widget([
        // single query fetch to render the tree
        'query' => KrajeeProductTree::find()->addOrderBy('root, lft'), 
        'headingOptions' => ['label' => 'Categories'],
        'fontAwesome' => true,      // optional
        'isAdmin' => false,         // optional (toggle to enable admin mode)
        'displayValue' => 1,        // initial display value
        'softDelete' => true,       // defaults to true
        'cacheSettings' => [        
            'enableCache' => true   // defaults to true
        ],
        'hideTopRoot'=>true,
        'treeOptions' => ['style' => 'height:1000px width:900px' ],
        //more detail can be added to the node
        'nodeLabel' => function($node) {
                             return $node->name;
                       },
        //disable the toolbar completely                       
        'toolbar'           => [
                TreeView::BTN_REFRESH => false,
                TreeView::BTN_CREATE => false,
                TreeView::BTN_CREATE_ROOT => false,
                TreeView::BTN_REMOVE => false,
                TreeView::BTN_SEPARATOR => false,
                TreeView::BTN_MOVE_UP => false,
                TreeView::BTN_MOVE_DOWN => false,
                TreeView::BTN_MOVE_LEFT => false,
                TreeView::BTN_MOVE_RIGHT => false,
            ],                 
        'showIDAttribute' => false,
        'showTooltips' => false,
        'showNameAttribute' => false,
        'softDelete' => false,
        'cacheSettings' => ['enableCache' => true],
        //show => none removes the iconType etc setting under details                       
        'iconEditSettings'=>['show'=>'none'],
        //remove the form buttons
        'showFormButtons'=>false,
        'breadcrumbs'=>[//'depth'=>null,
                        'glue'=>'&raquo;',
                        'activeCss'=>'kv-crumb-active',
                        'untitled'=>'Untitled'
                       ],
        //removing header below removes the search button and header                       
        //'wrapperTemplate'=>'{header}{tree}{footer}',         
        'wrapperTemplate'=>'{tree}',
        //removing the detail below removes the second column of view(s) 1 - 5. Section 5 is being used to render the extra data. See frontend\config\main.php later.
        'mainTemplate'=>'<div class="row">
                            <div class="col-sm-3">
                                {wrapper}
                            </div>
                            <div class="col-sm-9">
                                {detail}
                            </div>
                         </div>'                       
    ]); 
?>
</div>

I found the Treeview setup above, still left the breadcrumbs section of the {Detail} open with the save and reset buttons still enabled.

The isDisabled section in the model below is particularly important in not giving access to the save and reset button associated with the inbuilt breadcrumb section of vendor\kartik-v\yii2-tree-manager\src\views_form.php.(Line 184) as seen here:

if ($node->isDisabled()) {
        $inputOpts['disabled'] = true;
    } 

frontend\models\krajeeproducttree.php

<?php
namespace frontend\models;

use Yii;
 
class KrajeeProductTree extends \kartik\tree\models\Tree
{
    public static function getDb()
    {
        return \frontend\components\Utilities::userdb();
    }
       
    public static function tableName()
    {
        return 'works_krajee_product_tree';
    }
    
    public function isDisabled()
    {
        //so if the user is an admin he will be able to edit the tree otherwise the tree will be disabled
        //but the nodes will be clickable and section 5 will be available.
        if (Yii::$app->user->can('Manage Admin')) {
            return false;
        } else { return true; }
    }
    
    public function rules()
    {
        return [
            [['product_id','productcategory_id','productsubcategory_id'],'integer'],
            [['product_id','productcategory_id','productsubcategory_id'],'default','value'=>null], 
            [['product_id','productcategory_id','productsubcategory_id'],'safe']
        ];
    }
}

The above model reflects the addition of 3 foreign keys each primary keys in their respective table that have been added to the Krajeeproducttree table.

The below controller builds a tree from these 3 tables. Everytime the user clicks on the refresh breadcrumb the tree is rebuilt.

frontend\controllers\KrajeeproducttreeController.php

<?php

namespace frontend\controllers;

use frontend\models\KrajeeProductTree;
use frontend\models\Productcategory;
use frontend\models\Productsubcategory;
use frontend\models\Product;
use kartik\tree\Controllers\NodeController;
use yii\filters\VerbFilter;

class KrajeeproducttreeController extends NodeController
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                   // 'delete' => ['POST'],
                ],
            ],
           'access' => 
                            [
                            'class' => \yii\filters\AccessControl::className(),
                            'only' => ['index','populate'],
                            'rules' => [
                            [
                              'allow' => true,
                              'roles' => ['@'],
                            ],
                            [
                              'allow' => false,
                              'roles' => ['?'],
                            ],  
                            [
                              'allow' => true,
                              'verbs' => ['POST']
                            ],  
                            ],
            ], 
        ];
    }
        
    public function actionIndex()
    {
        return $this->render('index');      
    }
    
    public function actionPopulate()
    {
        //remove all data in the database
        KrajeeProductTree::deleteAll();
        //rebuild the database given data from productcategory ie. postcode, productsubcategory ie. street, product ie. house
        //create the root and call it Run
        $root = new KrajeeProductTree(['name'=>'Run']);
        $root->makeRoot();
        //create the postcode nodes
        $allpostcodes =[];
        $allpostcodes = Productcategory::find()->orderBy('id')->all();
        foreach ($allpostcodes as $key => $value)
        {
            $newpostcodenode = new KrajeeProductTree(['name'=>$allpostcodes[$key]['name']]);
            $newpostcodenode->productcategory_id = $allpostcodes[$key]['id']; 
            $newpostcodenode->prependTo($root);
            $allstreets = [];
            $allstreets = Productsubcategory::find()
                        ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                        ->all();
            //create the street nodes associated with this new node
            $allhouses = [];
            foreach ($allstreets as $key => $value)
            {
                $newstreetnode = new KrajeeProductTree(['name'=>$allstreets[$key]['name']]);
                $newstreetnode->productsubcategory_id = $allstreets[$key]['id'] ;
                $newstreetnode->prependTo($newpostcodenode);
                $allhouses = Product::find()
                        ->where(['productsubcategory_id'=>$allstreets[$key]['id']])
                        ->andWhere(['productcategory_id'=>$allstreets[$key]['productcategory_id']])
                        ->andWhere(['isactive'=>1])
                        ->all();
                //create the house nodes associated with this new steet node
                foreach ($allhouses as $key => $value)
                {
                    $newhousenode = new KrajeeProductTree(['name'=>$allhouses[$key]['productnumber']]);
                    $newhousenode->product_id = $allhouses[$key]['id'];
                    $newhousenode->prependTo($newstreetnode);
                }  
            }  
        }      
        return $this->render('index'); 
    }     
}

frontend\config\main.php under Modules section.

'treemanager' =>  [
        'class' => 'kartik\tree\Module',
        'treeViewSettings'=> [
            'nodeView' => '@kvtree/views/_form',    
            'nodeAddlViews' => [
                1 => '',
                2 => '',
                3 => '',
                4 => '',
                5 => '@app/views/krajeeproducttree/product',
        ]]    
       ],

As has been mentioned by Kartik-v, the $node variable is inherited by the view if the view is listed under the treeViewSettings in the frontend\config\main.php.

frontend\views\krajeeproducttree\product.php

<?php
   use Yii;
   use yii\helpers\Url;
   use yii\helpers\Html;
?>
<div class="krajeeproducttree-product">
    <br>
        <?php
          if ($node->product_id > 0){
            echo Html::a('<h4>View House Details: ' .$node->name. '</h4>',Url::toRoute(['/product/view','id'=>$node->product_id]));
          }         
          if ($node->productsubcategory_id > 0){
            echo Html::a('<h4>View Street Details: ' .$node->name. '</h4>',Url::toRoute(['/productsubcategory/view','id'=>$node->productsubcategory_id]));
          }         
          if ($node->productcategory_id > 0){
            echo Html::a('<h4>View Postcode Details: ' .$node->name. '</h4>',Url::toRoute(['/productcategory/view','id'=>$node->productcategory_id]));
          }         
        ?>
    <br>
</div>

Hopefully this will be of assistance to you or perhaps someone in the future.

Response to Faisal: Confusing...Yes the product.php will only be useful if you have foreign id keys in your extended model pointing to their table so that you can link the node with a url to the controller/action/id associated with the table. I did this in order to avoid displaying a large amount of information if each node is clicked.

Here is the controller without the foreign keys:

public function actionPopulate()
        {
            //remove all data in the database
            KrajeeProductTree::deleteAll();
            //rebuild the database given data from productcategory ie. postcode, productsubcategory ie. street, product ie. house
            //create the root and call it Run
            $root = new KrajeeProductTree(['name'=>'Run']);
            $root->makeRoot();
            //create the postcode nodes
            $allpostcodes =[];
            $allpostcodes = Productcategory::find()->orderBy('id')->all();
            foreach ($allpostcodes as $key => $value)
            {
                $newpostcodenode = new KrajeeProductTree(['name'=>$allpostcodes[$key]['name']]);
                $newpostcodenode->prependTo($root);
                $allstreets = [];
                $allstreets = Productsubcategory::find()
                            ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                            ->all();
                //create the street nodes associated with this new node
                $allhouses = [];
                foreach ($allstreets as $key => $value)
                {
                    $newstreetnode = new KrajeeProductTree(['name'=>$allstreets[$key]['name']]);
                    $newstreetnode->prependTo($newpostcodenode);
                    $allhouses = Product::find()
                            ->where(['productsubcategory_id'=>$allstreets[$key]['id']])
                            ->andWhere(['productcategory_id'=>$allstreets[$key]['productcategory_id']])
                            ->andWhere(['isactive'=>1])
                            ->all();
                    //create the house nodes associated with this new steet node
                    foreach ($allhouses as $key => $value)
                    {
                        $newhousenode = new KrajeeProductTree(['name'=>$allhouses[$key]['productnumber']]);
                        $newhousenode->prependTo($newstreetnode);
                    }  
                }  
            }      
            return $this->render('index'); 
        }

You will notice that children nodes are prepended to ie. prependTo the parent node. You can do this for all your models within your modules that you intend to create a tree for. You will also notice that the controller is extended from the NodeController.

Here is the format of the tables themselves.

Productcategory ie. Postcodes has an id autoincrement field. Productsubcategory ie. streets also has an id autoincrement field. In addition Productsubcategory has a foreign key productcategory_id that points to the Productcategory table.

The Product table ie. houses has its id autoincrement field. In addition it has two foreign keys ie. productsubcategory_id that points to the Productsubcategory table. It also has a foreign key productcategory_id that points to the Productcategory table.

This structure helps to link the three levels and also to use Yii2's relation modeling structure which is used in the above models in the above link.

Each street is linked to one postcode, ie. productcategory_id from table Productsubcategory (street) is the same as Productcategory table's id field, This structure also helps to retrieve data for each node. So the following code in the controller links the two levels:

$allstreets = Productsubcategory::find()
                            ->where(['productcategory_id'=>$allpostcodes[$key]['id']])
                            ->all();

Under the frontend\config\main.php you have added nodeView, is this necessary? also I can't find ...krajeeproducttree/product in your code.

nodeView is an alias concatenated with a path pointing to the view that renders the detail and is found on line 81 of vendor\kartik-v\yii2-tree-manager\src\Module. The default value is '@kvtree/views/_form' if not mentioned under the config\main.php. This _form is extended by the nodeAddlViews and has to exist if you want to show additional information. The _form can be modified and inserted under your model's views but will have to be correctly aliased eg @app \ views \krajeeproducttree \ _form.php.

Now I am getting an error Setting unknown property: kartik\tree\TreeView::treeViewSettings...

treeViewSettings is not a variable listed under \vendor\kartik-v\yii2-tree-manager\src\TreeView however on line 137, nodeView exists and on line 153 nodeAddlViews exists so you will be able to use these variables separately. ie. not within treeViewSettings for each separate Tree that you choose to build.

Also I can't find .....krajeeproducttree/product in your code...

Yes it would be expected that the controller KrajeeproductreeController would have an action called product to call up the product view product.php. This is normally expected but if you do a var_dump($node) in any of the views that you create for the nodeAddlViews you will get an array for $node. Normally you have to pass a parameter with the render in the controller eg.

return $this->render('index', [
            'node' => $node
        ]); 

but the fact that you are getting this automatically is mentioned here by Krajee.

Each of the views above will directly receive and can read the same parameters as mentioned in the nodeView section above (e.g. these will be available to the view as $node, $modelClass, $action etc.). In addition, the views will also receive the $form parameter, which is the ActiveForm instance (from kartik-v/yii2-widget-activeform).

So therefore there is no need for an action. The $node value is generated here:

Line 1211 in TreeView in the vendor folder

public function renderDetail()
    {
        /**
         * @var Tree $modelClass
         * @var Tree $node
         */
        $modelClass = $this->query->modelClass;
        $node = $this->displayValue ? $modelClass::findOne($this->displayValue) : null;
        if (empty($node)) {
            $node = new $modelClass;
        }

The $node value is created when the detail is rendered.

这篇关于kartik树视图在每个节点上显示不同的视图单击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆