Yii2显示/隐藏kartik树视图节点

时间:2020-06-29 06:10:22

标签: treeview yii2-advanced-app treenode kartik-v

我正在使用Kartik Tree Manager。我能够添加,删除,更新节点。还有更多的要求,那就是根据用户访问权限显示/隐藏节点。即,当为用户提供特定节点时,则仅应显示具有所有子节点(如果有)的特定节点。

到目前为止我做了什么?

我已经创建了一个表user-node,其中正在向用户分配节点ID,如下所示

enter image description here

我想做什么

现在我只想只显示指定节点及其子节点,并向该用户隐藏其他节点

enter image description here

控制器

目前,我在两种视图中渲染树结构,但将来会有更多视图

  1. 我的首页

    public function actionIndex()
    {
       if(Yii::$app->user->isGuest){
        $this->redirect(Yii::$app->urlManager->createUrl('site/login'));
        }
       return $this->render('index');
    }
    
  2. 本身是树管理器节点控制器

    /**
    * View, create, or update a tree node via ajax
    *
    * @return mixed json encoded response
    */
    public function actionManage()
    {
        static::checkValidRequest();
        $data = static::getPostData();
        $nodeTitles = TreeSecurity::getNodeTitles($data);
        $callback = function () use ($data, $nodeTitles) {
        $id = ArrayHelper::getValue($data, 'id', null);
        $parentKey = ArrayHelper::getValue($data, 'parentKey', '');
        $parsedData = TreeSecurity::parseManageData($data);
        $out = $parsedData['out'];
        $oldHash = $parsedData['oldHash'];
        $newHash = $parsedData['newHash'];
        /**
         * @var Module $module
         * @var Tree $treeClass
         * @var Tree $node
         */
        $treeClass = $out['treeClass'];
        if (!isset($id) || empty($id)) {
            $node = new $treeClass;
            $node->initDefaults();
        } else {
            $node = $treeClass::findOne($id);
        }
        $module = TreeView::module();
        $params = $module->treeStructure + $module->dataStructure + [
                'node' => $node,
                'parentKey' => $parentKey,
                'treeManageHash' => $newHash,
                'treeRemoveHash' => ArrayHelper::getValue($data, 'treeRemoveHash', ''),
                'treeMoveHash' => ArrayHelper::getValue($data, 'treeMoveHash', ''),
            ] + $out;
        if (!empty($data['nodeViewParams'])) {
            $params = ArrayHelper::merge($params, unserialize($data['nodeViewParams']));
        }
        if (!empty($module->unsetAjaxBundles)) {
            $cb = function ($e) use ($module) {
                foreach ($module->unsetAjaxBundles as $bundle) {
                    unset($e->sender->assetBundles[$bundle]);
                }
            };
            Event::on(View::class, View::EVENT_AFTER_RENDER, $cb);
        }
        TreeSecurity::checkSignature('manage', $oldHash, $newHash);
        return $this->renderAjax($out['nodeView'], ['params' => $params]);
    };
    return self::process(
        $callback,
        Yii::t('kvtree', 'Error while viewing the {node}. Please try again later.', $nodeTitles),
        null
    );
    }
    

如何实现?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

一种实现隐藏/显示某些节点​​的方法如下:

  • 在视图中,您应该具有数据库表名称。

  • 查找您感兴趣的表名。

  • 在表名的文件夹内应该有类似_form.php,_script.php和index.php的文件名

  • index.php文件应该有一些用途,其中应该有: ...

    使用kartik \ tree \ TreeView;

    使用kartik \ tree \ Module;

