Skip to content

Instantly share code, notes, and snippets.

@yus-ham
Last active August 4, 2017 01:42
Show Gist options
  • Save yus-ham/fef36a7e675689088a86c3541d7570ee to your computer and use it in GitHub Desktop.
Save yus-ham/fef36a7e675689088a86c3541d7570ee to your computer and use it in GitHub Desktop.
<?php //dist/views/tree/index.php
?>
<br>
<br>
<br>
<?=\app\ext\tree\TreeView::widget([
'query' => \app\ext\tree\Node::find()->addOrderBy('root, lft'),
'headingOptions' => ['label' => 'Categories'],
'rootOptions' => ['label'=>'<span class="text-primary">Root</span>'],
'fontAwesome' => false
, 'isAdmin' => true,
'displayValue' => 1,
// 'iconEditSettings'=> [
// 'show' => 'list',
// 'listData' => [
// 'folder' => 'Folder',
// 'file' => 'File',
// 'mobile' => 'Phone',
// 'bell' => 'Bell',
// ]
// ],
'softDelete' => true,
'cacheSettings' => ['enableCache' => FALSE]
]);
<?php //ext/tree/Node.php
namespace app\ext\tree;
use Yii;
class Node extends \kartik\tree\models\Tree
{
public static function tableName() {
return 'tbl_tree';
}
public function afterSave($isInsert, $changedAttributes) {
Yii::$app->session['tvScrollTop'] = Yii::$app->request->post('tvScrollTop');
parent::afterSave($isInsert, $changedAttributes);
}
}
//ext/tree/assets/tree.js
!(function(__tvId) {
var __tv = window[$('#' + __tvId).data('krajee-treeview')],
$tree = $('#' + __tv.treeId),
$detail = $('#' + __tv.detailId),
$btnCut = $('#' + __tv.toolbarId).find('.kv-cut');
__tv.alertFadeDuration = 2000
// cut button
$btnCut.on('click', function() {
this.disabled = true
$(this).data('clipNode', $('#' + __tvId).data('clipNode'))
// remove tooltip
this.nextSibling && this.nextSibling.remove()
showAlert('Select folder to paste')
})
$('#' + __tvId).on('treeview.beforeselect',
function(event, key, jqXHR, settings) {
this.dataset.clipNode = key
if ($btnCut.data('clipNode') > 0) {
move($btnCut.data('clipNode'), key)
$btnCut.data('clipNode', null)
}
})
$('#'+ __tvId).on('treeview.selected', function(event, key, jqXHR, settings) {
var $form = $('#' + __tvId + '-nodeform')
var scrollTop = $tree.scrollTop()
$form.prepend('<input name=tvScrollTop value='+ scrollTop +' type=hidden>')
$('#'+ __tv.detailId +' .alert').css('display', 'none').removeClass('hide')
})
function move(from, to) {
var $nodeFrom = $tree.find('li[data-key=' + from + ']'),
$nodeTo = $tree.find('li[data-key=' + to + ']'),
dir = 'any'
$.ajax({
type: 'post',
dataType: 'json',
data: {
'idFrom': $nodeFrom.data('key'),
'idTo': $nodeTo.data('key'),
'modelClass': 'app\\\\ext\\\\tree\\\\Node',
'dir': dir,
'allowNewRoots': 1,
'treeMoveHash': $('input[name=treeMoveHash]').val(),
'tvScrollTop': $tree.scrollTop()
},
url: $('#'+ __tvId).data('moveAction'),
beforeSend: function(jqXHR, settings) {
$tree.parent().addClass('kv-loading-search');
},
success: function(data, textStatus, jqXHR) {
if (data.status === 'success') {
if ($nodeTo.find('li').length > 0) {
$nodeTo.children('ul').append($nodeFrom);
} else {
$nodeTo.addClass('kv-parent');
$(document.createElement('ul')).appendTo($nodeTo).append($nodeFrom);
}
showAlert(data.out, 'success');
$tree.find('li.kv-collapsed').each(function() {
if ($(this).has($nodeFrom).length > 0) {
$(this).removeClass('kv-collapsed');
}
})
}
$tree.parent().removeClass('kv-loading-search');
},
error: function(jqXHR, textStatus, errorThrown) {
showAlert(errorThrown, 'danger');
$tree.parent().removeClass('kv-loading-search');
},
});
}
function showAlert(msg, type) {
('danger|warning|success'.indexOf(type) == -1) && (type = 'info')
var $alert = $detail.find('.alert-' + type)
$alert.append(msg).fadeIn('slow', function() {
setTimeout(function() {
$alert.fadeOut('slow')
}, __tv.alertFadeDuration)
})
}
})(document.querySelector('[data-krajee-treeview]').id)
<?php //controllers/TreeController.php
namespace app\controllers;
use Yii;
class TreeController extends \yii\web\Controller
{
public function actionIndex() {
return $this->render('index');
}
public function actionInput() {
return $this->render('_index');
}
public function actionMove() {
$dir = $idTo = $idFrom = $treeMoveHash = '';
extract(Yii::$app->request->post());
$nodeFrom = \app\ext\tree\Node::findOne($idFrom);
$nodeTo = \app\ext\tree\Node::findOne($idTo);
$nodeFrom->appendTo($nodeTo);
\Yii::$app->response->format = 'json';
return ['status' => 'success', 'out' => Yii::t('kvtree', 'The node was moved successfully.') ];
}
}
<?php //ext/tree/TreeView.php
namespace app\ext\tree;
use yii\helpers\Url;
use yii\helpers\Html;
use Yii;
class TreeView extends \kartik\tree\TreeView
{
public function getActions() {
return [
'move' => Url::toRoute('tree/move'),
];
}
public function init() {
parent::init();
$this->view->registerAssetBundle(TreeViewAsset::className());
$tvScrollTop = (int) Yii::$app->session['tvScrollTop'];
$this->view->registerJs("
jQuery('#{$this->id}-nodeform')
.prepend('<input name=tvScrollTop value=$tvScrollTop type=hidden>')
jQuery('#{$this->id}-tree').scrollTop($tvScrollTop)
jQuery('#{$this->id}').data('moveAction', '{$this->actions['move']}')
");
}
public function renderTree() {
$roots = Node::find()->roots()->all();
return Html::tag('div',
$this->renderRoot().
$this->renderNodes($roots, ['class' => 'kv-tree']),
$this->treeOptions);
}
public function renderNodes($nodes, $options = []) {
$items = [];
$structure = $this->_module->treeStructure + $this->_module->dataStructure;
extract($structure);
$nodeDepth = $currDepth = $counter = 0;
foreach ($nodes as $node) {
if (!$this->isAdmin && !$node->isVisible() || !$this->showInactive && !$node->isActive()) {
continue;
}
/** @noinspection PhpUndefinedVariableInspection */
$nodeDepth = $node->$depthAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeLeft = $node->$leftAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeRight = $node->$rightAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeKey = $node->$keyAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeName = $node->$nameAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeIcon = $node->$iconAttribute;
/** @noinspection PhpUndefinedVariableInspection */
$nodeIconType = $node->$iconTypeAttribute;
$indicators = '';
if (isset($this->nodeLabel)) {
$label = $this->nodeLabel;
$nodeName = is_callable($label) ? $label($node) :
(is_array($label) ? ArrayHelper::getValue($label, $nodeKey, $nodeName)
: $nodeName);
}
$nodeName = $node->id . ') '.$nodeName;
if (trim($indicators) == null) {
$indicators = '&nbsp;';
}
$nodeOptions = [
'data-key' => $nodeKey,
'data-lft' => $nodeLeft,
'data-rgt' => $nodeRight,
'data-lvl' => $nodeDepth,
'data-readonly' => static::parseBool($node->isReadonly()),
'data-movable-u' => static::parseBool($node->isMovable('u')),
'data-movable-d' => static::parseBool($node->isMovable('d')),
'data-movable-l' => static::parseBool($node->isMovable('l')),
'data-movable-r' => static::parseBool($node->isMovable('r')),
'data-removable' => static::parseBool($node->isRemovable()),
'data-removable-all' => static::parseBool($node->isRemovableAll()),
];
$children = $node->children(1)->all();
$css = [];
if (!empty($children)) {
$css[] = 'kv-parent';
}
if (!$node->isVisible() && $this->isAdmin) {
$css[] = 'kv-invisible';
}
if ($this->showCheckbox && $node->isSelected()) {
$css[] = 'kv-selected';
}
if ($node->isCollapsed()) {
$css[] = 'kv-collapsed';
}
if ($node->isDisabled()) {
$css[] = 'kv-disabled';
}
if (!$node->isActive()) {
$css[] = 'kv-inactive';
}
$indicators .= $this->renderToggleIconContainer(false) . "\n";
$indicators .= $this->showCheckbox ? $this->renderCheckboxIconContainer(false) . "\n" : '';
if (!empty($css)) {
Html::addCssClass($nodeOptions, $css);
}
$items[] = Html::tag('li',
"<div tabindex='-1' class='kv-tree-list'>\n".
" <div class='kv-node-indicators'>\n{$indicators}\n</div>\n".
" <div tabindex=-1 class=kv-node-detail>\n".
$this->renderNodeIcon($nodeIcon, $nodeIconType, empty($children)) . "\n".
" <span class='kv-node-label'>". $nodeName ."</span>".
" </div>\n".
"</div>\n".
(!empty($children) ? $this->renderNodes($children) : ''),
$nodeOptions);
}
return Html::tag('ul', implode('', $items), $options);
}
public function renderToolbar() {
$_toolbar = $this->toolbar;
$this->toolbar = array_slice($_toolbar, 0, 8, true);
$this->toolbar += [
'cut' => [
'icon' => 'move',
'options' => ['title' => Yii::t('app', 'Cut'), 'disabled' => true]
],
// 'paste' => [
// 'icon' => 'paste',
// 'options' => ['title' => Yii::t('app', 'Paste'), 'disabled' => true]
// ]
];
$this->toolbar += array_slice($_toolbar, -2, 3, true);
return parent::renderToolbar();
}
}
<?php //ext/tree/TreeViewAsset.php
namespace app\ext\tree;
class TreeViewAsset extends \yii\web\AssetBundle
{
public $sourcePath = __DIR__.'/assets';
public $js = ['tree.js'];
public $depends = ['kartik\tree\TreeViewAsset'];
public $publishOptions = ['forceCopy' => true];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment