datagrid icon indicating copy to clipboard operation
datagrid copied to clipboard

Treeview - child nodes

Open MikKuba opened this issue 1 year ago • 6 comments

I have problem with child nodes in treeview.

This is how I set dataSource - result is array, because example does not work good with Doctrine. IMO array is OK.

$grid->setDataSource($this->getResourcesTree($this->facade->getResources([], "priority")));
$grid->setTreeView([$this, 'getChildren'], 'has_children');

And functions for creating tree:

    private function getResourcesTree(array $resources, $parentId = null, $fromParent = null): array
    {
        $return = [];
        foreach ($resources as $resource) {
            if ($resource['parentId'] == $parentId) {
                $children = $this->getResourcesTree($resources, $resource['id']);
                if($children) {
                    $resource['children'] = $children;
                }
                $resource['has_children'] = isset($resource['children']) ? count($resource['children']) : 0;
                
                $return[$resource['id']] = $resource;
            }
        }
        if($fromParent) {
            $return = $this->getChildrenTree($return, (int)$fromParent);
        }
        
        return $return;
    }

    private function getChildrenTree(array $resources, int $fromParent, $firstLoop = true): array
    {
        foreach($resources as $value){
            if($value['id'] == $fromParent) {
                return $value['children'];
            }
            if(!$firstLoop && $value['parentId'] == $fromParent) {
                if(isset($value['children'])) {
                    return $value['children'];
                }
                else{
                    return $value;
                }
            }
            if(($value['has_children'] > 0) && !empty($value['children'])) {
                $children = $this->getChildrenTree($value['children'], $fromParent, false);
                if($children) {
                    return $children;
                }
            }
        }
        
        
        return [];
    }

And callback for nodes with children:

    public function getChildren($parentId): array
    {
        return $this->getResourcesTree($this->facade->getResources([], "priority"), null, $parentId);
    }

Now the problem, what's wrong. When I open first level node (meaning from root to first level), every child nodes appear correctly. But, if this node has another children and I try to show them, page reload and all nodes are packed up. And also - when I successfully opened first level from root, same issue is when i want to click edit on this child node.

Do you have any idea, what's wrong with my code, or is it some issue of this library? Thanks a lot for any suggestions!

MikKuba avatar May 01 '24 09:05 MikKuba

Hi, not sure, if it´s connected-but I have just found kind of strange behavior of Tree View.

I have Status switch on every line - in root level, everything works, if I open children level and use the status switch, it looses connection to Presenter (I have grid in ocmponent), it runs the "statusChange" callback, but in it, I can´t check working Ajax. Calling $this->presenter->isAjax() returns false, while using status switch on root level, it returns true.

I have switchStatus method in baseGrid class (I have tons of grids and statusSwitch is always the same), but in few special cases, I´m overloading that general function, calling parent and adding some stuff after the base function and it won´t run that code as page reloads instead of redrawing single line via Ajax.

It kind of seems like your problem is the same - instead of Ajax opening, your page reloads and everything is packed again.

No idea tho...if problem is on our side, or on datagrid side. Could be easilly wrong implementation. Tree view demo on: https://examples.contributte.org/datagrid-skeleton/tree-view/ doesn´t work at all

darkWolf-PR avatar Aug 16 '24 19:08 darkWolf-PR

@MikKuba so, I´ve searched a bit more and found out updating Naja1 to Naja2 and adding this fix https://github.com/contributte/datagrid/pull/1035 to datagrid.js fixes my issue with Ajax.

dataGridLoad = function () {
	naja.load();
};

to:

dataGridLoad = function () {
	if (isNaja2()) {
		document.querySelectorAll('.datagrid .ajax').forEach((element) => {
			naja.uiHandler.bindUI(element);
		});
	} else {
		naja.load();
	}
};

darkWolf-PR avatar Aug 16 '24 21:08 darkWolf-PR

Hey @darkWolf-PR, I am not sure what you mean, can you open PR please?

f3l1x avatar Aug 19 '24 12:08 f3l1x

@f3l1x What you mean exactly? @MikKuba did not said which JS library is he using. I´ve found that the problem I´ve had with datagrid reloading whole page within TreeView instead of using ajax (which seems to be the same issue as he had) was connected to support of Naja 1 library (I had Naja 1.8.3) in Datagrid.

After checking other issues and pulls, I´ve found the one I´ve tried to link that suggests similar problem with Naja2 and fix for that, so I had nothing to loose, switched to latest Naja and added suggested change to datagrid.js.

That fixed me the reloading problem. So I guess it´s something related to released datagrid version and used Naja 1 version. I have no idea what, because I do not understand this JS at all... It still doesn´t work completely, it fails to redraw respected grid line after status switch.

Switching status in child node misses these two lines in ajax request(these are from root node status switch), no idea why: _datagrid_redrawItem_class "" _datagrid_redrawItem_id 7

Btw - that not working demo(tree view part) is already using the new version 7? As there is BS5 in assets. It´s impossible to open child rows there. Links from demo page have wrong urls too: See the code below 👇 or see GitHub

darkWolf-PR avatar Aug 20 '24 17:08 darkWolf-PR

Oh, I see now. I will try to fix demo. :-)

f3l1x avatar Aug 21 '24 08:08 f3l1x

@f3l1x it looks like treeView demo misses this Which, btw, is really awesome code, probably from Dibi?, which I keep failing to recreate in NetteDatabase.

darkWolf-PR avatar Aug 21 '24 16:08 darkWolf-PR