Hello everyone, would it be possible for the Tree component to have checkbox that when selecting a branch all your children also did? Would be to use it in the same way that Cuba Studio uses it. It would be fantastic to be able to use it also in the Tree Table component.
Greetings and thanks.
Hello, the best variant is to use WidgetsTree.
I’ll use entity Employee to show how to do it.
You have to create new view which includes chief and subordinates. Also you can setup entity instance name in entity editor.
After that you should create screen with HierarchicalDatasource and WidgetsTree, which is linked to the datasource:
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
caption="msg://browseCaption"
class="com.company.checkabletree.web.employee.EmployeeBrowse"
messagesPack="com.company.checkabletree.web.employee">
<dsContext>
<hierarchicalDatasource id="employeesDs"
class="com.company.checkabletree.entity.Employee"
hierarchyProperty="chief"
view="employee-view">
<query>
<![CDATA[select e from checkabletree$Employee e]]>
</query>
</hierarchicalDatasource>
</dsContext>
<layout>
<widgetsTree id="tree"
height="100%"
width="100%">
<items datasource="employeesDs"></items>
</widgetsTree>
</layout>
</window>
Next step is to setup WidgetBuilder to generate rows in WidgetsTree.
In screen controller you should inject:
- WidgetsTree
- HierarchicalDatasource
- ComponentsFactory
public class EmployeeBrowse extends AbstractLookup {
@Inject
private ComponentsFactory componentsFactory;
@Inject
private HierarchicalDatasource<Employee, UUID> employeesDs;
@Inject
private WidgetsTree<Employee> tree;
...
}
and create new Map to store Employees linked to the CheckBoxes:
private Map<Employee, CheckBox> employeeCheckBoxMap = new HashMap<>();
Let’s setup our WidgetBuilder in overrided init method of controller:
@Override
public void init(Map<String, Object> params) {
tree.setWidgetBuilder((datasource, itemId, leaf) -> {
final Employee employee = employeesDs.getItem((UUID) itemId);
if (employee == null)
return null;
CheckBox checkBox = (CheckBox) componentsFactory.createComponent(CheckBox.NAME);
// entity instance name will be shown to the right of checkbox
checkBox.setCaption(employee.getInstanceName());
checkBox.addValueChangeListener(e -> {
// update children
for (Employee subordinate : employee.getSubordinates()) {
updateRecursive(subordinate, (boolean) e.getValue());
}
});
employeeCheckBoxMap.put(employee, checkBox);
return checkBox;
});
}
private void updateRecursive(Employee employee, boolean checked) {
CheckBox checkBox = employeeCheckBoxMap.get(employee);
checkBox.setValue(checked);
for (Employee subordinate : employee.getSubordinates()) {
updateRecursive(subordinate, checked);
}
}
If you want to update parents you should use this code in CheckBox ValueChangeListener:
checkBox.addValueChangeListener(e -> {
Employee chief = employee.getChief();
if (chief != null) {
updateRecursive(chief, (boolean) e.getValue());
}
});
private void updateRecursive(Employee employee, boolean checked) {
CheckBox checkBox = employeeCheckBoxMap.get(employee);
checkBox.setValue(checked);
Employee chief = employee.getChief();
if (chief != null) {
updateRecursive(chief, checked);
}
}
And as result we will get a such screen:
Thanks for your answer.
Greetings.
Hi Daniil,
Could you share this sample project about WidgetsTree, please? Is it same usage in Cuba6.10?
Hello @anjingjing
Unfortunately I don’t have the project anymore. Please ask me questions if you’ll encounter problems.
Regards,
Daniil
Hi Daniil,
Could you help check this issue: How to use widgetsTree component - #4 от пользователя 624517928 - CUBA.Platform
The WidgetsTree seems has data in it, but not display correctly. We are using cuba6.10 and halo theme.
As I see the problem is solved. Am I right?
Yes, never mind