From c7896b56c637e505cf92be0dc72cef174525e306 Mon Sep 17 00:00:00 2001 From: Kartik Visweswaran Date: Sat, 5 Mar 2022 01:32:38 +0530 Subject: [PATCH] Updates to release v1.1.3 --- .gitattributes | 3 - CHANGE.md | 6 +- LICENSE.md | 2 +- README.md | 12 +- composer.json | 77 ++++----- src/Module.php | 43 +++-- src/TreeSecurity.php | 5 +- src/TreeView.php | 143 +++++++++------- src/TreeViewAsset.php | 4 +- src/TreeViewInput.php | 65 ++++++-- src/TreeViewInputAsset.php | 4 +- src/assets/css/kv-tree-input.css | 4 +- src/assets/css/kv-tree-input.min.css | 4 +- src/assets/css/kv-tree.css | 36 ++-- src/assets/css/kv-tree.min.css | 6 +- src/assets/js/kv-tree-input.js | 4 +- src/assets/js/kv-tree-input.min.js | 4 +- src/assets/js/kv-tree.js | 4 +- src/assets/js/kv-tree.min.js | 4 +- src/controllers/NodeController.php | 11 +- src/migrations/m230416_200116_tree.php | 2 +- src/migrations/tree.sql | 2 +- src/models/Tree.php | 98 +++++++---- src/models/TreeQuery.php | 4 +- src/models/TreeTrait.php | 221 ++++++++++++++++++++++--- src/views/_form.php | 8 +- 26 files changed, 526 insertions(+), 250 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1064e8f..0000000 --- a/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -/.github export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore \ No newline at end of file diff --git a/CHANGE.md b/CHANGE.md index 7384a9c..ff7e2a3 100755 --- a/CHANGE.md +++ b/CHANGE.md @@ -3,8 +3,10 @@ Change Log: `yii2-tree-manager` ## Version 1.1.3 -**Date:** _under development_ +**Date:** 04-Mar-2022 +- Enhancements for Bootstrap 5.x support. +- PHP 8.1 enhancements for native functions. - (bug #259): Correct icons list display based on `iconEditSettings['show']`. - (enh #258): Enhanced BS4 custom checkbox and radio styling for toggle inputs. - (enh #257): Enhance search close icon styling. @@ -16,7 +18,7 @@ Change Log: `yii2-tree-manager` ## Version 1.1.2 -**Date:** 13-Mar-2019 +**Date:** 13-Mar-2021 - (enh #244): Correct hidden css to use `BS_HIDE` within `bsCssMap`. - (enh #240): Rename events triggered via jquery to start with `treeview:`. diff --git a/LICENSE.md b/LICENSE.md index d7d7c2c..fad0173 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2019, Kartik Visweswaran +Copyright (c) 2015 - 2022, Kartik Visweswaran Krajee.com All rights reserved. diff --git a/README.md b/README.md index 8f1e1f1..5cc0599 100755 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@
yii2-tree-manager
+

- Donate - + title="Donate via Paypal" target="_blank">Donate +       + kartikv +

