HierarchyProperty of WebTreeDataGrid

Hi,

I’m in process of creating a Custom Action to create Child Row which will automatically set the selected record in the TreeDataGrid as parent of new record.

I got stuck in accessing the hierachy property of TreeDataGrid. I can’t find a getter method of it. Only I could see is getter to HierarchyColumn which is different altogether.

Below is my current code which producing NPE because i have used hierarchyColumn getter.

MetaPropertyPath hierarchyProperty = ((WebTreeDataGrid) target).getHierarchyColumn().getPropertyPath();
        if(hierarchyProperty != null)
            e.setValueEx(hierarchyProperty.toPathString(), target.getSingleSelected());

Kindly help me accessing hierachyProperty value.

Thanks,
Hari

Hello @harikrishnadhas.k1,

To access hierarchyProperty value you could use the following snippet:

if (target instanceof TreeDataGrid) {
    DataGrid.Column hierarchyColumn = ((TreeDataGrid<?>) target).getHierarchyColumn();
    if (hierarchyColumn != null) {
        MetaPropertyPath metaPropertyPath = hierarchyColumn.getPropertyPath();
        String id = hierarchyColumn.getId();
    }
}

Regards,
Gleb

Hello @durygin,

The hierarchyColumn value is returning as null. The TreeDataGrid has hierarchyProperty value set.

My previous code had similar approach and problem with that code too was the same.

Thanks,
Hari

@harikrishnadhas.k1 At what point do you want to access the hierarchyColumn?

@durygin

I’m using this in initializer.

@Override
    public void setInitializer(Consumer<E> initializer) {
        super.setInitializer(initializer);
        initializer.andThen(this::initParent);
    }

    private void initParent(E e){
        DataGrid.Column hierarchyColumn = ((TreeDataGrid<?>) target).getHierarchyColumn();

        if(hierarchyColumn != null){
            MetaPropertyPath hierarchyProperty = hierarchyColumn.getPropertyPath();
            if(hierarchyProperty != null)
                e.setValueEx(hierarchyProperty.toPathString(), target.getSingleSelected());
        }
    }

Hello @harikrishnadhas.k1,

Why would you want to add your own logic to the CreateAction#setInitializer() method? Your code will not run unless the user himself specifies an initializer in his code.

Also, the initializer is set during the screen loading process, and not when you click on the button that triggers the action. You can move your code to CreateAction#execute() method and then you will be able to access the hierarchyProperty.

Regards,
Gleb

OK. I will try and let you know the result.

I’m creating a Child Action, which will create a Child record for the selected record in the TreeDataGrid. So I need to set the parent property attribute of the new entity record. Actually the initializer is getting called but the hierarchyColumn is always null.

But I will try with execute method and see if hierarcyColumn would work there

I tried adding the same code in execute method, still I get hierarchyColumn as null only.

image

Below is the Datagrid code.

 <treeDataGrid id="tasksTable"
                              width="100%"
                              dataContainer="taskPlanDc"
                              hierarchyProperty="parentTask">

Should I set hierarchyColumn property of treeDataGrid?

Does hierarchyProperty and hierarchyColumn are same?

If so why 2 different attributes provided for them in XML?

I guess hierarchyColumn is something only for display, that where the hierarchy dropdown icon will display however hierarchyProperty is something basic to define the hierarchy of the data. So get property path of hierarchyColumn might not help me in this case.

Can I access the hierarchyProperty directly?

@durygin,

Any help would be appreciated to access the hierarchyProperty.

Thanks,
Hari

@harikrishnadhas.k1,

I’ve created a test project with ChildAction that works as you described above, but only with TreeTable:

TreeTable

        <treeTable id="tasksTable"
                   width="100%"
                   dataContainer="tasksDc"
                   hierarchyProperty="parentTask">
            <actions>
                <action id="createChild" type="createChild"/>
                <action id="edit" type="edit"/>
                <action id="remove" type="remove"/>
            </actions>
            <columns>
                <column id="name"/>
                <column id="dueDate"/>
                <column id="parentTask"/>
            </columns>
            <rowsCount/>
            <buttonsPanel id="buttonsPanel"
                          alwaysVisible="true">
                <button id="createChildBtn" action="tasksTable.createChild"/>
                <button id="editBtn" action="tasksTable.edit"/>
                <button id="removeBtn" action="tasksTable.remove"/>
            </buttonsPanel>
        </treeTable>

ChildCreateAction

@ActionType(CreateChildAction.ID)
public class CreateChildAction<E extends Entity> extends CreateAction<E> {

    public static final String ID = "createChild";

    public CreateChildAction() {
        this(ID);
    }

    public CreateChildAction(String id) {
        super(id);
        this.primary = true;
    }

    @Inject
    protected void setMessages(Messages messages) {
        this.caption = messages.getMainMessage("actions.CreateChild");
    }

    @SuppressWarnings({"ConstantConditions", "rawtypes", "unchecked"})
    @Override
    public void execute() {
        if (target == null) {
            throw new IllegalStateException("CreateChildAction target is not set");
        }

        if (!(target.getItems() instanceof EntityDataUnit)) {
            throw new IllegalStateException("CreateChildAction target items is null or does not implement EntityDataUnit");
        }

        MetaClass metaClass = ((EntityDataUnit) target.getItems()).getEntityMetaClass();
        if (metaClass == null) {
            throw new IllegalStateException("Target is not bound to entity");
        }

        EditorBuilder builder = screenBuilders.editor(target);

        if (newEntitySupplier != null) {
            E entity = newEntitySupplier.get();
            builder = builder.newEntity(entity);
        } else {
            builder = builder.newEntity();
        }

        if (initializer != null) {
            builder = builder.withInitializer(initializer);
        } else {
            builder = builder.withInitializer(getDefaultInitializer());
        }

        builder = screenInitializer.initBuilder(builder);

        if (transformation != null) {
            builder.withTransformation(transformation);
        }

        Screen editor = builder.build();

        if (afterCommitHandler != null) {
            editor.addAfterCloseListener(afterCloseEvent -> {
                CloseAction closeAction = afterCloseEvent.getCloseAction();
                if (closeAction.equals(WINDOW_COMMIT_AND_CLOSE_ACTION)) {
                    Entity committedEntity = ((EditorScreen) editor).getEditedEntity();
                    afterCommitHandler.accept((E) committedEntity);
                }
            });
        }

        screenInitializer.initScreen(editor);

        editor.show();
    }

    @SuppressWarnings({"unchecked", "ConstantConditions"})
    protected Consumer<E> getDefaultInitializer() {
        return (entity) -> {
            if (target instanceof TreeTable
                    && target.getItems() instanceof TreeTableItems
                    && ((TreeTableItems<E>) target.getItems()).getHierarchyPropertyName() != null) {
                String hierarchyPropertyName = ((TreeTableItems<E>) target.getItems()).getHierarchyPropertyName();
                entity.setValue(hierarchyPropertyName, target.getSingleSelected());
            }
        };
    }
}

TreeDataGrid

The hierarchyColumn is responsible for which column will be the main one when displaying hierarchical data.

Unfortunately, ContainerTreeDataGridItems class does not have getter for hierarchyProperty field. I have created an issue in Github to add a getter for a hierarchyProperty field.

Regards,
Gleb

Thanks @durygin. I will change my TreeDataGrid to TreeTable. Once you fix the bug, I can change it back to TreeDataGrid.