Hi Community,
I'm using SmartGWT LGPL 4.1. I'm having some issues trying to call updateCaches() on a filtered databound TreeGrid set up with keepParentsOnFilter flag on.
I've created a minimal showcase to reproduce the problem. The TreeGrid data is bound to a custom datasource that, for simplicity, returns the whole dataset in response to the first fetch operation; the real datasource is much more complex and calls server endpoints to retrieve and update the data.
I now decide to filter by "Name" column putting the filter "ch" so that both "Chuck" and "Charles" leaf nodes pass the filter. The parents are kept too thanks to the keepParentsOnFilter flag.
Finally, I have some external component that updates data server side. The datasource is informed of these changes and updates the TreeGrid through an updateCaches() call. I've mocked this behaviour with the Update button in my showcase: I'm updating the age information of nodes "Elvis" and "Chuck".
When clicking the button, the observed behaviour is that both updated nodes are removed from the filtered tree. Only removing the filter the updated nodes reappear.
What I've managed to understand by debugging is that, when the ResultTree is informed of the updated nodes, it does not keep into consideration the keepParentsOnFilter flag; as a consequence, when the "Elvis" folder is analyzed it does not pass the filter and is removed from the filtered tree along with its child "Chuck".
Is there something I am setting up or doing wrong? Thanks for any advice.
TreeDataSource.java
TreeGridExample.java
I'm using SmartGWT LGPL 4.1. I'm having some issues trying to call updateCaches() on a filtered databound TreeGrid set up with keepParentsOnFilter flag on.
I've created a minimal showcase to reproduce the problem. The TreeGrid data is bound to a custom datasource that, for simplicity, returns the whole dataset in response to the first fetch operation; the real datasource is much more complex and calls server endpoints to retrieve and update the data.
I now decide to filter by "Name" column putting the filter "ch" so that both "Chuck" and "Charles" leaf nodes pass the filter. The parents are kept too thanks to the keepParentsOnFilter flag.
Finally, I have some external component that updates data server side. The datasource is informed of these changes and updates the TreeGrid through an updateCaches() call. I've mocked this behaviour with the Update button in my showcase: I'm updating the age information of nodes "Elvis" and "Chuck".
When clicking the button, the observed behaviour is that both updated nodes are removed from the filtered tree. Only removing the filter the updated nodes reappear.
What I've managed to understand by debugging is that, when the ResultTree is informed of the updated nodes, it does not keep into consideration the keepParentsOnFilter flag; as a consequence, when the "Elvis" folder is analyzed it does not pass the filter and is removed from the filtered tree along with its child "Chuck".
Is there something I am setting up or doing wrong? Thanks for any advice.
TreeDataSource.java
Code:
import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import com.smartgwt.client.data.DSRequest; import com.smartgwt.client.data.DSResponse; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.data.fields.DataSourceIntegerField; import com.smartgwt.client.data.fields.DataSourceTextField; import com.smartgwt.client.types.CriteriaPolicy; import com.smartgwt.client.types.DSOperationType; import com.smartgwt.client.types.DSProtocol; import com.smartgwt.client.widgets.tree.TreeNode; public class TreeDataSource extends DataSource { private final Map<String, TreeNode> dataset = new HashMap<String, TreeNode>(); public TreeDataSource() { setClientOnly(true); setDataProtocol(DSProtocol.CLIENTCUSTOM); setCriteriaPolicy(CriteriaPolicy.DROPONCHANGE); DataSourceTextField idField = new DataSourceTextField("id"); idField.setPrimaryKey(true); idField.setHidden(true); DataSourceTextField parentIdField = new DataSourceTextField("parentId"); parentIdField.setForeignKey("id"); parentIdField.setHidden(true); DataSourceTextField nameField = new DataSourceTextField("name"); nameField.setCanFilter(true); DataSourceIntegerField valueField = new DataSourceIntegerField("age"); valueField.setCanFilter(true); setFields(idField, parentIdField, nameField, valueField); populateDataset(); } protected void populateDataset() { TreeNode johnNode = new TreeNode(); johnNode.setAttribute("id", "1"); johnNode.setAttribute("parentId", (String) null); johnNode.setAttribute("name", "John"); johnNode.setAttribute("age", 24); johnNode.setIsFolder(true); dataset.put("1", johnNode); TreeNode elvisNode = new TreeNode(); elvisNode.setAttribute("id", "2"); elvisNode.setAttribute("parentId", "1"); elvisNode.setAttribute("name", "Elvis"); elvisNode.setAttribute("age", 32); elvisNode.setIsFolder(true); dataset.put("2", elvisNode); TreeNode chuckNode = new TreeNode(); chuckNode.setAttribute("id", "3"); chuckNode.setAttribute("parentId", "2"); chuckNode.setAttribute("name", "Chuck"); chuckNode.setAttribute("age", 28); chuckNode.setIsFolder(false); dataset.put("3", chuckNode); TreeNode bartNode = new TreeNode(); bartNode.setAttribute("id", "4"); bartNode.setAttribute("parentId", "1"); bartNode.setAttribute("name", "Bart"); bartNode.setAttribute("age", 55); bartNode.setIsFolder(true); dataset.put("4", bartNode); TreeNode charlesNode = new TreeNode(); charlesNode.setAttribute("id", "5"); charlesNode.setAttribute("parentId", "4"); charlesNode.setAttribute("name", "Charles"); charlesNode.setAttribute("age", 44); charlesNode.setIsFolder(false); dataset.put("5", charlesNode); TreeNode ericNode = new TreeNode(); ericNode.setAttribute("id", "6"); ericNode.setAttribute("parentId", "1"); ericNode.setAttribute("name", "Eric"); ericNode.setAttribute("age", 25); ericNode.setIsFolder(true); dataset.put("6", ericNode); TreeNode fordNode = new TreeNode(); fordNode.setAttribute("id", "7"); fordNode.setAttribute("parentId", "6"); fordNode.setAttribute("name", "Ford"); fordNode.setAttribute("age", 18); fordNode.setIsFolder(false); dataset.put("7", fordNode); } @Override protected Object transformRequest(final DSRequest dsRequest) { if (dsRequest.getOperationType() == DSOperationType.FETCH) { executeFetch(dsRequest); } else { throw new RuntimeException("Not supported operation type " + dsRequest.getOperationType().toString()); } return dsRequest.getData(); } protected void executeFetch(final DSRequest dsRequest) { String requestId = dsRequest.getRequestId(); Collection<TreeNode> nodes = dataset.values(); DSResponse response = new DSResponse(); response.setData(nodes.toArray(new TreeNode[nodes.size()])); processResponse(requestId, response); } public void externalUpdate() { TreeNode elvisNode = dataset.get("2"); elvisNode.setAttribute("age", 33); TreeNode chuckNode = dataset.get("3"); chuckNode.setAttribute("age", 29); List<TreeNode> nodes = new ArrayList<TreeNode>(2); nodes.add(elvisNode); nodes.add(chuckNode); DSResponse response = new DSResponse(); response.setData(nodes.toArray(new TreeNode[nodes.size()])); response.setOperationType(DSOperationType.UPDATE); updateCaches(response); } }
Code:
import com.google.gwt.core.client.EntryPoint; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeGridField; public class TreeGridExample implements EntryPoint { @Override public void onModuleLoad() { final TreeDataSource treeDataSource = new TreeDataSource(); TreeGrid personTree = new TreeGrid(); personTree.setWidth(300); personTree.setHeight(400); personTree.setDataSource(treeDataSource); personTree.setAutoFetchData(true); personTree.setShowFilterEditor(true); personTree.setKeepParentsOnFilter(true); personTree.setFilterOnKeypress(true); TreeGridField nameField = new TreeGridField("name", "Name", 200); TreeGridField ageField = new TreeGridField("age", "Age", 100); personTree.setFields(nameField, ageField); IButton button = new IButton("Update"); button.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { treeDataSource.externalUpdate(); } }); button.setLayoutAlign(Alignment.CENTER); VLayout mainView = new VLayout(10); mainView.setHeight100(); mainView.setWidth100(); mainView.addMember(personTree); mainView.addMember(button); mainView.draw(); } }
Comment