[![Stable Version](https://poser.pugx.org/kartik-v/yii2-tree-manager/v/stable)](https://packagist.org/packages/kartik-v/yii2-tree-manager) @@ -58,7 +60,7 @@ The following important PHP classes are available with this module: 6. **kartik\tree\controllers\NodeController:** _Controller_, the controller actions that manages the editing of each node for create, update, delete, or reorder (move). ## Demo -You can see detailed [documentation](http://demos.krajee.com/tree-manager) and [TreeView demonstration](http://demos.krajee.com/tree-manager-demo/treeview) or [TreeViewInput demonstration](http://demos.krajee.com/tree-manager-demo/tree-view-input) on usage of the extension. +You can see detailed [documentation](http://demos.krajee.com/tree-manager), [API Code Documentation](https://docs.krajee.com/kartik-tree-treeview) and [TreeView demonstration](http://demos.krajee.com/tree-manager-demo/treeview) or [TreeViewInput demonstration](http://demos.krajee.com/tree-manager-demo/tree-view-input) on usage of the extension. ## Installation @@ -132,7 +134,7 @@ use Yii; class Tree extends \yii\db\ActiveRecord { - use kartik\tree\models\TreeTrait. + use kartik\tree\models\TreeTrait; /** * @inheritdoc diff --git a/composer.json b/composer.json index 2667c50..b682267 100755 --- a/composer.json +++ b/composer.json @@ -1,41 +1,42 @@ { - "name": "kartik-v/yii2-tree-manager", - "description": "An enhanced tree management module with tree node selection and manipulation using nested sets.", - "keywords": [ - "bootstrap", - "tree", - "treeview", - "krajee", - "hierarchy", - "nested", - "set", - "nestedset", - "ajax", - "jquery" - ], - "homepage": "https://github.com/kartik-v/yii2-tree-manager", - "type": "yii2-extension", - "license": "BSD-3-Clause", - "authors": [ - { - "name": "Kartik Visweswaran", - "email": "kartikv2@gmail.com", - "homepage": "http://www.krajee.com/" - } - ], - "require": { - "kartik-v/yii2-widget-activeform": ">=1.5.7", - "creocoder/yii2-nested-sets": ">=0.9", - "kartik-v/yii2-dialog": ">=1.0" - }, - "autoload": { - "psr-4": { - "kartik\\tree\\": "src" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } + "name": "kartik-v/yii2-tree-manager", + "description": "An enhanced tree management module with tree node selection and manipulation using nested sets.", + "keywords": [ + "bootstrap", + "tree", + "treeview", + "krajee", + "hierarchy", + "nested", + "set", + "nestedset", + "ajax", + "jquery" + ], + "homepage": "https://github.com/kartik-v/yii2-tree-manager", + "type": "yii2-extension", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Kartik Visweswaran", + "email": "kartikv2@gmail.com", + "homepage": "http://www.krajee.com/" } + ], + "require": { + "kartik-v/yii2-krajee-base": ">=3.0.4", + "kartik-v/yii2-widget-activeform": ">=1.6.2", + "creocoder/yii2-nested-sets": ">=0.9", + "kartik-v/yii2-dialog": ">=1.0" + }, + "autoload": { + "psr-4": { + "kartik\\tree\\": "src" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + } } \ No newline at end of file diff --git a/src/Module.php b/src/Module.php index f669ca8..ea82ebe 100644 --- a/src/Module.php +++ b/src/Module.php @@ -1,67 +1,81 @@ [ + * 'treemanager' => [ + * 'class' => '\kartik\tree\Module', + * // other module settings, refer detailed documentation + * ] + * ] + * ``` * @author Kartik Visweswaran * @since 1.0 */ class Module extends \kartik\base\Module { /** - * The module name for Krajee treeview + * @var string module name for the Krajee Tree management module */ const MODULE = 'treemanager'; /** - * Manage node action + * @var string manage node action */ const NODE_MANAGE = 'manage'; /** - * Remove node action + * @var string remove node action */ const NODE_REMOVE = 'remove'; /** - * Move node action + * @var string move node action */ const NODE_MOVE = 'move'; /** - * Save node action + * @var string save node action */ const NODE_SAVE = 'save'; /** - * Tree details form view - Section Part 1 + * @var int section part 1 of the tree details form view */ const VIEW_PART_1 = 1; /** - * Tree details form view - Section Part 2 + * @var int section part 2 of the tree details form view */ const VIEW_PART_2 = 2; /** - * Tree details form view - Section Part 3 + * @var int section part 3 of the tree details form view */ const VIEW_PART_3 = 3; /** - * Tree details form view - Section Part 4 + * @var int section part 4 of the tree details form view */ const VIEW_PART_4 = 4; /** - * Tree details form view - Section Part 5 + * @var int section part 5 of the tree details form view */ const VIEW_PART_5 = 5; /** - * @var array the configuration of nested set attributes structure + * @var array the configuration of nested set attributes structure. */ public $treeStructure = []; @@ -124,8 +138,7 @@ public function init() 'iconTypeAttribute' => 'icon_type' ]; $nodeActions = ArrayHelper::getValue($this->treeViewSettings, 'nodeActions', []); - // prepends Error in Console Applications - if (\Yii::$app instanceof \yii\web\Application) { + if (Yii::$app instanceof WebApplication) { $nodeActions += [ self::NODE_MANAGE => Url::to(['/treemanager/node/manage']), self::NODE_SAVE => Url::to(['/treemanager/node/save']), diff --git a/src/TreeSecurity.php b/src/TreeSecurity.php index 0f2b0cd..e079bcd 100644 --- a/src/TreeSecurity.php +++ b/src/TreeSecurity.php @@ -1,7 +1,7 @@ * @since 1.0 diff --git a/src/TreeView.php b/src/TreeView.php index 1c1f308..6e872b2 100644 --- a/src/TreeView.php +++ b/src/TreeView.php @@ -1,7 +1,7 @@ Tree::find()->addOrderBy('root, lft'), + * 'headingOptions' => ['label' => 'Categories'], + * 'isAdmin' => false, // optional (toggle to enable admin mode) + * 'displayValue' => 1, // initial display value + * //'softDelete' => true, // normally not needed to change + * //'cacheSettings' => ['enableCache' => true] // normally not needed to change + * ]); + * ``` + * + * @see https://github.com/creocoder/yii2-nested-sets * * @author Kartik Visweswaran - * @since 1.0 */ class TreeView extends Widget { @@ -261,6 +280,7 @@ class TreeView extends Widget /** * @var boolean whether to use font awesome icons. Defaults to `false`. + * @deprecated since v1.1.3 (for Bootstrap 4.x and above this will always be true) */ public $fontAwesome = false; @@ -359,41 +379,36 @@ class TreeView extends Widget /** * @var string the icon markup for the opened parent node if no icon was setup in the database. If not set will * default to: - * - `` if [[bsVersion]] is `4.x`. - * - `` if [[fontAwesome]] is `true` and [[bsVersion]] is `3.x`. - * - `` if [[fontAwesome]] is `false` and [[bsVersion]] is `3.x`. + * - `` if [[bsVersion]] is not `3.x` or [[fontAwesome]] is `true`. + * - `` if [[bsVersion]] is `3.x` and [[fontAwesome]] is `false` . */ public $defaultParentNodeOpenIcon; /** * @var string the default icon for expanding the node. If not set will default to: - * - `` if [[bsVersion]] is `4.x`. - * - `` if [[fontAwesome]] is `true` and [[bsVersion]] is `3.x`. - * - `` if [[fontAwesome]] is `false` and [[bsVersion]] is `3.x`. + * - `` if [[bsVersion]] is not `3.x` or [[fontAwesome]] is `true`. + * - `` if [[bsVersion]] is `3.x` and [[fontAwesome]] is `false` . */ public $defaultExpandNodeIcon; /** * @var string the default icon for collapsing the node. If not set will default to: - * - `` if [[bsVersion]] is `4.x`. - * - `` if [[fontAwesome]] is `true` and [[bsVersion]] is `3.x`. - * - `` if [[fontAwesome]] is `false` and [[bsVersion]] is `3.x`. + * - `` if [[bsVersion]] is not `3.x` or [[fontAwesome]] is `true`. + * - `` if [[bsVersion]] is `3.x` and [[fontAwesome]] is `false` . */ public $defaultCollapseNodeIcon; /** * @var array default icon for a checked node which will represent a checked checkbox. If not set will default to: - * - `` if [[bsVersion]] is `4.x`. - * - `` if [[fontAwesome]] is `true` and [[bsVersion]] is `3.x`. - * - `` if [[fontAwesome]] is `false` and [[bsVersion]] is `3.x`. + * - `` if [[bsVersion]] is not `3.x` or [[fontAwesome]] is `true`. + * - `` if [[bsVersion]] is `3.x` and [[fontAwesome]] is `false` . */ public $defaultCheckedNodeIcon; /** * @var string the HTML attributes for an unchecked node which will represent an unchecked checkbox. If not set will default to: - * - `` if [[bsVersion]] is `4.x`. - * - `` if [[fontAwesome]] is `true` and [[bsVersion]] is `3.x`. - * - `` if [[fontAwesome]] is `false` and [[bsVersion]] is `3.x`. + * - `` if [[bsVersion]] is not `3.x` or [[fontAwesome]] is `true`. + * - `` if [[bsVersion]] is `3.x` and [[fontAwesome]] is `false` . */ public $defaultUncheckedNodeIcon; @@ -473,7 +488,7 @@ class TreeView extends Widget /** * @var array the HTML attributes for the indicator which will represent a checked checkbox. The following special * options are recognized: - * - `label`: _string_, the label for the indicator. If not set will default to [[defaultCheckNodeIcon]]. + * - `label`: _string_, the label for the indicator. If not set will default to [[defaultCheckedNodeIcon]]. */ public $checkedNodeOptions = []; @@ -506,7 +521,7 @@ class TreeView extends Widget /** * @var array the HTML attributes for the search container */ - public $searchContainerOptions = ['class' => 'kv-search-sm']; + public $searchContainerOptions = []; /** * @var array the HTML attributes for the search input @@ -516,7 +531,7 @@ class TreeView extends Widget /** * @var array the HTML attributes for the search clear indicator */ - public $searchClearOptions = ['class' => 'close']; + public $searchClearOptions = []; /** * @var boolean whether to hide unmatched search items when searching @@ -636,17 +651,17 @@ class TreeView extends Widget protected $_nodeSelected = null; /** - * @var array configuration of icons for BS3, BS4, and FA. The 4th array value is optional and includes any + * @var array configuration of icons for Glyphicons and Font Awesome. The 3rd array value is optional and includes any * additional css class to be added. */ protected static $_nodeIcons = [ - 'defaultExpandNodeIcon' => ['expand', 'plus-square', 'plus-square-o'], - 'defaultCollapseNodeIcon' => ['collapse', 'minus-square', 'minus-square-o'], - 'defaultCheckedNodeIcon' => ['checked', 'check-square', 'check-square-o'], - 'defaultUncheckedNodeIcon' => ['unchecked', 'square', 'square-o'], - 'defaultChildNodeIcon' => ['file', 'file', 'file'], - 'defaultParentNodeIcon' => ['folder', 'folder', 'folder-close', 'kv-node-closed'], - 'defaultParentNodeOpenIcon' => ['folder-open', 'folder-open', 'folder-open', 'kv-node-opened'], + 'defaultExpandNodeIcon' => ['glyphicon glyphicon-expand', 'far fa-plus-square'], + 'defaultCollapseNodeIcon' => ['glyphicon glyphicon-collapse', 'far fa-minus-square'], + 'defaultCheckedNodeIcon' => ['glyphicon glyphicon-checked', 'far fa-check-square'], + 'defaultUncheckedNodeIcon' => ['glyphicon glyphicon-unchecked', 'far fa-square'], + 'defaultChildNodeIcon' => ['glyphicon glyphicon-file', 'fas fa-file'], + 'defaultParentNodeIcon' => ['glyphicon glyphicon-folder', 'fas fa-folder', 'kv-node-closed'], + 'defaultParentNodeOpenIcon' => ['glyphicon glyphicon-folder-open', 'fas fa-folder-open', 'kv-node-opened'], ]; /** @@ -667,23 +682,19 @@ public static function module() /** * Initialize icons - * @throws InvalidConfigException + * + * @throws InvalidConfigException|Exception */ protected function initIcons() { - $isBs4 = $this->isBs4(); - $prefix = $this->getDefaultIconPrefix(); + $notBs3 = !$this->isBs(3); foreach (static::$_nodeIcons as $prop => $setting) { if (!isset($this->$prop)) { - $icon = $isBs4 ? $setting[1] : ($this->fontAwesome ? $setting[2] : $setting[0]); - $pre = $this->fontAwesome && !$isBs4 ? 'fa fa-' : $prefix; - if ($isBs4 && substr($setting[2], -2) === '-o') { - $pre = 'far fa-'; + $icon = $notBs3 || $this->fontAwesome ? $setting[1] : $setting[0]; + if (isset($setting[2])) { + $icon .= ' ' . $setting[2]; } - if (isset($setting[3])) { - $icon .= ' ' . $setting[3]; - } - $this->$prop = Html::tag('i', '', ['class' => $pre . $icon]); + $this->$prop = Html::tag('i', '', ['class' => $icon]); } } } @@ -752,7 +763,7 @@ protected static function usesTrait($class, $trait, $autoload = false) return true; } $traitsToSearch = array_merge($newTraits, $traitsToSearch); - }; + } foreach ($traits as $t => $str) { $traits = array_merge(class_uses($t, $autoload), $traits); if (in_array($trait, $traits)) { @@ -776,7 +787,7 @@ protected static function parseBool($var) /** * @inheritdoc - * @throws \Exception + * @throws Exception */ public function init() { @@ -801,7 +812,7 @@ public function run() */ public function initOptions() { - $isBs4 = $this->isBs4(); + $notBs3 = !$this->isBs(3); $this->_iconsListShow = ArrayHelper::getValue($this->iconEditSettings, 'show', 'text'); if (!$this->_module->treeStructure['treeAttribute']) { $this->allowNewRoots = false; @@ -812,7 +823,7 @@ public function initOptions() $this->initIcons(); $this->_nodes = $this->query->all(); if (!isset($this->iconPrefix)) { - $this->iconPrefix = $this->isBs4() ? 'fas fa-' : ($this->fontAwesome ? 'fa fa-' : 'glyphicon glyphicon-'); + $this->iconPrefix = !$this->isBs(3) ? 'fas fa-' : ($this->fontAwesome ? 'fa fa-' : 'glyphicon glyphicon-'); } $this->_nodeSelected = $this->options['id'] . '-nodesel'; $this->initSelectedNode(); @@ -824,7 +835,7 @@ public function initOptions() if (empty($this->options['class'])) { $this->options['class'] = 'form-control ' . $this->hideCssClass ; } - Html::addCssClass($this->treeWrapperOptions, 'kv-tree-wrapper'); + Html::addCssClass($this->treeWrapperOptions, ['kv-tree-wrapper', 'tree-bs' . $this->getBsVer()]); Html::addCssClass($this->headerOptions, 'kv-header-container'); Html::addCssClass($this->headingOptions, 'kv-heading-container'); Html::addCssClass($this->toolbarOptions, 'kv-toolbar-container'); @@ -917,7 +928,7 @@ public function initOptions() ], self::BTN_SEPARATOR, self::BTN_REFRESH => [ - 'icon' => $isBs4 ? 'sync-alt' : 'refresh', + 'icon' => $notBs3 ? 'sync-alt' : 'refresh', 'options' => ['title' => Yii::t('kvtree', 'Refresh')], 'url' => Yii::$app->request->url, ], @@ -938,13 +949,13 @@ public function initOptions() */ public function renderWidget() { - $content = strtr( + $content = Lib::strtr( $this->mainTemplate, [ '{wrapper}' => $this->renderWrapper(), '{detail}' => $this->renderDetail(), ] ); - return strtr( + return Lib::strtr( $content, [ '{heading}' => $this->renderHeading(), '{search}' => $this->renderSearch(), @@ -958,10 +969,11 @@ public function renderWidget() * Renders the tree wrapper container * * @return string + * @throws Exception */ public function renderWrapper() { - $content = strtr( + $content = Lib::strtr( $this->wrapperTemplate, [ '{header}' => $this->renderHeader(), '{tree}' => $this->renderTree(), @@ -975,6 +987,7 @@ public function renderWrapper() * Renders the markup for the button actions toolbar * * @return string + * @throws Exception */ public function renderToolbar() { @@ -1084,6 +1097,7 @@ public function renderHeading() * Renders the markup for the tree hierarchy - uses a fast non-recursive mode of tree traversal. * * @return string + * @throws Exception */ public function renderTree() { @@ -1129,10 +1143,10 @@ public function renderTree() $out .= Html::beginTag('ul') . "\n"; $currDepth = $currDepth + ($nodeDepth - $currDepth); } elseif ($nodeDepth < $currDepth) { - $out .= str_repeat("\n", $currDepth - $nodeDepth) . "\n"; + $out .= Lib::str_repeat("\n", $currDepth - $nodeDepth) . "\n"; $currDepth = $currDepth - ($currDepth - $nodeDepth); } - if (trim($indicators) == null) { + if (Lib::trim($indicators) == null) { $indicators = ' '; } $nodeOptions = [ @@ -1170,8 +1184,8 @@ public function renderTree() if (!$node->isActive()) { $css[] = 'kv-inactive '; } - $indicators .= $this->renderToggleIconContainer(false) . "\n"; - $indicators .= $this->showCheckbox ? $this->renderCheckboxIconContainer(false) . "\n" : ''; + $indicators .= $this->renderToggleIconContainer() . "\n"; + $indicators .= $this->showCheckbox ? $this->renderCheckboxIconContainer() . "\n" : ''; if (!empty($css)) { Html::addCssClass($nodeOptions, $css); } @@ -1187,7 +1201,7 @@ public function renderTree() '' . "\n"; ++$counter; } - $out .= str_repeat("\n", $nodeDepth) . "\n"; + $out .= Lib::str_repeat("\n", $nodeDepth) . "\n"; $out .= "\n"; if (!$this->hideTopRoot && !$this->topRootAsHeading) { $out = $this->renderRoot() . $out; @@ -1262,7 +1276,7 @@ public function renderDetail() /** * Registers the client assets for the widget - * @throws \Exception + * @throws Exception */ public function registerAssets() { @@ -1333,7 +1347,7 @@ protected function initTreeView() $this->bsVersion = $this->_module->bsVersion; } $this->initBsVersion(); - $isBs4 = $this->isBs4(); + $notBs3 = !$this->isBs(3); $prefix = $this->getDefaultIconPrefix(); $defaultBtnCss = $this->getDefaultBtnCss(); if (empty($this->emptyNodeMsg)) { @@ -1346,11 +1360,11 @@ protected function initTreeView() if (!isset($this->nodeViewButtonLabels['submit'])) { $this->nodeViewButtonLabels['submit'] = Html::tag('i', '', - ['class' => $prefix . ($isBs4 ? 'save' : 'floppy-disk')]); + ['class' => $prefix . ($notBs3 ? 'save' : 'floppy-disk')]); } if (!isset($this->nodeViewButtonLabels['reset'])) { $this->nodeViewButtonLabels['reset'] = Html::tag('i', '', - ['class' => $prefix . ($isBs4 ? 'redo' : 'repeat')]); + ['class' => $prefix . ($notBs3 ? 'redo' : 'repeat')]); } if (!isset($this->buttonOptions['class'])) { $this->buttonOptions['class'] = 'btn ' . $defaultBtnCss; @@ -1375,8 +1389,8 @@ protected function initSelectedNode() return; } $session = Yii::$app->session; - $id = $this->_nodeSelected ? $this->_nodeSelected : 'kvNodeId'; - $key = $session->get($id, null); + $id = isset($this->_nodeSelected) ? $this->_nodeSelected : 'kvNodeId'; + $key = $session->get($id); if ($key) { $this->displayValue = $key; } @@ -1428,7 +1442,7 @@ protected function sortToolbar() } /** - * Render the default node icon markup + * Render the default node icon markup. * * @param string $icon the current node's icon * @param integer $iconType the current node's icon type, must be one of: @@ -1475,7 +1489,7 @@ protected function renderToggleIcon($action = 'collapse') */ protected function renderToggleIconContainer($root = false) { - $content = $this->renderToggleIcon('expand') . $this->renderToggleIcon('collapse'); + $content = $this->renderToggleIcon('expand') . $this->renderToggleIcon(); $options = $root ? $this->rootNodeToggleOptions : $this->nodeToggleOptions; return Html::tag('span', $content, $options); } @@ -1505,7 +1519,7 @@ protected function renderCheckboxIcon($checked = false) */ protected function renderCheckboxIconContainer($root = false) { - $content = $this->renderCheckboxIcon(true) . $this->renderCheckboxIcon(false); + $content = $this->renderCheckboxIcon(true) . $this->renderCheckboxIcon(); $options = $root ? $this->rootNodeCheckboxOptions : $this->nodeCheckboxOptions; return Html::tag('span', $content, $options); } @@ -1528,6 +1542,7 @@ protected function renderIcon($icon, $options = []) * Renders the markup for the detail form to edit/view the selected tree node * * @return null|array + * @throws Exception */ protected function getIconsList() { diff --git a/src/TreeViewAsset.php b/src/TreeViewAsset.php index febdca0..bcc6b1b 100644 --- a/src/TreeViewAsset.php +++ b/src/TreeViewAsset.php @@ -1,7 +1,7 @@ * @since 1.0 diff --git a/src/TreeViewInput.php b/src/TreeViewInput.php index ddacb1d..db15d78 100644 --- a/src/TreeViewInput.php +++ b/src/TreeViewInput.php @@ -1,13 +1,16 @@ Tree::find()->addOrderBy('root, lft'), + * 'headingOptions' => ['label' => 'Categories'], + * 'name' => 'kv-product', // input name + * 'value' => '1,2,3', // values selected (comma separated for multiple select) + * 'asDropdown' => true, // will render the tree input widget as a dropdown. + * 'multiple' => true, // set to false if you do not need multiple selection + * 'fontAwesome' => true, // render font awesome icons + * 'rootOptions' => [ + * 'label' => '', + * 'class' => 'text-success' + * ], // custom root label + * //'options' => ['disabled' => true], + * ]); + * ``` * * @author Kartik Visweswaran * @since 1.0 @@ -25,7 +50,7 @@ class TreeViewInput extends TreeView { /** - * @var Model the data model that this widget is associated with. + * @var Tree|Model the tree data model that this widget is associated with. */ public $model; @@ -98,11 +123,11 @@ protected function initTreeView() } $this->showCheckbox = true; $css = 'kv-tree-input-widget'; - if ($this->isBs4()) { - $carets = '' . + if (!$this->isBs(3)) { + $carets = ''. ''; } else { - $carets = '' . + $carets = ''. ''; } $this->_defaultCaret = Html::tag('div', $carets, ['class' => 'kv-carets']); @@ -146,18 +171,19 @@ protected function initDropdown() Html::addCssClass($input, $css); Html::addCssClass($dropdown, ['dropdown-menu', 'kv-tree-dropdown']); Html::addCssClass($options, ['dropdown', 'kv-tree-dropdown-container']); - $id = $this->options['id'] . '-tree-input'; + $id = $this->options['id'].'-tree-input'; $this->_placeholder = ArrayHelper::remove($input, 'placeholder', Yii::t('kvtree', 'Select...')); $this->_placeholder = Html::tag('span', $this->_placeholder, ['class' => 'kv-placeholder']); $config['dropdown'] = array_replace_recursive([ - 'id' => $id . '-menu', + 'id' => $id.'-menu', 'role' => 'menu', 'aria-labelledby' => $id, ], $dropdown); + $dataToggle = 'data-' . ($this->isBs(5) ? 'bs-' : '') . 'toggle'; $config['input'] = array_replace_recursive([ 'id' => $id, 'tabindex' => -1, - 'data-toggle' => 'dropdown', + $dataToggle => 'dropdown', 'aria-haspopup' => 'true', 'aria-expanded' => 'false', ], $input); @@ -174,33 +200,35 @@ protected function initDropdown() public function renderWidget() { if (!$this->showToolbar) { - $this->wrapperTemplate = strtr($this->wrapperTemplate, ['{footer}' => '']); + $this->wrapperTemplate = Lib::strtr($this->wrapperTemplate, ['{footer}' => '']); } - $content = strtr($this->renderWrapper(), [ + $content = Lib::strtr($this->renderWrapper(), [ '{heading}' => $this->renderHeading(), '{search}' => $this->renderSearch(), '{toolbar}' => $this->renderToolbar(), - ]) . "\n" . + ])."\n". $this->getInput(); if ($this->asDropdown) { return $this->renderDropdown($content); } + return $content; } /** * Generates the dropdown tree menu * - * @param string $content the content to be embedded in the dropdown menu + * @param string $content the content to be embedded in the dropdown menu * * @return string */ protected function renderDropdown($content) { $config = $this->dropdownConfig; - $input = Html::tag('div', $config['caret'] . $this->_placeholder, $config['input']); + $input = Html::tag('div', $config['caret'].$this->_placeholder, $config['input']); $dropdown = Html::tag('div', $content, $config['dropdown']); - return Html::tag('div', $input . $dropdown, $config['options']); + + return Html::tag('div', $input.$dropdown, $config['options']); } /** @@ -213,6 +241,7 @@ public function getInput() if ($this->hasModel()) { return Html::activeHiddenInput($this->model, $this->attribute, $this->options); } + return Html::hiddenInput($this->name, $this->value, $this->options); } @@ -220,6 +249,7 @@ public function getInput() * Renders the markup for the button actions toolbar * * @return string + * @throws Exception */ public function renderToolbar() { @@ -227,6 +257,7 @@ public function renderToolbar() return ''; } unset($this->toolbar[self::BTN_CREATE], $this->toolbar[self::BTN_CREATE_ROOT], $this->toolbar[self::BTN_REMOVE]); + return parent::renderToolbar(); } @@ -259,8 +290,8 @@ public function registerInputAssets() 'caret' => $this->dropdownConfig['caret'], 'autoCloseOnSelect' => $this->autoCloseOnSelect, ]); - $var = $name . '_' . hash('crc32', $opts); - $this->options['data-krajee-' . $name] = $var; + $var = $name.'_'.hash('crc32', $opts); + $this->options['data-krajee-'.$name] = $var; $view->registerJs("var {$var}={$opts};", View::POS_HEAD); $view->registerJs("jQuery('#{$id}').{$name}({$var});"); } diff --git a/src/TreeViewInputAsset.php b/src/TreeViewInputAsset.php index 0269a57..cb08dce 100644 --- a/src/TreeViewInputAsset.php +++ b/src/TreeViewInputAsset.php @@ -1,7 +1,7 @@ * @since 1.0 diff --git a/src/assets/css/kv-tree-input.css b/src/assets/css/kv-tree-input.css index 126bd95..01c6b62 100644 --- a/src/assets/css/kv-tree-input.css +++ b/src/assets/css/kv-tree-input.css @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Input Widget Style Sheet * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ diff --git a/src/assets/css/kv-tree-input.min.css b/src/assets/css/kv-tree-input.min.css index 8e34b60..f258f6d 100644 --- a/src/assets/css/kv-tree-input.min.css +++ b/src/assets/css/kv-tree-input.min.css @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Input Widget Style Sheet * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */.kv-single-select .kv-node-checkbox,.kv-single-select .kv-root-node-checkbox,.kv-tree-dropdown-container .kv-up,.kv-tree-dropdown-container.open .kv-dn,.kv-tree-dropdown-container.show .kv-dn{display:none}.kv-tree-input-widget .kv-focussed{background-color:#fff}.kv-tree-dropdown-container{cursor:pointer}.kv-tree-input-widget .kv-disabled>.kv-tree-list .kv-node-checkbox,.kv-tree-input-widget .kv-disabled>.kv-tree-list .kv-node-detail,.kv-tree-input.disabled .kv-carets,.kv-tree-input.disabled .kv-tree-input-values{cursor:not-allowed}.kv-tree-dropdown{padding:0;width:100%}.kv-tree-dropdown-container .form-control .caret{float:right;margin-top:8px}.kv-placeholder{color:#999}.kv-tree-input,.kv-tree-input.form-control{height:auto}.kv-tree-input.disabled{cursor:not-allowed;background-color:#eee}.kv-tree-input.has-multi{padding:3px 8px 5px}.kv-tree-input-values{margin:0;padding:0;overflow:hidden;white-space:nowrap}.kv-tree-input-values li{float:left;list-style:none;padding:2px 5px;margin:3px 3px 0 0;position:relative;background:#f9f9f9;border:1px solid #ddd;border-radius:3px;color:#555;font-size:12px}.kv-tree-input-values li:focus,.kv-tree-input-values li:hover{background:#ebebeb;border-color:#adadad;color:#333}.kv-tree-dropdown .kv-header-container,.kv-tree-dropdown .kv-tree-wrapper.form-control{border:none}.kv-single-select .kv-node-indicators{padding-right:2px;margin-right:2px}.has-multi .kv-tree-input-values{margin-right:20px}.kv-carets{position:absolute;right:10px}.has-multi .kv-carets{padding:4px 4px 0 0}.kv-up .caret{border-top:none;border-bottom:4px solid}.kv-tree-dropdown-container .kv-dn,.kv-tree-dropdown-container.open .kv-up,.kv-tree-dropdown-container.show .kv-up{display:inline-block}.kv-tree-input.dropdown-toggle::after{display:none!important} \ No newline at end of file diff --git a/src/assets/css/kv-tree.css b/src/assets/css/kv-tree.css index 956de92..1728932 100644 --- a/src/assets/css/kv-tree.css +++ b/src/assets/css/kv-tree.css @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Style Sheet * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ @@ -98,11 +98,6 @@ cursor: default; } -.kv-node-detail:hover { - background-color: #e8e8e8; - cursor: default; -} - .kv-node-indicators { float: left; background-color: #fff; @@ -268,8 +263,21 @@ ul.kv-tree, .kv-tree ul { .kv-search-container .kv-search-clear { position: absolute; cursor: default; - padding: 10px; + padding: 6px 8px; right: 0; + color: #000; + text-shadow: 0 1px 0 #fff; + line-height: 1; + opacity: .5; + font-size: 22px; +} + +.tree-bs3 .kv-search-container .kv-search-clear { + padding: 2px 8px; +} + +.kv-search-container .kv-search-clear:hover { + opacity: .85; } .kv-highlight { @@ -282,11 +290,6 @@ ul.kv-tree, .kv-tree ul { font-weight: bold; } -.kv-search-sm .kv-search-clear { - font-size: 1.4em; - padding: 6px 9px; -} - .kv-tree-wrapper .kv-tree { margin-top: -10px !important; } @@ -325,7 +328,12 @@ li.kv-invisible > .kv-tree-list .kv-node-label { } .kv-node-detail:focus, .kv-focussed { - background-color: #f5f5f5; + background-color: #eaeaea; +} + +.kv-node-detail:hover { + background-color: #cecece; + cursor: default; } .kv-node-message { diff --git a/src/assets/css/kv-tree.min.css b/src/assets/css/kv-tree.min.css index b8119c8..e1e0262 100644 --- a/src/assets/css/kv-tree.min.css +++ b/src/assets/css/kv-tree.min.css @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Style Sheet * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com - */.kv-root-node-checkbox,.kv-root-node-toggle{font-style:normal}.kv-search-container,.kv-tree-list{position:relative}.kv-node-message,.kv-toolbar-container{text-align:center}.kv-tree-wrapper,.kv-tree-wrapper.form-control{height:auto;padding:0}.kv-tree-container{overflow:auto;padding:0 5px 5px;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.kv-tree-root{display:inline-block;background-color:#fff;margin-top:10px;padding:0 5px}.kv-tree-root.kv-root-heading{margin:0;padding:5px;font-weight:700}.kv-heading-container{margin:4px 6px;font-weight:700;font-size:1.1em}.kv-footer-container,.kv-header-container{padding:5px}.kv-detail-container{overflow:auto;min-height:150px;padding:0 20px 5px;border-radius:5px;border:1px solid #ddd}.kv-detail-container>.alert{margin-top:50px}.kv-detail-heading{margin:0 -20px 15px;padding:5px 5px 5px 15px;border-radius:4px 4px 0 0;border-bottom:1px solid #ddd;background-color:#f5f5f5}.kv-detail-heading .btn{margin-left:1px}.kv-detail-crumbs{font-size:18px;color:#aaa;padding-top:6px;text-shadow:0 1px 0 #fff}.kv-detail-crumbs .kv-crumb-active{color:#777;font-weight:700}.kv-tree-list{margin:0;background:#fff;top:1em;width:100%;cursor:default}.kv-node-detail:hover{background-color:#e8e8e8;cursor:default}.kv-node-indicators{float:left;background-color:#fff}.kv-node-indicators .kv-node-toggle{margin-right:5px;cursor:pointer}.kv-has-checkbox .kv-node-toggle{margin-right:0;cursor:pointer}.kv-node-checkbox,.kv-root-node-checkbox,.kv-root-node-toggle{margin-right:5px;cursor:pointer}.kv-tree-wrapper .kv-node-unchecked{display:inline}.kv-tree-wrapper .kv-node-checked{display:none}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-detail{background-color:#d9edf7}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-checked,.kv-has-checkbox.kv-selected>.kv-tree-root .kv-node-checked{display:inline}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-unchecked,.kv-has-checkbox.kv-selected>.kv-tree-root .kv-node-unchecked{display:none}.kv-tree li,.kv-tree ul,ul.kv-tree{list-style:none;margin:0;padding:0}.kv-tree ul,ul.kv-tree{padding-left:.73em}.kv-tree li{padding-left:.75em;border:dotted #333;border-width:0 0 1px 1px;line-height:1.9}.kv-tree li ul{border-top:1px dotted #333;margin-left:-.75em;padding-left:1.4em}.kv-parent ul li:last-child>ul,.kv-tree>li:last-child>ul{box-shadow:-5px 0 0 #fff}.kv-parent ul li:last-child ul,.kv-tree>li:last-child ul{margin-bottom:-.75em;padding-bottom:.75em;border-left-color:#fff}.kv-tree li.kv-parent{border-bottom:1px solid #fff}.kv-tree-wrapper .kv-node-collapse{display:inline}.kv-tree-wrapper .kv-collapsed .kv-node-collapse,.kv-tree-wrapper .kv-collapsed>ul>li,.kv-tree-wrapper .kv-node-expand,.kv-tree-wrapper.kv-collapsed .kv-tree-root .kv-node-collapse{display:none}.kv-tree-wrapper .kv-collapsed .kv-node-expand,.kv-tree-wrapper.kv-collapsed .kv-tree-root .kv-node-expand{display:inline}.kv-icon-05{font-size:1.05em}.kv-icon-10{font-size:1.1em}.kv-icon-15{font-size:1.15em}.kv-icon-20{font-size:1.2em}.kv-loading{background:url(../img/loading.gif) center center no-repeat #fff;min-height:150px;cursor:wait}.kv-loading-search{background:url(../img/loading-results.gif) center 55px no-repeat #fff}.kv-loading-search .kv-tree{opacity:.45;cursor:wait}.kv-active-filter li{display:none}.kv-active-filter li.kv-filter-match{display:block}.kv-search-input{padding-right:30px}.kv-search-container .kv-search-clear{position:absolute;cursor:default;padding:10px;right:0}.kv-highlight{color:#8a6d3b;background-color:#fcf8e3;padding:.3em 0}.kv-node-label .kv-search-found{font-weight:700}.kv-search-sm .kv-search-clear{font-size:1.4em;padding:6px 9px}.kv-tree-wrapper .kv-tree{margin-top:-10px!important}li.kv-inactive>.kv-tree-list .kv-node-label{color:#a94442;text-decoration:line-through}li.kv-disabled>.kv-tree-list .kv-node-checkbox,li.kv-disabled>.kv-tree-list .kv-node-icon,li.kv-disabled>.kv-tree-list .kv-node-label{opacity:.45;filter:alpha(opacity=45)}.kv-tree-root.kv-disabled>.kv-root-node-checkbox,li.kv-disabled>.kv-tree-list .kv-node-checkbox{cursor:not-allowed}li.kv-empty{font-style:italic;color:#777;border-color:#777}li.kv-invisible>.kv-tree-list .kv-node-label{font-style:italic;border-top:1px dotted;border-bottom:1px dotted}.kv-tree-nofooter{border-bottom:none}.kv-focussed,.kv-node-detail:focus{background-color:#f5f5f5}.kv-node-message{padding:60px 0;color:#999;font-size:1.4em}.kv-node-toggle,.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon.kv-icon-child,.kv-tree-wrapper .kv-icon-parent,.kv-tree-wrapper .kv-node-closed,.kv-tree-wrapper .kv-node-opened{display:none}.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-opened,.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon.kv-icon-parent{display:inline}.kv-collapsed>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-opened{display:none}.kv-collapsed>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-closed,.kv-parent>.kv-tree-list>.kv-node-indicators>.kv-node-toggle{display:inline}.kv-hide-top .kv-tree-root{display:none}@media (max-width:768px){.kv-detail-container{margin-top:20px}} \ No newline at end of file + */.kv-root-node-checkbox,.kv-root-node-toggle{font-style:normal}.kv-search-container,.kv-tree-list{position:relative}.kv-node-message,.kv-toolbar-container{text-align:center}.kv-tree-wrapper,.kv-tree-wrapper.form-control{height:auto;padding:0}.kv-tree-container{overflow:auto;padding:0 5px 5px;border-top:1px solid #ddd;border-bottom:1px solid #ddd}.kv-tree-root{display:inline-block;background-color:#fff;margin-top:10px;padding:0 5px}.kv-tree-root.kv-root-heading{margin:0;padding:5px;font-weight:700}.kv-heading-container{margin:4px 6px;font-weight:700;font-size:1.1em}.kv-footer-container,.kv-header-container{padding:5px}.kv-detail-container{overflow:auto;min-height:150px;padding:0 20px 5px;border-radius:5px;border:1px solid #ddd}.kv-detail-container>.alert{margin-top:50px}.kv-detail-heading{margin:0 -20px 15px;padding:5px 5px 5px 15px;border-radius:4px 4px 0 0;border-bottom:1px solid #ddd;background-color:#f5f5f5}.kv-detail-heading .btn{margin-left:1px}.kv-detail-crumbs{font-size:18px;color:#aaa;padding-top:6px;text-shadow:0 1px 0 #fff}.kv-detail-crumbs .kv-crumb-active{color:#777;font-weight:700}.kv-tree-list{margin:0;background:#fff;top:1em;width:100%;cursor:default}.kv-node-indicators{float:left;background-color:#fff}.kv-node-indicators .kv-node-toggle{margin-right:5px;cursor:pointer}.kv-has-checkbox .kv-node-toggle{margin-right:0;cursor:pointer}.kv-node-checkbox,.kv-root-node-checkbox,.kv-root-node-toggle{margin-right:5px;cursor:pointer}.kv-tree-wrapper .kv-node-unchecked{display:inline}.kv-tree-wrapper .kv-node-checked{display:none}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-detail{background-color:#d9edf7}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-checked,.kv-has-checkbox.kv-selected>.kv-tree-root .kv-node-checked{display:inline}.kv-has-checkbox .kv-selected>.kv-tree-list .kv-node-unchecked,.kv-has-checkbox.kv-selected>.kv-tree-root .kv-node-unchecked{display:none}.kv-tree li,.kv-tree ul,ul.kv-tree{list-style:none;margin:0;padding:0}.kv-tree ul,ul.kv-tree{padding-left:.73em}.kv-tree li{padding-left:.75em;border:dotted #333;border-width:0 0 1px 1px;line-height:1.9}.kv-tree li ul{border-top:1px dotted #333;margin-left:-.75em;padding-left:1.4em}.kv-parent ul li:last-child>ul,.kv-tree>li:last-child>ul{box-shadow:-5px 0 0 #fff}.kv-parent ul li:last-child ul,.kv-tree>li:last-child ul{margin-bottom:-.75em;padding-bottom:.75em;border-left-color:#fff}.kv-tree li.kv-parent{border-bottom:1px solid #fff}.kv-tree-wrapper .kv-node-collapse{display:inline}.kv-tree-wrapper .kv-collapsed .kv-node-collapse,.kv-tree-wrapper .kv-collapsed>ul>li,.kv-tree-wrapper .kv-node-expand,.kv-tree-wrapper.kv-collapsed .kv-tree-root .kv-node-collapse{display:none}.kv-tree-wrapper .kv-collapsed .kv-node-expand,.kv-tree-wrapper.kv-collapsed .kv-tree-root .kv-node-expand{display:inline}.kv-icon-05{font-size:1.05em}.kv-icon-10{font-size:1.1em}.kv-icon-15{font-size:1.15em}.kv-icon-20{font-size:1.2em}.kv-loading{background:url(../img/loading.gif) center center no-repeat #fff;min-height:150px;cursor:wait}.kv-loading-search{background:url(../img/loading-results.gif) center 55px no-repeat #fff}.kv-loading-search .kv-tree{opacity:.45;cursor:wait}.kv-active-filter li{display:none}.kv-active-filter li.kv-filter-match{display:block}.kv-search-input{padding-right:30px}.kv-search-container .kv-search-clear{position:absolute;cursor:default;padding:6px 8px;right:0;color:#000;text-shadow:0 1px 0 #fff;line-height:1;opacity:.5;font-size:22px}.tree-bs3 .kv-search-container .kv-search-clear{padding:2px 8px}.kv-search-container .kv-search-clear:hover{opacity:.85}.kv-highlight{color:#8a6d3b;background-color:#fcf8e3;padding:.3em 0}.kv-node-label .kv-search-found{font-weight:700}.kv-tree-wrapper .kv-tree{margin-top:-10px!important}li.kv-inactive>.kv-tree-list .kv-node-label{color:#a94442;text-decoration:line-through}li.kv-disabled>.kv-tree-list .kv-node-checkbox,li.kv-disabled>.kv-tree-list .kv-node-icon,li.kv-disabled>.kv-tree-list .kv-node-label{opacity:.45;filter:alpha(opacity=45)}.kv-tree-root.kv-disabled>.kv-root-node-checkbox,li.kv-disabled>.kv-tree-list .kv-node-checkbox{cursor:not-allowed}li.kv-empty{font-style:italic;color:#777;border-color:#777}li.kv-invisible>.kv-tree-list .kv-node-label{font-style:italic;border-top:1px dotted;border-bottom:1px dotted}.kv-tree-nofooter{border-bottom:none}.kv-focussed,.kv-node-detail:focus{background-color:#eaeaea}.kv-node-detail:hover{background-color:#cecece;cursor:default}.kv-node-message{padding:60px 0;color:#999;font-size:1.4em}.kv-node-toggle,.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon.kv-icon-child,.kv-tree-wrapper .kv-icon-parent,.kv-tree-wrapper .kv-node-closed,.kv-tree-wrapper .kv-node-opened{display:none}.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-opened,.kv-parent>.kv-tree-list>.kv-node-detail>.kv-node-icon.kv-icon-parent{display:inline}.kv-collapsed>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-opened{display:none}.kv-collapsed>.kv-tree-list>.kv-node-detail>.kv-node-icon .kv-node-closed,.kv-parent>.kv-tree-list>.kv-node-indicators>.kv-node-toggle{display:inline}.kv-hide-top .kv-tree-root{display:none}@media (max-width:768px){.kv-detail-container{margin-top:20px}} \ No newline at end of file diff --git a/src/assets/js/kv-tree-input.js b/src/assets/js/kv-tree-input.js index 5385eaa..a3a6675 100644 --- a/src/assets/js/kv-tree-input.js +++ b/src/assets/js/kv-tree-input.js @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Input Widget Management Script * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ diff --git a/src/assets/js/kv-tree-input.min.js b/src/assets/js/kv-tree-input.min.js index eb555ae..a478592 100644 --- a/src/assets/js/kv-tree-input.min.js +++ b/src/assets/js/kv-tree-input.min.js @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Input Widget Management Script * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ diff --git a/src/assets/js/kv-tree.js b/src/assets/js/kv-tree.js index f583396..657f7d6 100644 --- a/src/assets/js/kv-tree.js +++ b/src/assets/js/kv-tree.js @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Validation Module. * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ diff --git a/src/assets/js/kv-tree.min.js b/src/assets/js/kv-tree.min.js index 60e6a57..a7522e1 100644 --- a/src/assets/js/kv-tree.min.js +++ b/src/assets/js/kv-tree.min.js @@ -1,12 +1,12 @@ /*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2019 + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2022 * @package yii2-tree-manager * @version 1.1.3 * * Tree View Validation Module. * * Author: Kartik Visweswaran - * Copyright: 2015 - 2019, Kartik Visweswaran, Krajee.com + * Copyright: 2015 - 2022, Kartik Visweswaran, Krajee.com * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ diff --git a/src/controllers/NodeController.php b/src/controllers/NodeController.php index ca8e2de..7fadf6e 100644 --- a/src/controllers/NodeController.php +++ b/src/controllers/NodeController.php @@ -1,7 +1,7 @@ where(['id' => 1])->one(); + * + * // find all active nodes and order them by their price: + * $nodes = CustomTree::find() + * ->where(['status' => 1]) + * ->orderBy('price') + * ->all(); + * ``` + * + * This method is also called by [[yii\db\ActiveRecord::hasOne()]] and [[yii\db\ActiveRecord::hasMany()]] to + * create a relational query. + * + * You may override this method to return a customized query. For example, + * + * ```php + * use kartik\tree\models\Tree; + * + * class CustomTree extends Tree + * { + * public static function find() + * { + * // use CustomTreeQuery instead of the default ActiveQuery + * return new CustomTreeQuery(get_called_class()); + * } + * } + * ``` + * + * The following code shows how to apply a default condition for all queries: + * + * ```php + * use kartik\tree\models\Tree; + * + * class CustomTree extends Tree + * { + * public static function find() + * { + * return parent::find()->where(['deleted' => false]); + * } + * } + * + * // Use andWhere()/orWhere() to apply the default condition + * // SELECT FROM custom_tree WHERE `deleted`=:deleted AND price > 30 + * $nodes = CustomTree::find()->andWhere('price > 30')->all(); + * + * // Use where() to ignore the default condition + * // SELECT FROM custom_tree WHERE price > 30 + * $nodes = CustomTree::find()->where('price > 30')->all(); + * + * @return TreeQuery the newly created [[TreeQuery]] instance. */ public static function find() { - /** @noinspection PhpUndefinedFieldInspection */ $treeQuery = isset(self::$treeQueryClass) ? self::$treeQueryClass : TreeQuery::class; return new $treeQuery(get_called_class()); } /** - * @inheritdoc + * Creates the query for the [[Tree]] active record + * + * @return TreeQuery the newly created [[TreeQuery]] instance. */ public static function createQuery() { - /** @noinspection PhpUndefinedFieldInspection */ $treeQuery = isset(self::$treeQueryClass) ? self::$treeQueryClass : TreeQuery::class; return new $treeQuery(['modelClass' => get_called_class()]); } /** - * @inheritdoc + * Returns a list of behaviors that this component should behave as. + * + * Child classes may override this method to specify the behaviors they want to behave as. + * + * The return value of this method should be an array of behavior objects or configurations + * indexed by behavior names. A behavior configuration can be either a string specifying + * the behavior class or an array of the following structure: + * + * ```php + * 'behaviorName' => [ + * 'class' => 'BehaviorClass', + * 'property1' => 'value1', + * 'property2' => 'value2', + * ] + * ``` + * + * Note that a behavior class must extend from [[yii\base\Behavior]]. Behaviors can be attached using a name or anonymously. + * When a name is used as the array key, using this name, the behavior can later be retrieved using [[Tree::getBehavior()]] + * or be detached using [[Tree::detachBehavior()]]. Anonymous behaviors can not be retrieved or detached. + * + * Behaviors declared in this method will be attached to the component automatically (on demand). + * + * @return array the behavior configurations. + * @throws InvalidConfigException */ public function behaviors() { @@ -94,18 +179,105 @@ public function behaviors() } /** - * @inheritdoc + * Declares which DB operations should be performed within a transaction in different scenarios. + * The supported DB operations are: [[Tree::OP_INSERT]], [[Tree::OP_UPDATE]] and [[Tree::OP_DELETE]], + * which correspond to the [[Tree::insert()]], [[Tree::update()]] and [[Tree::delete()]] methods, respectively. + * By default, these methods are NOT enclosed in a DB transaction. + * + * In some scenarios, to ensure data consistency, you may want to enclose some or all of them + * in transactions. You can do so by overriding this method and returning the operations + * that need to be transactional. For example, + * + * ```php + * return [ + * 'admin' => Tree::OP_INSERT, + * 'api' => Tree::OP_INSERT | Tree::OP_UPDATE | Tree::OP_DELETE, + * // the above is equivalent to the following: + * // 'api' => Tree::OP_ALL, + * + * ]; + * ``` + * + * The above declaration specifies that in the "admin" scenario, the insert operation [[Tree::insert()]]) + * should be done in a transaction; and in the "api" scenario, all the operations should be done + * in a transaction. + * + * @return array the declarations of transactional operations. The array keys are scenarios names, + * and the array values are the corresponding transaction operations. */ public function transactions() { - /** @noinspection PhpUndefinedClassConstantInspection */ return [ self::SCENARIO_DEFAULT => self::OP_ALL, ]; } /** - * @inheritdoc + * Returns the validation rules for attributes. + * + * Validation rules are used by [[Tree::validate()]] to check if attribute values are valid. + * Child classes may override this method to declare different validation rules. + * + * Each rule is an array with the following structure: + * + * ```php + * [ + * ['attribute1', 'attribute2'], + * 'validator type', + * 'on' => ['scenario1', 'scenario2'], + * //...other parameters... + * ] + * ``` + * + * where + * + * - attribute list: required, specifies the attributes array to be validated, for single attribute you can pass a string; + * - validator type: required, specifies the validator to be used. It can be a built-in validator name, + * a method name of the model class, an anonymous function, or a validator class name. + * - on: optional, specifies the [[Tree::scenarios()]] array in which the validation + * rule can be applied. If this option is not set, the rule will apply to all scenarios. + * - additional name-value pairs can be specified to initialize the corresponding validator properties. + * Please refer to individual validator class API for possible properties. + * + * A validator can be either an object of a class extending [[yii\validators\Validator]], or a model class method + * (called *inline validator*) that has the following signature: + * + * ```php + * // $params refers to validation parameters given in the rule + * function validatorName($attribute, $params) + * ``` + * + * In the above `$attribute` refers to the attribute currently being validated while `$params` contains an array of + * validator configuration options such as `max` in case of `string` validator. The value of the attribute currently being validated + * can be accessed as `$this->$attribute`. Note the `$` before `attribute`; this is taking the value of the variable + * `$attribute` and using it as the name of the property to access. + * + * Yii also provides a set of [[yii\validators\Validator::builtInValidators|built-in validators]]. + * Each one has an alias name which can be used when specifying a validation rule. + * + * Below are some examples: + * + * ```php + * [ + * // built-in "required" validator + * [['username', 'password'], 'required'], + * // built-in "string" validator customized with "min" and "max" properties + * ['username', 'string', 'min' => 3, 'max' => 12], + * // built-in "compare" validator that is used in "register" scenario only + * ['password', 'compare', 'compareAttribute' => 'password2', 'on' => 'register'], + * // an inline validator defined via the "authenticate()" method in the model class + * ['password', 'authenticate', 'on' => 'login'], + * // a validator of class "DateRangeValidator" + * ['dateRange', 'DateRangeValidator'], + * ]; + * ``` + * + * Note, in order to inherit rules defined in the parent class, a child class needs to + * merge the parent rules with child rules using functions such as `array_merge()`. + * + * @return array validation rules + * @throws InvalidConfigException + * @see Tree::scenarios() */ public function rules() { @@ -155,7 +327,7 @@ public function initDefaults() extract($module->dataStructure); $this->setDefault($iconTypeAttribute, TreeView::ICON_CSS); foreach (static::$boolAttribs as $attr) { - $val = in_array($attr, static::$falseAttribs) ? false : true; + $val = !in_array($attr, static::$falseAttribs); $this->setDefault($attr, $val); } } @@ -280,7 +452,6 @@ public function activateNode($currNode = true) $module = TreeView::module(); extract($module->dataStructure); if ($this->isRemovableAll()) { - /** @noinspection PhpUndefinedMethodInspection */ $children = $this->children()->all(); foreach ($children as $child) { /** @@ -288,7 +459,6 @@ public function activateNode($currNode = true) */ $child->active = true; if (!$child->save()) { - /** @noinspection PhpUndefinedFieldInspection */ /** @noinspection PhpUndefinedVariableInspection */ $this->nodeActivationErrors[] = [ 'id' => $child->$idAttribute, @@ -301,7 +471,6 @@ public function activateNode($currNode = true) if ($currNode) { $this->active = true; if (!$this->save()) { - /** @noinspection PhpUndefinedFieldInspection */ /** @noinspection PhpUndefinedVariableInspection */ $this->nodeActivationErrors[] = [ 'id' => $this->$idAttribute, @@ -334,12 +503,10 @@ public function removeNode($softDelete = true, $currNode = true) $module = TreeView::module(); extract($module->dataStructure); if ($this->isRemovableAll()) { - /** @noinspection PhpUndefinedMethodInspection */ $children = $this->children()->all(); foreach ($children as $child) { $child->active = false; if (!$child->save()) { - /** @noinspection PhpUndefinedFieldInspection */ /** @noinspection PhpUndefinedVariableInspection */ $this->nodeRemovalErrors[] = [ 'id' => $child->$keyAttribute, @@ -352,7 +519,6 @@ public function removeNode($softDelete = true, $currNode = true) if ($currNode) { $this->active = false; if (!$this->save()) { - /** @noinspection PhpUndefinedFieldInspection */ /** @noinspection PhpUndefinedVariableInspection */ $this->nodeRemovalErrors[] = [ 'id' => $this->$keyAttribute, @@ -364,14 +530,28 @@ public function removeNode($softDelete = true, $currNode = true) } return true; } else { - /** @noinspection PhpUndefinedMethodInspection */ return $this->removable_all || $this->isRoot() && $this->children()->count() == 0 ? $this->deleteWithChildren() : $this->delete(); } } + /** - * @inheritdoc + * Returns the attribute labels. + * + * Attribute labels are mainly used for display purpose. For example, given an attribute + * `firstName`, we can declare a label `First Name` which is more user-friendly and can + * be displayed to end users. + * + * By default an attribute label is generated using [[yii\db\ActiveRecord::generateAttributeLabel()]]. + * This method allows you to explicitly specify attribute labels. + * + * Note, in order to inherit labels defined in the parent class, a child class needs to + * merge the parent labels with child labels using functions such as `array_merge()`. + * + * @return array attribute labels (name => label) + * @throws InvalidConfigException + * @see yii\db\ActiveRecord::generateAttributeLabel() */ public function attributeLabels() { @@ -413,7 +593,7 @@ public function attributeLabels() /** * Generate and return the breadcrumbs for the node. * - * @param integer $depth the breadcrumbs parent depth + * @param int $depth the breadcrumbs parent depth * @param string $glue the pattern to separate the breadcrumbs * @param string $currCss the CSS class to be set for current node * @param string $new the name to be displayed for a new node @@ -432,7 +612,6 @@ public function getBreadcrumbs($depth = 1, $glue = ' » ', $currCss = 'kv-c $depth = empty($depth) ? null : intval($depth); $module = TreeView::module(); $nameAttribute = ArrayHelper::getValue($module->dataStructure, 'nameAttribute', 'name'); - /** @noinspection PhpUndefinedMethodInspection */ $crumbNodes = $depth === null ? $this->parents()->all() : $this->parents($depth - 1)->all(); $crumbNodes[] = $this; $i = 1; diff --git a/src/views/_form.php b/src/views/_form.php index 00410de..7a1a516 100644 --- a/src/views/_form.php +++ b/src/views/_form.php @@ -1,6 +1,6 @@
-
+
'btn ' . $defaultBtnCss, 'title' => $resetTitle] + ['class' => 'btn btn-sm ' . $defaultBtnCss, 'title' => $resetTitle] ) ?> 'btn btn-primary', 'title' => $submitTitle] + ['class' => 'btn btn-sm btn-primary', 'title' => $submitTitle] ) ?>