├── .gitignore
├── README.md
├── composer.json
├── composer.lock
├── images
└── tree.png
├── resources
├── dist
│ ├── jquery.nestable.min.css
│ └── jquery.nestable.min.js
├── lang
│ ├── ar
│ │ └── filament-tree.php
│ └── en
│ │ └── filament-tree.php
└── views
│ ├── components
│ ├── tree-field.blade.php
│ └── tree-item.blade.php
│ ├── tree-assets.blade.php
│ └── tree-page.blade.php
└── src
├── FilamentTreeServiceProvider.php
├── Forms
└── Components
│ └── TreeField.php
├── HasTree.php
└── TreePage.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | /.idea
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Filament Tree
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 | ```sh
10 | composer require yemenpoint/filament-tree
11 | ```
12 |
13 | publish assets
14 |
15 | ```sh
16 | php artisan vendor:publish --tag="filament-tree-assets"
17 | php artisan vendor:publish --tag="filament-tree-views"
18 | ```
19 |
20 | # Tree Field
21 |
22 | ### migration
23 | ```php
24 | Schema::table('tryings', function (Blueprint $table) {
25 | $table->json("items")->nullable();
26 | });
27 | ```
28 |
29 | ```php
30 |
31 | use Yemenpoint\FilamentTree\Forms\Components\TreeField;
32 |
33 | TreeField::make("items")
34 | ->setMaxDepth(999)
35 | ->default([["id" => "1", "name" => "item 1", "children" => [["id" => "2", "name" => "item 2", "children" => []]]]]),
36 | ```
37 |
38 | # Tree Page
39 |
40 | ## Table structure and model
41 | ```structure
42 | categories
43 | id - integer
44 | parent_id - integer
45 | order - integer
46 | name - string
47 | ```
48 | ```php
49 | Schema::create('categories', function (Blueprint $table) {
50 | $table->id();
51 | $table->unsignedBigInteger('parent_id')->nullable();
52 | $table->integer('order')->nullable()->default(0);
53 | $table->string('name');
54 | });
55 | ```
56 |
57 | # model
58 | ```php
59 | hasMany(self::class, 'parent_id', 'id')->with("children")->orderBy("order");
74 | }
75 | }
76 |
77 | ```
78 | # page
79 |
80 | ```php
81 |
82 | whereNull("parent_id")->orderBy("order")->get()->toArray();
97 | }
98 |
99 | public function getMaxDepth(): int
100 | {
101 | return parent::getMaxDepth(); // TODO: Change the autogenerated stub
102 | }
103 |
104 | public function isDisabled(): bool
105 | {
106 | return parent::isDisabled(); // TODO: Change the autogenerated stub
107 | }
108 |
109 | }
110 |
111 | ```
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yemenpoint/filament-tree",
3 | "description": "Filament Tree field and page",
4 | "type": "library",
5 | "require": {
6 | "php": "^8.0",
7 | "filament/filament": "*"
8 | },
9 | "autoload": {
10 | "psr-4": {
11 | "Yemenpoint\\FilamentTree\\": "src/"
12 | }
13 | },
14 | "authors": [
15 | {
16 | "name": "yemenpoint",
17 | "email": "ebrahim29001@gmail.com"
18 | }
19 | ],
20 | "extra": {
21 | "laravel": {
22 | "providers": [
23 | "Yemenpoint\\FilamentTree\\FilamentTreeServiceProvider"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/images/tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yemenpoint/FilamentTree/8cd175a7abfa317f2eed14c79c8694293ded9de8/images/tree.png
--------------------------------------------------------------------------------
/resources/dist/jquery.nestable.min.css:
--------------------------------------------------------------------------------
1 | .dd{position:relative;display:block;margin:0;padding:0;max-width:600px;list-style:none;font-size:13px;line-height:20px}.dd-list{display:block;position:relative;margin:0;padding:0;list-style:none}.dd-list .dd-list{padding-left:30px}.dd-empty,.dd-item,.dd-placeholder{display:block;position:relative;margin:0;padding:0;min-height:20px;font-size:13px;line-height:20px}.dd-handle{display:block;height:30px;margin:5px 0;padding:5px 10px;color:#333;text-decoration:none;font-weight:700;border:1px solid #ccc;background:#fafafa;border-radius:3px;box-sizing:border-box}.dd-handle:hover{color:#2ea8e5;background:#fff}.dd-item>button{position:relative;cursor:pointer;float:left;width:25px;height:20px;margin:5px 0;padding:0;text-indent:100%;white-space:nowrap;overflow:hidden;border:0;background:0 0;font-size:12px;line-height:1;text-align:center;font-weight:700}.dd-item>button:before{display:block;position:absolute;width:100%;text-align:center;text-indent:0}.dd-item>button.dd-expand:before{content:'+'}.dd-item>button.dd-collapse:before{content:'-'}.dd-expand{display:none}.dd-collapsed .dd-collapse,.dd-collapsed .dd-list{display:none}.dd-collapsed .dd-expand{display:block}.dd-empty,.dd-placeholder{margin:5px 0;padding:0;min-height:30px;background:#f2fbff;border:1px dashed #b6bcbf;box-sizing:border-box;-moz-box-sizing:border-box}.dd-empty{border:1px dashed #bbb;min-height:100px;background-color:#e5e5e5;background-size:60px 60px;background-position:0 0,30px 30px}.dd-dragel{position:absolute;pointer-events:none;z-index:9999}.dd-dragel>.dd-item .dd-handle{margin-top:0}.dd-dragel .dd-handle{box-shadow:2px 4px 6px 0 rgba(0,0,0,.1)}.dd-nochildren .dd-placeholder{display:none}
--------------------------------------------------------------------------------
/resources/dist/jquery.nestable.min.js:
--------------------------------------------------------------------------------
1 | !function(t,e,s,i){function o(e,o){this.w=t(s),this.el=t(e),(o=o||a).rootClass!==i&&"dd"!==o.rootClass&&(o.listClass=o.listClass?o.listClass:o.rootClass+"-list",o.itemClass=o.itemClass?o.itemClass:o.rootClass+"-item",o.dragClass=o.dragClass?o.dragClass:o.rootClass+"-dragel",o.handleClass=o.handleClass?o.handleClass:o.rootClass+"-handle",o.collapsedClass=o.collapsedClass?o.collapsedClass:o.rootClass+"-collapsed",o.placeClass=o.placeClass?o.placeClass:o.rootClass+"-placeholder",o.noDragClass=o.noDragClass?o.noDragClass:o.rootClass+"-nodrag",o.noChildrenClass=o.noChildrenClass?o.noChildrenClass:o.rootClass+"-nochildren",o.emptyClass=o.emptyClass?o.emptyClass:o.rootClass+"-empty"),this.options=t.extend({},a,o),this.options.json!==i&&this._build(),this.init()}var n="ontouchstart"in s,l=function(){var t=s.createElement("div"),i=s.documentElement;if(!("pointerEvents"in t.style))return!1;t.style.pointerEvents="auto",t.style.pointerEvents="x",i.appendChild(t);var o=e.getComputedStyle&&"auto"===e.getComputedStyle(t,"").pointerEvents;return i.removeChild(t),!!o}(),a={contentCallback:function(t){return t.content?t.content:t.id},listNodeName:"ol",itemNodeName:"li",handleNodeName:"div",contentNodeName:"span",rootClass:"dd",listClass:"dd-list",itemClass:"dd-item",dragClass:"dd-dragel",handleClass:"dd-handle",contentClass:"dd-content",collapsedClass:"dd-collapsed",placeClass:"dd-placeholder",noDragClass:"dd-nodrag",noChildrenClass:"dd-nochildren",emptyClass:"dd-empty",expandBtnHTML:'',collapseBtnHTML:'',group:0,maxDepth:5,threshold:20,fixedDepth:!1,fixed:!1,includeContent:!1,scroll:!1,scrollSensitivity:1,scrollSpeed:5,scrollTriggers:{top:40,left:40,right:-40,bottom:-40},effect:{animation:"none",time:"slow"},callback:function(t,e,s){},onDragStart:function(t,e,s){},beforeDragStop:function(t,e,s){},listRenderer:function(t,e){var s="<"+e.listNodeName+' class="'+e.listClass+'">';return s+=t,s+=""+e.listNodeName+">"},itemRenderer:function(e,s,i,o,n){var l=t.map(e,function(t,e){return" "+e+'="'+t+'"'}).join(" "),a="<"+o.itemNodeName+l+">";return a+="<"+o.handleNodeName+' class="'+o.handleClass+'">',a+="<"+o.contentNodeName+' class="'+o.contentClass+'">',a+=s,a+=""+o.contentNodeName+">",a+=""+o.handleNodeName+">",a+=i,a+=""+o.itemNodeName+">"}};o.prototype={init:function(){var s=this;s.reset(),s.el.data("nestable-group",this.options.group),s.placeEl=t('');var i=this.el.find(s.options.itemNodeName);t.each(i,function(e,i){var o=t(i),n=o.parent();s.setParent(o),n.hasClass(s.options.collapsedClass)&&s.collapseItem(n.parent())}),i.length||this.appendEmptyElement(this.el),s.el.on("click","button",function(e){if(!s.dragEl){var i=t(e.currentTarget),o=i.data("action"),n=i.parents(s.options.itemNodeName).eq(0);"collapse"===o&&s.collapseItem(n),"expand"===o&&s.expandItem(n)}});var o=function(e){var i=t(e.target);if(!i.hasClass(s.options.handleClass)){if(i.closest("."+s.options.noDragClass).length)return;i=i.closest("."+s.options.handleClass)}i.length&&!s.dragEl&&(s.isTouch=/^touch/.test(e.type),s.isTouch&&1!==e.touches.length||(e.preventDefault(),s.dragStart(e.touches?e.touches[0]:e)))},l=function(t){s.dragEl&&(t.preventDefault(),s.dragMove(t.touches?t.touches[0]:t))},a=function(t){s.dragEl&&(t.preventDefault(),s.dragStop(t.touches?t.changedTouches[0]:t))};n&&(s.el[0].addEventListener("touchstart",o,!1),e.addEventListener("touchmove",l,!1),e.addEventListener("touchend",a,!1),e.addEventListener("touchcancel",a,!1)),s.el.on("mousedown",o),s.w.on("mousemove",l),s.w.on("mouseup",a);s.el.bind("destroy-nestable",function(){n&&(s.el[0].removeEventListener("touchstart",o,!1),e.removeEventListener("touchmove",l,!1),e.removeEventListener("touchend",a,!1),e.removeEventListener("touchcancel",a,!1)),s.el.off("mousedown",o),s.w.off("mousemove",l),s.w.off("mouseup",a),s.el.off("click"),s.el.unbind("destroy-nestable"),s.el.data("nestable",null)})},destroy:function(){this.el.trigger("destroy-nestable")},add:function(e){var s="."+this.options.listClass,o=t(this.el).children(s);e.parent_id!==i&&(o=o.find('[data-id="'+e.parent_id+'"]'),delete e.parent_id,0===o.children(s).length&&(o=o.append(this.options.listRenderer("",this.options))),o=o.find(s+":first"),this.setParent(o.parent())),o.append(this._buildItem(e,this.options))},replace:function(t){var e=this._buildItem(t,this.options);this._getItemById(t.id).replaceWith(e)},removeItem:function(e){var s=this.options,i=this.el;(e=e||this).remove();var o="."+s.listClass+" ."+s.listClass+":not(:has(*))";t(i).find(o).remove();t(i).find('[data-action="expand"], [data-action="collapse"]').each(function(){0===t(this).siblings("."+s.listClass).length&&t(this).remove()})},remove:function(t,e){var s=this.options,i=this,o=this._getItemById(t),n=s.effect.animation||"fade",l=s.effect.time||"slow";"fade"===n?o.fadeOut(l,function(){i.removeItem(o)}):this.removeItem(o),e&&e()},removeAll:function(e){function s(){l.each(function(){i.removeItem(t(this))}),n.show(),e&&e()}var i=this,o=this.options,n=i.el.find(o.listNodeName).first(),l=n.children(o.itemNodeName),a=o.effect.animation||"fade",r=o.effect.time||"slow";"fade"===a?n.fadeOut(r,s):s()},_getItemById:function(e){return t(this.el).children("."+this.options.listClass).find('[data-id="'+e+'"]')},_build:function(){var e=this.options.json;"string"==typeof e&&(e=JSON.parse(e)),t(this.el).html(this._buildList(e,this.options))},_buildList:function(e,s){if(!e)return"";var i="",o=this;return t.each(e,function(t,e){i+=o._buildItem(e,s)}),s.listRenderer(i,s)},_buildItem:function(e,s){function i(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'"};return t+"".replace(/[&<>"']/g,function(t){return e[t]})}function o(t){var e={};for(var s in t)e[t[s]]=t[s];return e}var n=function(e){delete(e=t.extend({},e)).children,delete e.classes,delete e.content;var s={};return t.each(e,function(t,e){"object"==typeof e&&(e=JSON.stringify(e)),s["data-"+t]=i(e)}),s}(e);n.class=function(e,s){var i=e.classes||{};"string"==typeof i&&(i=[i]);var n=o(i);return n[s.itemClass]=s.itemClass,t.map(n,function(t){return t}).join(" ")}(e,s);var l=s.contentCallback(e),a=this._buildList(e.children,s),r=t(s.itemRenderer(n,l,a,s,e));return this.setParent(r),r[0].outerHTML},serialize:function(){var e=this,s=function(i){var o=[];return i.children(e.options.itemNodeName).each(function(){var i=t(this),n=t.extend({},i.data()),l=i.children(e.options.listNodeName);if(e.options.includeContent){var a=i.find("."+e.options.contentClass).html();a&&(n.content=a)}l.length&&(n.children=s(l)),o.push(n)}),o};return s(e.el.find(e.options.listNodeName).first())},asNestedSet:function(){function e(i,l,a){var r,d,h=a+1;return t(i).children(o.listNodeName).children(o.itemNodeName).length>0&&(l++,t(i).children(o.listNodeName).children(o.itemNodeName).each(function(){h=e(t(this),l,h)}),l--),r=t(i).attr("data-id"),s(r)&&(r=parseInt(r)),d=t(i).parent(o.listNodeName).parent(o.itemNodeName).attr("data-id")||"",s(d)&&(d=parseInt(d)),r&&n.push({id:r,parent_id:d,depth:l,lft:a,rgt:h}),a=h+1}function s(e){return t.isNumeric(e)&&Math.floor(e)==e}var i=this,o=i.options,n=[],l=1;return i.el.find(o.listNodeName).first().children(o.itemNodeName).each(function(){l=e(this,0,l)}),n=n.sort(function(t,e){return t.lft-e.lft})},returnOptions:function(){return this.options},serialise:function(){return this.serialize()},toHierarchy:function(e){function s(e){var o=(t(e).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/);if(o){var n={id:o[2]};return t(e).children(i.listType).children(i.items).length>0&&(n.children=[],t(e).children(i.listType).children(i.items).each(function(){var t=s(this);n.children.push(t)})),n}}var i=t.extend({},this.options,e),o=[];return t(this.element).children(i.items).each(function(){var t=s(this);o.push(t)}),o},toArray:function(){function e(n,l,a){var r,d,h=a+1;return n.children(s.options.listNodeName).children(s.options.itemNodeName).length>0&&(l++,n.children(s.options.listNodeName).children(s.options.itemNodeName).each(function(){h=e(t(this),l,h)}),l--),r=n.data().id,d=l===i+1?s.rootID:n.parent(s.options.listNodeName).parent(s.options.itemNodeName).data().id,r&&o.push({id:r,parent_id:d,depth:l,left:a,right:h}),a=h+1}var s=t.extend({},this.options,this),i=s.startDepthCount||0,o=[],n=2,l=this;return l.el.find(l.options.listNodeName).first().children(l.options.itemNodeName).each(function(){n=e(t(this),i+1,n)}),o=o.sort(function(t,e){return t.left-e.left})},reset:function(){this.mouse={offsetX:0,offsetY:0,startX:0,startY:0,lastX:0,lastY:0,nowX:0,nowY:0,distX:0,distY:0,dirAx:0,dirX:0,dirY:0,lastDirX:0,lastDirY:0,distAxX:0,distAxY:0},this.isTouch=!1,this.moving=!1,this.dragEl=null,this.dragRootEl=null,this.dragDepth=0,this.hasNewRoot=!1,this.pointEl=null},expandItem:function(t){t.removeClass(this.options.collapsedClass)},collapseItem:function(t){t.children(this.options.listNodeName).length&&t.addClass(this.options.collapsedClass)},expandAll:function(){var e=this;e.el.find(e.options.itemNodeName).each(function(){e.expandItem(t(this))})},collapseAll:function(){var e=this;e.el.find(e.options.itemNodeName).each(function(){e.collapseItem(t(this))})},setParent:function(e){e.is(this.options.itemNodeName)&&e.children(this.options.listNodeName).length&&(e.children("[data-action]").remove(),e.prepend(t(this.options.expandBtnHTML)),e.prepend(t(this.options.collapseBtnHTML)))},unsetParent:function(t){t.removeClass(this.options.collapsedClass),t.children("[data-action]").remove(),t.children(this.options.listNodeName).remove()},dragStart:function(e){var i=this.mouse,o=t(e.target).closest(this.options.itemNodeName),n={top:e.pageY,left:e.pageX},l=this.options.onDragStart.call(this,this.el,o,n);if(void 0===l||!1!==l){this.placeEl.css("height",o.height()),i.offsetX=e.pageX-o.offset().left,i.offsetY=e.pageY-o.offset().top,i.startX=i.lastX=e.pageX,i.startY=i.lastY=e.pageY,this.dragRootEl=this.el,this.dragEl=t(s.createElement(this.options.listNodeName)).addClass(this.options.listClass+" "+this.options.dragClass),this.dragEl.css("width",o.outerWidth()),this.setIndexOfItem(o),o.after(this.placeEl),o[0].parentNode.removeChild(o[0]),o.appendTo(this.dragEl),t(s.body).append(this.dragEl),this.dragEl.css({left:e.pageX-i.offsetX,top:e.pageY-i.offsetY});var a,r,d=this.dragEl.find(this.options.itemNodeName);for(a=0;athis.dragDepth&&(this.dragDepth=r)}},createSubLevel:function(e,s){var i=t("<"+this.options.listNodeName+"/>").addClass(this.options.listClass);return s&&i.append(s),e.append(i),this.setParent(e),i},setIndexOfItem:function(e,s){(s=s||[]).unshift(e.index()),t(e[0].parentNode)[0]!==this.dragRootEl[0]?this.setIndexOfItem(t(e[0].parentNode),s):this.dragEl.data("indexOfItem",s)},restoreItemAtIndex:function(e,s){for(var i=this.el,o=s.length-1,n=0;n0?1:-1,d.dirY=0===d.distY?0:d.distY>0?1:-1;var h=Math.abs(d.distX)>Math.abs(d.distY)?1:0;if(!d.moving)return d.dirAx=h,void(d.moving=!0);if(r.scroll)if(void 0!==e.jQuery.fn.scrollParent){var c=!1,p=this.el.scrollParent()[0];p!==s&&"HTML"!==p.tagName?(r.scrollTriggers.bottom+p.offsetHeight-i.pageY=r.threshold&&(d.distAxX=0,a=this.placeEl.prev(r.itemNodeName),d.distX>0&&a.length&&!a.hasClass(r.collapsedClass)&&!a.hasClass(r.noChildrenClass)&&(o=a.find(r.listNodeName).last(),this.placeEl.parents(r.listNodeName).length+this.dragDepth<=r.maxDepth&&(o.length?(o=a.children(r.listNodeName).last()).append(this.placeEl):this.createSubLevel(a,this.placeEl))),d.distX<0&&(this.placeEl.next(r.itemNodeName).length||(n=this.placeEl.parent(),this.placeEl.closest(r.itemNodeName).after(this.placeEl),n.children().length||this.unsetParent(n.parent()))));var f=!1;if(l||(this.dragEl[0].style.visibility="hidden"),this.pointEl=t(s.elementFromPoint(i.pageX-s.body.scrollLeft,i.pageY-(e.pageYOffset||s.documentElement.scrollTop))),l||(this.dragEl[0].style.visibility="visible"),this.pointEl.hasClass(r.handleClass)&&(this.pointEl=this.pointEl.closest(r.itemNodeName)),this.pointEl.hasClass(r.emptyClass))f=!0;else if(!this.pointEl.length||!this.pointEl.hasClass(r.itemClass))return;var u=this.pointEl.closest("."+r.rootClass),m=this.dragRootEl.data("nestable-id")!==u.data("nestable-id");if(!d.dirAx||m||f){if(m&&r.group!==u.data("nestable-group"))return;if(this.options.fixedDepth&&this.dragDepth+1!==this.pointEl.parents(r.listNodeName).length)return;if(this.dragDepth-1+this.pointEl.parents(r.listNodeName).length>r.maxDepth)return;var g=i.pageY')}},t.fn.nestable=function(s){var i=this,n=this,l=arguments;return"Nestable"in e||(e.Nestable={},Nestable.counter=0),i.each(function(){var e=t(this).data("nestable");if(e){if("string"==typeof s&&"function"==typeof e[s])if(l.length>1){for(var i=[],a=1;a 'تم الحفظ بنجاح',
5 | 'tree_error_message' => 'حدث خطا اثناء الحفظ',
6 | 'collapse_all' => 'تصغير الكل',
7 | 'expand_all' => 'توسيع الكل',
8 | 'save' => 'حفظ',
9 | ];
--------------------------------------------------------------------------------
/resources/lang/en/filament-tree.php:
--------------------------------------------------------------------------------
1 | 'saved successfully',
5 | 'tree_error_message' => 'something went wrong',
6 | 'collapse_all' => 'collapse all',
7 | 'expand_all' => 'expand all',
8 | 'save' => 'save',
9 | ];
--------------------------------------------------------------------------------
/resources/views/components/tree-field.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 |
3 | $tree_id = "tree" . \Illuminate\Support\Str::slug($getStatePath(), "_");
4 | $items = $getValue();
5 | @endphp
6 |
7 | @include("filament-tree::tree-assets")
8 |
9 |
38 |
48 |
51 |
52 |
64 |
65 |
66 |
67 | @if($items && is_array($items))
68 | @foreach ($items as $item)
69 | @include("filament-tree::components.tree-item", ["item"=> $item])
70 | @endforeach
71 | @endif
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/resources/views/components/tree-item.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{data_get($item,"name")}}
3 |
4 | @if(count($children = data_get($item,"children",[])))
5 | @foreach ($children as $child)
6 | @include("filament-tree::components.tree-item", ["item"=> $child])
7 | @endforeach
8 | @endif
9 |
10 |
11 |
--------------------------------------------------------------------------------
/resources/views/tree-assets.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/resources/views/tree-page.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $tree_id = "tree_view_id";
3 | @endphp
4 |
5 | @include("filament-tree::tree-assets")
6 |
34 |
35 |
36 |
48 |
49 |
50 |
51 | @if($items && is_array($items))
52 | @foreach ($items as $item)
53 | @include("filament-tree::components.tree-item", ["item"=> $item])
54 | @endforeach
55 | @endif
56 |
57 |
58 | @if(!$this->isDisabled())
59 |
60 |
69 | @endif
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/FilamentTreeServiceProvider.php:
--------------------------------------------------------------------------------
1 | name('filament-tree')
15 | ->hasAssets()
16 | ->hasTranslations()
17 | ->hasViews();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Forms/Components/TreeField.php:
--------------------------------------------------------------------------------
1 | maxDepth;
16 | }
17 |
18 |
19 | public function setMaxDepth(int $maxDepth)
20 | {
21 | $this->maxDepth = $maxDepth;
22 | return $this;
23 | }
24 |
25 |
26 | public function getValue()
27 | {
28 | $state = parent::getState();
29 |
30 | if (is_array($state)) {
31 | return $state;
32 | } else {
33 | try {
34 | return json_decode($state, true);
35 | } catch (\Exception $e) {
36 | return [];
37 | }
38 | }
39 | }
40 |
41 | public function getState()
42 | {
43 | $state = parent::getState();
44 |
45 | if (is_array($state)) {
46 | return json_encode($state);
47 | } else {
48 | try {
49 | return $state;
50 | } catch (\Exception $e) {
51 | return json_encode([]);
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/HasTree.php:
--------------------------------------------------------------------------------
1 | &$item) {
24 | $item[self::orderColumnName()] = $key;
25 | }
26 | foreach ($readyItems as $i) {
27 | self::where("id",data_get($i,"id"))->update($i);
28 | }
29 |
30 | return ["success", __("filament-tree::filament-tree.tree_saved_message")];
31 | }
32 |
33 |
34 | public static function prepareNode(&$readyItems, $item, $parent_id = null)
35 | {
36 | $readyItems[] = [
37 | "id" => data_get($item, 'id'),
38 | self::parentColumnName() => $parent_id,
39 | ];
40 |
41 | if ($children = data_get($item, "children", [])) {
42 | foreach ($children as $child) {
43 | self::prepareNode($readyItems, $child, data_get($item, 'id'));
44 | }
45 | }
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/src/TreePage.php:
--------------------------------------------------------------------------------
1 | $this->getItems()
30 | ];
31 | }
32 |
33 | public function updateTree($tree)
34 | {
35 | if ($this->isDisabled()) {
36 | return;
37 | }
38 | try {
39 | $model = static::getModel();
40 |
41 | list($status, $message) = $model::SaveTree($tree);
42 |
43 | if ($status && $message) {
44 | $this->notify($status, $message);
45 | }
46 |
47 | } catch (\Exception $e) {
48 | $this->notify("error", __("filament-tree::filament-tree.tree_error_message"));
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------