Страница 1 из 1

Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.18, 20:14
Deyan
Здравствуйте!

Пробую установить виджет wbraganca/yii2-fancytree-widget в целях обучения.

Смысл, чтобы слева была форма меню и при нажатии в ветвях дерева справа в форме 'инфо' все отображалось.
Изображение
По порядку..

Для этого использую creocoder/yii2-nested-sets wbraganca/yii2-fancytree-widget (выводит js plagin c деревом) но у него дата передаётся в таком иерархическом виде.

Код: Выделить всё

$data = [
	['title' => 'Node 1', 'key' => 1],
	['title' => 'Folder 2', 'key' => '2', 'folder' => true, 'children' => [
		['title' => 'Node 2.1', 'key' => '3'],
		['title' => 'Node 2.2', 'key' => '4']
	]]
];
и поэтому подключаю wokster/yii2-nested-sets-tree-behavior (формирует нужный массив из нужных моделей)

В меню контроллер сделан экшен 'tree' и 'move'

MenuControoller

Код: Выделить всё

public function actionTree($id = 1)
    {
        return $this-> render ('tree', [
            'data' => Menu::findOne($id)->tree()
            ]);
    }

    public function actionMove ($item,$action,$second)

    {
        $item_model = Menu::findOne($item);
        $second_model = Menu::findOne($second);
        switch ($action){
            case 'after':
                $item_model->insertAfter($second_model);
                break;
            case 'before':
                $item_model->insertBefore($second_model);
                break;
            case 'over':
                $item_model->appendTo($second_model);
                break;
        }
        $item_model->save();
        return true;
    }
но вот с вьюшкой 'tree' трабл.. если сделать по рекомендации автора, то она выглядит так:

Tree.php

Код: Выделить всё

<?php
use yii\web\JsExpression;
use wbraganca\fancytree\FancytreeWidget;
use wokster\treebehavior\NestedSetsTreeBehavior;
/**

/* @var $this yii\web\View */
/* @var $data array */

$this->title = 'дерево категорий';
?>

<div class "">
 <div class = "row">
 	<div class = "col-xs-6 col-sm-6 col-md-6 col-lg-6">
	  <div class = "box box-primary">
		<dib class = "box-header with-border">
		 <h3 class ="box-title">дерево</h3>
	      <div class ="box-tools pull-right">
	<a href="<?=\yii\helpers\Url::toRoute('/menu/create')?>" class="btn btn-box-tool">
	<i class="fa fa-plus-square-o" aria-hidden="true"></i></a>
	<button type="button" class="btn btn-box-tool" data-wiget="collapse">
	<i class="fa fa-minus"></i></button>
</div>
</div><!--/.box-header -->
<div class="box-body">

 <?php