...

  • 在这些use语句之后,您可以添加以下代码:

    / ** @var整数$ uid * /

      // get current logged in user id.
    
      // this is used to control showing tree content, and
    
      // to control form fields.
    
      if (isset(Yii::$app->user)) {
          $uid = Yii::$app->user->getId();
      }
    
  • 因此,现在登录的用户ID保存在变量$ uid

  • 在相同的index.php文件中,您应该具有呈现树状视图的代码。始于:echo TreeView :: widget

  • 在此TreeView :: widget([..中,您可以添加仅显示当前已登录用户内容的查询,如下所示:

    'query'=> YourTableName :: find()-> where([['user_id'=> $ uid])-> addOrderBy('root,lft'),

...其他设置...

如果您希望管理员查看或更改内容,则可以添加一个名为AdminController的控制器,然后在此index.php TreeView :: widget中添加以下更多选项:

echo TreeView::widget([

    'query' => YourTableName::find()->where(['user_id' => $uid])->addOrderBy('root, lft'),

    'headingOptions' => ['label' => 'YourLableName'],

    //'rootOptions' => ['label' => '<span class="text-success">Root</span>'],

    'fontAwesome' => false,

    'isAdmin' => true,

    'showInactive' => AdminController::isAdmin(),

    'displayValue' => 0,

    'showIDAttribute' => true,

    'emptyNodeMsg' => ' type some msg here ... .',

    'showCheckbox' => false,

    'multiple' => false,

    'options' => ['id' => 'treeID'],

    'allowNewRoots' => false,

    'toolbar' => [
    'create' => ['alwaysDisabled' => true],
    //'remove' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-up' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-down' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-left' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-right' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    //'remove' => false,
    ],

    'cascadeSelectChildren' => false,

    //'softDelete' => false,

    'iconEditSettings'=> [
    'show'      => 'list',
    'listData'  => [
    // 'folder' => 'Folder',
    'file' => 'File',
    'star' => 'Star',
    'bell' => 'Bell',
    // 'phone' => 'Phone',
    ]
],

'cacheSettings' => ['enableCache' => true],

'nodeAddlViews' => [
    Module::VIEW_PART_1 => '@app/views/mappings/_form',
    ],
]);
  • 这只是一个小开始,但是您可以更进一步。例如,假设用户尚未登录,或者您想以任何方式显示某些节点​​。在这些情况下,您可以使用switch case语句并检查例如在这种情况下是否未定义$ uid(未设置此名称,因为用户未登录),您可以要求用户登录或呈现或显示其他内容。树状视图:

    开关($ SomeVariable){ 情况“ case_to_check”: 回声TreeView :: widget([ ... 'query'=> TableName :: find()-> where([['user_id'=> $ uid])-> addOrderBy('root,lft'), ... 休息;
    情况“ another_case”: 回声TreeView :: widget([ ... 打破; 默认: 回声TreeView :: widget([ ...

==您还可以在index.php的顶部添加html select,如下所示:

<select name="Give_any_name_you_like" size=1 class="btn btn-primary" style="margin-bottom: 0.5em; margin-left: 0.5em; ">
<option value="0">Select Node</option>
<option value="1">mynodes</option>
<option value="2">othernodes</option>
<option value="3">allnodes</option>
</select>

然后使用Java脚本过滤和捕获选定的值,然后可以在切换情况下使用此vale显示某些节点​​。您可以将Java脚本代码放在<?php块内,并在切换大小写之前或回显TreeView :: widget([。Java脚本代码可能看起来像这样:

$this->registerJs("
$('select[name=" . "The_name_you_give_in_select" . "]').change(function(){     
var value = $(this).val();                    
switch(value) {
case '1':
window.location.href = \"your-page-name?what=mynodes\" ; 
break;
case '2':
window.location.href = \"your-page-name?what=othernodes\" ;
break;        
default:
window.location.href = \"your-page-name?what=allnodes\" ;
}   

});", View::POS_READY); 

===然后检查切换情况下的值,并用它来过滤要显示的树节点。类似于下面的Java脚本代码上方的代码:

/** @var integer $The_name_you_give_in_select */
// get value from selection menu.
// this is used to filter and show desired tree.
if (isset($_GET['what'])) {
$The_name_you_give_in_select = $_GET['what'];
} else {
$The_name_you_give_in_select = "defaultcase";
}     
// Then in switch case:     
switch ($The_name_you_give_in_select) {
case "mynodes":
echo TreeView::widget([
...
break;
Case "othernodes":
echo TreeView::widget([
...
break;
default:
echo TreeView::widget([
...

============== ===另外,您可能需要在views / your_table_name / _form.php中进行一些更改

  • 在_form.php中,您还可以控制显示哪些字段,哪些字段可编辑或只读等,诸如此类: == _form.php:

    ... / ** @var整数$ userid * /

      // save current node user id in var $userid
    
      // to be used to control form fields
    
      $userid = $node->user_id;
    
      ...
    
      if(isset($userid)){
      $username = Yii::$app->user->identity;
      }
    
      ...
    
      <div class="your-form">
      ...
      <?= $form->field($node, 'annotation')->textarea(['rows' => 6, 'readonly' => !(Yii::$app->user->identity->id == $userid or AdminController::isAdmin())]) ?>
    
      <?= $form->field($node, 'comments')->textarea(['rows' => 6, 'readonly' => !(Yii::$app->user->identity->id == $userid or AdminController::isAdmin())]) ?>
    
      <!--   <?/*= $form->field($username, 'username')->textInput(['maxlength' => true, 'readonly'=>true])->label('Created by User') */?>-->
    
      <?= $form->field($node, 'user_id')->textInput(['readonly'=>true]) ?>
    
      <?= $form->field($node, 'date_added')->textInput(['placeholder' => 'Date Added', 'readonly'=>true]) ?>
    
      </div>
    

========== === AdminContoler.php可能看起来像这样:

<?php
namespace app\controllers;
use Yii;
...
class AdminController extends Controller
{

/**
*
* manage admins.
* add admins here
* this will allow admins more control on all tables, but not accessing and managing users
* controlling, accessing and managing users is configured through:
* - config/web.php and views/layouts/main.php
*  - (1) in config/web.php go to modules -> user -> admins and add username(s)that you want to be admin accessing and managing users
*  - (2) THEN in view views/layouts/main.php, follow the same logic in line 62 and add username(s).
*
* @return bool
*/
public static function isAdmin()
{
if (
Yii::$app->user->identity->username == 'type user name here'
or
Yii::$app->user->identity->username == 'type user name here'

// add more here for example by uncommenting the following lines and typing username that you want to be admin

// or
// Yii::$app->user->identity->username == 'type user name here'

// or
// Yii::$app->user->identity->username == 'type user name here'

// or
// Yii::$app->user->identity->username == 'type user name here'
) {
return true;
} else {
return false;
}
}
}