sp-dev-fx-controls-react
sp-dev-fx-controls-react copied to clipboard
TreeView - dynamic adding children, nodes always expanded
Category
-
[ ] Enhancement
-
[ ] Bug
-
[x] Question
Version
Please specify what version of the library you are using: [1.19.0 ]
If I'm using the onExpandCollapse prop to dynamically add ITreeItem children to a node when it's expanded, then each child ITreeItem is added in an "expanded" state, so to drill further down, you need to collapse then expand in order to correctly show children.
Is there any way to add an ITreeItem with an empty children array, such that the new child is a collapsed state so that the new child item can be expanded to further retrieve children dynamically.
Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.
I experience the same behavior.
@jimmywim will it be possible to you share your code?
We are also trying to add children nodes on select of ITreeItem.
Below is our code of TreeView control.
<TreeView items={this.state.TreeLinks} defaultExpanded={false} selectionMode={TreeViewSelectionMode.Single} selectChildrenIfParentSelected={true} showCheckboxes={true} treeItemActionsDisplayMode={TreeItemActionsDisplayMode.Buttons} onSelect={this.onTreeItemSelect} onExpandCollapse={this.onTreeItemExpandCollapse} onRenderItem={this.renderCustomTreeItem} />
We are setting state value "TreeLinks" which is an array of type ITreeItem. When we click on any node, onSelect action get triigred and in that action we are not able to read state it shows undefined.
Below s code of onSelect action.
private onTreeItemSelect(items: ITreeItem[]) { console.log("Items selected: ", items); var someProperty = { ...this.state }; console.log(JSON.stringify(someProperty)); }
@Bhushan12986 If your state is null you need to change onTreeItemSelect to be an arrow function..
private onTreeItemSelect = (items: ITreeItem[]) => {
console.log("Items selected: ", items);
var someProperty = { ...this.state };
console.log(JSON.stringify(someProperty));
}
I decided to revisit this. I managed to get around the behaviour of the "expanded" state on adding new items with the prop
defaultExpandedChildren={false}
on the TreeView control. However, you still need to "expand" items twice before they display. The first one appears to fetch the children and add them to the children, but it's the second click that displays them.
after adding treearr.push(tree); in Else part the child nodes are binding. Expand and collapse are not working using Node-version v12.18.0 version
Please suggest on this below is the code
whole code is as below
import * as React from 'react'; import styles from './SpfxPnpTreeview.module.scss'; import { ISpfxPnpTreeviewProps } from './ISpfxPnpTreeviewProps'; import { ISpfxPnpTreeviewState } from './ISpfxPnpTreeviewState'; import { TreeView, ITreeItem, TreeViewSelectionMode, TreeItemActionsDisplayMode } from "@pnp/spfx-controls-react/lib/TreeView"; import { autobind } from 'office-ui-fabric-react/lib/Utilities';
import { sp } from "@pnp/sp"; import "@pnp/sp/webs"; import "@pnp/sp/lists"; import "@pnp/sp/items";
export default class SpfxPnpTreeview extends React.Component<ISpfxPnpTreeviewProps, ISpfxPnpTreeviewState> { constructor(props: ISpfxPnpTreeviewProps) { super(props); sp.setup({ spfxContext: this.props.context }); this.state = { TreeLinks: [] } this._getLinks(); }
private async _getLinks() { const allItems: any[] = await sp.web.lists.getByTitle("TreeLinks").items.getAll(); var treearr: ITreeItem[] = []; allItems.forEach(function (v, i) {
please suggest
I decided to revisit this. I managed to get around the behaviour of the "expanded" state on adding new items with the prop
defaultExpandedChildren={false}on the
TreeViewcontrol. However, you still need to "expand" items twice before they display. The first one appears to fetch the children and add them to the children, but it's the second click that displays them.
+1 I'm experiencing exactly the same issue.
Is there a fix for this solution already? If so, can someone please share a solution? Thanks!
Hello @jimmywim,
I'm not sure if I understand your need, but I've tried something with latest version (3.15.0), like this:
private treeitems = [
// ...
{
key: "R3",
label: "Root 3",
children: [
{
key: "12",
label: "Parent 9"
},
{
key: "13",
label: "Parent 10",
children: [
{
key: "gc3",
label: "Child of Parent 10",
children: [
{
key: "ggc1",
label: "Grandchild of Parent 10"
}
]
},
]
},
{
key: "14",
label: "Parent 11"
},
{
key: "15",
label: "Parent 12"
}
]
}
];
public render() {
return (
<TreeView items={this.treeitems}
defaultExpanded={false}
selectionMode={TreeViewSelectionMode.Multiple}
showCheckboxes={true}
treeItemActionsDisplayMode={TreeItemActionsDisplayMode.ContextualMenu}
onExpandCollapse={this.onExpandCollapseTree}
defaultExpandedChildren={false}
defaultExpandedKeys={this.state.treeViewSelectedKeys}
theme={this.props.themeVariant}
/>);
}
private onExpandCollapseTree(item: ITreeItem, isExpanded: boolean) {
console.log((isExpanded ? "item expanded: " : "item collapsed: ") + item);
if (item.key ==="R3" && isExpanded) {
item.children.push(...[{ key: "R1C3", label: "R1C3", children: [
{key: "R1C3C1", label: "R1C3C1", children: []}
]}]);
}
}
Which behaves like this:
Is it something like this you're trying to achieve? Of course, this needs to have the defaultExpandedChildren prop set to false first.
@michaelmaillot It's been a while, in fact, it's been that long this may have already been fixed, but basically I don't (or didn't) have the full structure upfront. I need to dynamically add the children when a node is expanded because I need to fetch them from a remote API.
So I think that the example above addresses your need.
If so, can I close this one or would you like to give a try first?
You can likely close this. I can't remember which project this was on (as it was 3 years ago) - but if the tree re-renders sucessfully when adding to children then this should work also in an async method.
I'm spoken a bit quickly, sorry. I can repro re-rendering issue when querying an API. This needs a bit of investigation in order to understand why does it behave like this and how could this be improved.
Hi! I also having hard times populating the children dynamically. I understood that if I update the items (I put it into the state, and update the state when loading is done) the TreeView gets updated (quite correctly), but my problem is that because of some reason, supplying a function to the onExpandCollapse, the item will not get expanded. So, it stays there collapsed, and I do not know a way to programmatically expand it after I received the new items. Just... isn't there a way to expand an item programmatically? That would solve this problem for me. Thanks!