// Example of data.
	
 echo  
  \wbraganca\fancytree\FancytreeWidget::widget([
  'options' =>[
    'source' => $data,
    'extensions' => ['dnd'],
    'dnd' => [
      'preventVoidMoves' => true,
      'preventRecursiveMoves' => true,
      'autoExpandMS' => 400,
      
      'dragStart' => new JsExpression('function(node, data) {
        return true;
      }'),
      'dragEnter' => new JsExpression('function(node, data) {
        return true;
      }'),

        'dragDrop' => new JsExpression('function (node, data) {
$.get("/menu/move",(item: data.otherNode.key.substr(1), action: data.hitMode,
 second:node.key.substr(1)},function() {
  data.otherNode.moveTo(node, data.hitMode);
});
  }'), 
     ],
  'activate' => new JsExpression ('function(event,data) {
      var title = data.node.title;
      var id = data.node.key.substr(1);
      $("#cat-info .box-header>h3") .text(title);
      $.get("/menu/view-ajax",(id: id),function(data) {
        $("#cat-info" .box-body").html (data);
        });
       }'),
       
    ]
]);
?>

       </div>
      </div>
     </div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
	<div class="box box-primary" id="cat-info">
	  <div class="box-header with-border">
	   <h3 class="box-title">инфо</h3>
	     <div class="box-tools pull-right">
	      <button type="button" class="btn btn-box-tool" data-wiget="collapse">
	      <i class="fa fa-minus"></i>
	     </button>
	     </div>
	   </div>
	</div><!--/.box-header-->
	</div class="box-body">

        </div>
      </div>
    </div>
  </div>
</div>	

?>
В этом случае виджет просто не выводится:
Изображение


Если в таком, то дерево выводится с закомм. 'activate' только.
'Activate' относится к событиям виджета fancytree- т.е. когда кликается
элемент в ветке дерева и справа в форме должно выскакивать форма полностью. Но это не работает.
Вопрос: как подключить эту взаимосвязь?

Код: Выделить всё

echo  
  \wbraganca\fancytree\FancytreeWidget::widget([
  'options' =>[
    'source' => $data,
    'extensions' => ['dnd'],
    'dnd' => [
      'preventVoidMoves' => true,
      'preventRecursiveMoves' => true,
      'autoExpandMS' => 400,
      
      'dragStart' => new JsExpression('function(node, data) {
        return true;
      }'),
      'dragEnter' => new JsExpression('function(node, data) {
        return true;
      }'),
     'dragDrop' => new JsExpression('function(node, data) {
        $.get("move",{item: data.otherNode.data["id"], action: data.hitMode, 
        second: node.data["id"]},function(e ) {
          data.otherNode.moveTo(node, data.hitMode);
         console.log(e);
        });
  }'),
     ],
 /* 'activate' => new JsExpression ('function(event,data) {
      var title = data.node.title;
      var id = data.node.key.substr(1);
      $("#cat-info .box-header>h3") .text(title);
      $.get("/menu/view-ajax",(id: id),function(data) {
        $("#cat-info" .box-body").html (data);
        });
       }'),*/
    ]
]);
?>

C 'dragDrop' автор объясняет один нюанс-когда кто-то взял элемент в ветке и потащил,
делается ajax запрос и раньше, когда пользовался расширением у него
'data.otherNode.key' была просто цифра,но потом появилась цифра с нижним
подчёркиванием в ред., поэтому был добавлен substr(1) В его варианте 'activate'
он тоже присутствует. Но все это у меня не работает.

Код: Выделить всё

 'dragDrop' => new JsExpression('function (node, data) {
$.get("/menu/move",(item: data.otherNode.key.substr(1), 
action: data.hitMode, second:node.key.substr(1)},function() {
  data.otherNode.moveTo(node, data.hitMode);
});
  }'), 

Re: Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.19, 11:01
Nex-Otaku
Каша какая-то. В целях обучения, лучше бы сами всё написали с нуля, чем монструозные виджеты скрещивать. Полезнее было бы.

Re: Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.19, 23:04
Deyan
Если бы это было проще, то написал бы с нуля. У меня все работает, кроме связей с формой инфо. Расширение wokster/yii2-nested-sets-tree-behavior и так адаптировано с Yii2

Re: Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.20, 11:20
Nex-Otaku
Можно не стену текста, а конкретнее, что "не работает"?

1. Мне нужно A.
2. Я делаю B.
3. Ожидаю получить C.
4. Вместо этого, получаю D.

Re: Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.21, 20:07
Deyan
1. Мне нужно A.

У меня есть созданное меню admin.new.com/menu и есть созданная admin.new.com/menu/tree
Мне нужно, чтобы при клике в блоке меню слева (на картинке- форма sadsasaf) справа в блоке 'инфо' эта форма отображалось. И в меню можно было перемещать элементы.
http://joxi.ru/nAyKpY3UXBDPdm
http://joxi.ru/brRZgeOtQpDlMr
http://joxi.ru/4AkqLzwtM9Dwnm
Изображение



2. Я делаю B.

Есть activate, который относится к событиям самого виджета fancytree

Код: Выделить всё

'activate' => new JsExpression ('function(event,data) {
      var title = data.node.title;
      var id = data.node.key.substr(1);
      $("#cat-info .box-header>h3") .text(title);
      $.get("/menu/view-ajax",(id: id),function(data) {
        $("#cat-info" .box-body").html (data);
Это должно получаться за счёт того, что мы получили data.node.title и заранее подготовленной 2 вёрстки блока (инфо) у него есть h3 title-box. изначально там инфо, но мы туда загоняем title. Далее, отправляю get во view-ajax в MenuController:

Код: Выделить всё

 public function actionViewAjax($id)
    {
        return $this->renderAjax('_form',[
            'model'=> $this->findModel($id),
         ]);
    }
Туда отправляется id той модели, которой кликнули в меню. И когда ajax вернулся то, что получили из экшена поместилось в cat-info" .box-body (который изначально пустой) Поэтому он меняется.

tree.php

Код: Выделить всё

<?php
use yii\web\JsExpression;
use wbraganca\fancytree\FancytreeWidget;
use wokster\treebehavior\NestedSetsTreeBehavior;
/**

/* @var $this yii\web\View */
/* @var $data array */

$this->title = 'дерево категорий';
?>

<div class "">
 <div class = "row">
 	<div class = "col-xs-6 col-sm-6 col-md-6 col-lg-6">
	  <div class = "box box-primary">
		<dib class = "box-header with-border">
		 <h3 class ="box-title">дерево</h3>
	      <div class ="box-tools pull-right">
			<a href="<?=\yii\helpers\Url::toRoute('/menu/create')?>" class="btn btn-box-tool"><i class="fa fa-plus-square-o" aria-hidden="true"></i></a>
	<button type="button" class="btn btn-box-tool" data-wiget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div><!--/.box-header -->
<div class="box-body">

 <?php
// Example of data.

echo  
  \wbraganca\fancytree\FancytreeWidget::widget([
  'options' =>[
    'source' => $data,
    'extensions' => ['dnd'],
    'dnd' => [
      'preventVoidMoves' => true,
      'preventRecursiveMoves' => true,
      'autoExpandMS' => 400,
      
      'dragStart' => new JsExpression('function(node, data) {
        return true;
      }'),
      'dragEnter' => new JsExpression('function(node, data) {
        return true;
      }'),
     'dragDrop' => new JsExpression('function(node, data) {
        $.get("move",{item: data.otherNode.data["id"], action: data.hitMode, 
        second: node.data["id"]},function(e ) {
          data.otherNode.moveTo(node, data.hitMode);
         console.log(e);
        });
  }'),
     ],
 /* 'activate' => new JsExpression ('function(event,data) {
      var title = data.node.title;
      var id = data.node.key.substr(1);
      $("#cat-info .box-header>h3") .text(title);
      $.get("/menu/view-ajax",(id: id),function(data) {
        $("#cat-info" .box-body").html (data);
        });
       }'),*/
    ]
]);
?>

 

       </div>
      </div>
     </div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
	<div class="box box-primary" id="cat-info">
	  <div class="box-header with-border">
	   <h3 class="box-title">инфо</h3>
	     <div class="box-tools pull-right">
	      <button type="button" class="btn btn-box-tool" data-wiget="collapse"><i class="fa fa-minus"></i>
	     </button>
	     </div>
	   </div>
	</div><!--/.box-header-->
	</div class="box-body">

        </div>
      </div>
    </div>
  </div>
</div>	

?>


3. Ожидаю получить C.
Меняющуюся форму при клике
http://joxi.ru/BA0oQ6eSBaYDz2

4. Вместо этого, получаю D.

С кодом 'activate' виджет не отображается и не кликается.

https://i.stack.imgur.com/UyAL6.jpg

Если его заком. то виджет появляется. Но с другим блоком 'инфо' не работает.
http://joxi.ru/V2VO65ki04R7gA

Подозреваю, что что-то с data.node.key.substr(1); и
'dragDrop' т.к. в изначальном варианте там было:

Код: Выделить всё

 'dragDrop' => new JsExpression('function (node, data) {
$.get("/menu/move",(item: data.otherNode.key.substr(1), action: data.hitMode,
 second:node.key.substr(1)},function() {
  data.otherNode.moveTo(node, data.hitMode);
});

Re: Проблема с Nested sets с drag&drop..и как подключить 'activate' в FancytreeWidget?

Добавлено: 2018.01.21, 21:37
Deyan
В документации описано так:
Event Handling
Functionality can be added (and modified) by defining event handlers (i.e. callback functions).
Every event handler is passed a data argument, that contains information about the event target.

Код: Выделить всё

  $("#tree").fancytree({
    ...
    activate: function(event, data){
      // A node was activated: display its title:
      var node = data.node;
      $("#echoActive").text(node.title)
    },
    beforeSelect: function(event, data){
      // A node is about to be selected: prevent this, for folder-nodes:
      if( data.node.isFolder() ){
        return false;
      }
    }
  });
An alternative way to define event handlers is to bind them later to an initialized tree. Note that the event name must be converted to lower case and prefixed with 'fancytree':

Код: Выделить всё

 $("#tree").on("fancytreebeforeselect", function(event, data){
    if( data.node.isFolder() ){
      return false;
    }
  });
https://github.com/mar10/fancytree/wiki