Skip to content

PickTree

Available since v3.0.1

PickTree is a component that allows to select a value from Popup list of entities

Tips

Use if user needs to open a detailed view of related entities. Feel free to use this field type for large entities of any size (only one page is loaded in memory)

Basics

Live Sample · GitHub

How does it look?

img_list.gif

img_info.png

img_form.gif

How to add?

Info

The popup is a tree: the business component of the popup must return parentId (filterable, null for the roots) and isLeaf, both declared as hidden fields of the popup widget. The tree settings are described in options.tree.

Example
  • Step 1. Popup

    In the following example, MyEntity entity has a OneToOne/ManyToOne reference to the MyEntityPick entity. Link is made by id, e.g. MyEntity.customFieldId = MyEntityPick.id. Also, is this example we will use one additional field MyEntityPick.customField, that will be shown on MyEntity widget

    • Step 1.1 Add String additional field to corresponding BaseEntity.

      @Entity
      @Getter
      @Setter
      @NoArgsConstructor
      public class MyEntityPick extends BaseEntity {
      
          @Column
          private String customField;
      
          @Column
          private Long parentId;
      
          @OneToMany(mappedBy = "parentId", fetch = FetchType.LAZY)
          private List<MyEntityPick> children = new ArrayList<>();
      
      }
      

    • Step 1.2 Add String additional field to corresponding DataResponseDTO.

      @Getter
      @Setter
      @NoArgsConstructor
      public class MyEntityPickDTO extends DataResponseDTO {
      
          @SearchParameter(name = "parentId", provider = LongValueProvider.class)
          private Long parentId;
      
          private Boolean isLeaf;
      
          @SearchParameter(name = "customField")
          private String customField;
      
          public MyEntityPickDTO(MyEntityPick entity) {
              this.id = entity.getId().toString();
              this.parentId = entity.getParentId();
              this.isLeaf = entity.getChildren().isEmpty();
              this.customField = entity.getCustomField();
          }
      
      }
      
    • Step 1.3 Create Popup List .widget.json.

      {
        "title": "myEntityPickTreePopup Title",
        "name": "myEntityPickTreePopup",
        "type": "PickTreePopup",
        "bc": "myEntityPickTreePopup",
        "fields": [
          {
            "title": "Custom Field",
            "key": "customField",
            "type": "input"
          },
          {
            "title": "id",
            "key": "id",
            "type": "text"
          },
          {
            "title": "Parent Id",
            "key": "parentId",
            "type": "hidden"
          },
          {
            "title": "Is Leaf",
            "key": "isLeaf",
            "type": "hidden"
          }
        ]
      }
      

    • Step 1.4 Add fields.setEnabled to corresponding FieldMetaBuilder.

          @Override
          public void buildIndependentMeta(FieldsMeta<MyEntityPickDTO> fields, InnerBcDescription bcDescription,
                                           Long parentId) {
              fields.enableFilter(MyEntityPickDTO_.parentId);
              fields.enableFilter(MyEntityPickDTO_.customField);
              fields.enableSort(MyEntityPickDTO_.customField);
              fields.enableSort(MyEntityPickDTO_.id);
          }
      

  • Step 2 Add Popup to .view.json.

    {
      "name": "myexamplelist",
      "title": "My example List",
      "url": "/screen/myexample/view/myexamplelist",
      "template": "DashboardView",
      "widgets": [
        {
          "widgetName": "myEntityPickTreePopup",
          "position": 20,
          "gridWidth": 12
        },
        {
          "widgetName": "SecondLevelMenu",
          "position": 0,
          "gridWidth": 24
        },
        {
          "widgetName": "MyExampleList",
          "position": 20,
          "gridWidth": 12
        }
      ],
      "rolesAllowed": [
        "CXBOX_USER"
      ]
    }
    
    {
      "name": "myexampleform",
      "title": "My Example Form",
      "template": "DashboardView",
      "url": "/screen/myexample/view/myexampleform",
      "widgets": [
        {
          "widgetName": "myEntityPickTreePopup",
          "position": 20,
          "gridWidth": 12
        },
        {
          "widgetName": "SecondLevelMenu",
          "position": 0,
          "gridWidth": 24
        },
        {
          "widgetName": "MyExampleForm",
          "position": 20,
          "gridWidth": 12
        }
      ],
      "rolesAllowed": [
        "CXBOX_USER"
      ]
    }
    
  • Step3 Add MyEntityPick field to corresponding BaseEntity.

        @Entity
        @Getter
        @Setter
        @NoArgsConstructor
        public class MyEntity extends BaseEntity {
    
            @JoinColumn(name = "CUSTOM_FIELD_ID")
            @ManyToOne
            private MyEntityPick customFieldEntity;
    
        }
    

  • Step4 Add two fields (for id and for additional field) to corresponding DataResponseDTO.

    @Getter
    @Setter
    @NoArgsConstructor
    public class MyExampleDTO extends DataResponseDTO {
    
        @SearchParameter(name = "customFieldEntity.customField")
        private String customField;
    
        @SearchParameter(name = "customFieldEntity.id", provider = LongValueProvider.class)
        private Long customFieldId;
    
        public MyExampleDTO(MyEntity entity) {
            this.id = entity.getId().toString();
            this.customFieldId = Optional.ofNullable(entity.getCustomFieldEntity())
                    .map(e -> e.getId())
                    .orElse(null);
            this.customField = Optional.ofNullable(entity.getCustomFieldEntity())
                    .map(e -> e.getCustomField())
                    .orElse(null);
        }
    
    }
    

  • Step5 Add bc myEntityPickTreePopup to corresponding EnumBcIdentifier.

    Info

    myEntityPickTreePopup business component needs to be a child of the business component from which the popup window is invoked.

        myExampleBc(MyExampleService.class),
        myEntityPickTreePopup(myExampleBc, MyEntityPickPickTreeService.class);
    

Step6 Add popupBcName and pickMap to .widget.json. pickMap - maping for field Picktree to MyEntity

pickMap defines the mapping between fields of the main BC (the primary form) and the popup BC from which the user selects a record.

  • Left side — the field in the main BC where the value should be written.
  • Right side — the field in the popup BC from which the value is taken when the user selects a row.
{
  "name": "MyExampleList",
  "title": "List title",
  "type": "List",
  "bc": "myExampleBc",
  "fields": [
    {
      "title": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customFieldId": "id",
        "customField": "customField"
      }
    }
  ]
}

Step6 Add popupBcName and pickMap to .widget.json. pickMap - maping for field Picktree to MyEntity

pickMap defines the mapping between fields of the main BC (the primary form) and the popup BC from which the user selects a record.

  • Left side — the field in the main BC where the value should be written.
  • Right side — the field in the popup BC from which the value is taken when the user selects a row.
{
  "name": "MyExampleInfo",
  "title": "Info title",
  "type": "Info",
  "bc": "myExampleBc",
  "fields": [
    {
      "label": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customFieldId": "id",
        "customField": "customField"
      }
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 12
            }
          ]
        }
      ]
    }
  }
}

Step6 Add popupBcName and pickMap to .widget.json. pickMap - maping for field Picktree to MyEntity

pickMap defines the mapping between fields of the main BC (the primary form) and the popup BC from which the user selects a record.

  • Left side — the field in the main BC where the value should be written.
  • Right side — the field in the popup BC from which the value is taken when the user selects a row.

When the user selects a record in the popup, take the value from the right-side field and place it into the left-side field.

{
  "name": "MyExampleForm",
  "title": "Form title",
  "type": "Form",
  "bc": "myExampleBc",
  "fields": [
    {
      "label": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customField": "customField",
        "customFieldId": "id"
      }
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 12
            }
          ]
        }
      ]
    }
  }
}

Live Sample · GitHub

Placeholder

Live Sample · GitHub

Placeholder allows you to provide a concise hint, guiding users on the expected value. This hint is displayed before any user input. It can be calculated based on business logic of application. It is shown for a Readonly field as well.

How does it look?

img_plchldr_list.png

not applicable

img_plchldr_form.png

How to add?

Example

Add fields.setPlaceholder to corresponding FieldMetaBuilder.

    @Override
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customFieldId);
        fields.setEnabled(MyExampleDTO_.customField);
        fields.setPlaceholder(MyExampleDTO_.customField, "Placeholder text");
        fields.setPlaceholder(MyExampleDTO_.customFieldRO, "Placeholder text");
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Color

Color allows you to specify a field color. It can be calculated based on business logic of application

Calculated color

Live Sample · GitHub

Constant color

Live Sample · GitHub

How does it look?

img_color_list.png

img_color_info.png

not applicable

How to add?

Example

Step 1 Add custom field for color to corresponding DataResponseDTO. The field can contain a HEX color or be null.

@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {

    @SearchParameter(name = "customFieldEntity.customField")
    private String customField;

    @SearchParameter(name = "customFieldEntity.id", provider = LongValueProvider.class)
    private Long customFieldId;

    private String customFieldColor;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customFieldColor = "#edaa";
        this.customFieldId = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getId())
                .orElse(null);
        this.customField = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getCustomField())
                .orElse(null);
    }

}

Step 2 Add "bgColorKey" : custom field for color to .widget.json.

{
  "name": "MyExampleList",
  "title": "List title",
  "type": "List",
  "bc": "myExampleBc",
  "fields": [
    {
      "title": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customFieldId": "id",
        "customField": "customField"
      },
      "bgColorKey": "customFieldColor"
    }
  ]
}

Step 2 Add "bgColorKey" : custom field for color to .widget.json.

{
  "name": "MyExampleInfo",
  "title": "Info title",
  "type": "Info",
  "bc": "myExampleBc",
  "fields": [
    {
      "label": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customField": "customField",
        "customFieldId": "id"
      },
      "bgColorKey": "customFieldColor"
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 12
            }
          ]
        }
      ]
    }
  }
}

not applicable

Live Sample · GitHub

Add "bgColor" : HEX color to .widget.json.

{
  "name": "MyExampleList",
  "title": "List title",
  "type": "List",
  "bc": "myExampleBc",
  "fields": [
    {
      "title": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customFieldId": "id",
        "customField": "customField"
      },
      "bgColor": "#edaa"
    }
  ]
}

Add "bgColor" : HEX color to .widget.json.

{
  "name": "MyExampleInfo",
  "title": "Info title",
  "type": "Info",
  "bc": "myExampleBc",
  "fields": [
    {
      "label": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customField": "customField",
        "customFieldId": "id"
      },
      "bgColor": "#edaa"
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 12
            }
          ]
        }
      ]
    }
  }
}

not applicable

Live Sample · GitHub

Readonly/Editable

Readonly/Editable indicates whether the field can be edited or not. It can be calculated based on business logic of application

Editable Live Sample · GitHub

Readonly Live Sample · GitHub

How does it look?

img_list.gif

not applicable

img_form.gif

img_ro_list.png

img_ro_info.png

img_ro_form.png

How to add?

Example

Step1 Add mapping DTO->entity to corresponding VersionAwareResponseService.

    @Override
    protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
                                                              BusinessComponent bc) {
        if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
            entity.setCustomFieldEntity(data.getCustomFieldId() != null
                    ? entityManager.getReference(MyEntityPick.class, data.getCustomFieldId())
                    : null);
        }

        return new ActionResultDTO<>(entityToDto(bc, entity));
    }
Step2 Add fields.setEnabled to corresponding FieldMetaBuilder.
    @Override
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customFieldId);
        fields.setEnabled(MyExampleDTO_.customField);
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Option 1 Enabled by default.

    @Override
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {

    }
Option 2 Not recommended. Property fields.setDisabled() overrides the enabled field if you use after property fields.setEnabled.

Works for List.

Works for Info.

Works for Form.

Live Sample · GitHub

Filtering

Live Sample · GitHub

Filtering allows you to search data based on criteria. The column filter has two modes, applying one of them clears the other:

  • By text: type a part of the value and press Apply. Search uses contains operator for the field referenced in key.
  • By records: click ... and choose the records in the popup. Search uses in operator which compares ids (the field mapped to id in pickMap). While this filter is applied, ... shows the number of chosen records.

Tips

Pop up widget for filtration is auto-generated based on widget for field editing (e.g. same fields, same filters and so on will be on both widgets). Optionally - separate widget for filtration can still be provided

How does it look?

img_filtr_list.gif

img_filtr_popup_list.gif

not applicable

not applicable

How to add?

Example

Step 1 Add @SearchParameter to corresponding DataResponseDTO. (Advanced customization SearchParameter)

@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {

    @SearchParameter(name = "customFieldEntity.customField")
    private String customField;

    @SearchParameter(name = "customFieldEntity.id", provider = LongValueProvider.class)
    private Long customFieldId;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customFieldId = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getId())
                .orElse(null);
        this.customField = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getCustomField())
                .orElse(null);
    }

}
Step 2 Add fields.enableFilter to corresponding FieldMetaBuilder.
    @Override
    public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                     Long parentId) {
        if (configuration.getForceActiveEnabled()) {
            fields.setForceActive(MyExampleDTO_.customField);
        }
        fields.enableFilter(MyExampleDTO_.customField);
        fields.enableSort(MyExampleDTO_.customField);
    }

not applicable

not applicable

Live Sample · GitHub

Drilldown

Live Sample · GitHub

DrillDown allows you to navigate to another view by simply tapping on it. Target view and other drill-down parts can be calculated based on business logic of application

Also, it optionally allows you to filter data on target view before it will be opened see more DrillDown

How does it look?

img_drilldown_list.png

img_drilldown_info.png

not applicable

How to add?

Example

Option 1

Step 1 Add fields.setDrilldown to corresponding FieldMetaBuilder.

    @Override
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customFieldId);
        fields.setEnabled(MyExampleDTO_.customField);
        fields.setDrilldown(
                MyExampleDTO_.customField,
                DrillDownType.INNER,
                "/screen/myexample/view/myexampleform/" + PlatformMyExampleController.myExampleBc + "/" + id
        );
    }

Step 2 Add "drillDown": "true" to .widget.json.

{
  "name": "MyExampleList",
  "title": "List title",
  "type": "List",
  "bc": "myExampleBc",
  "fields": [
    {
      "title": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customFieldId": "id",
        "customField": "customField"
      },
      "drillDown": "true"
    }
  ]
}
Option 2 Add "drillDownKey" : custom field to .widget.json. See more Drilldown

Step 2 Add "drillDown": "true" to .widget.json.

{
  "name": "MyExampleInfo",
  "title": "Info title",
  "type": "Info",
  "bc": "myExampleBc",
  "fields": [
    {
      "label": "Custom Field",
      "key": "customField",
      "type": "pickTree",
      "popupBcName": "myEntityPickTreePopup",
      "pickMap": {
        "customField": "customField",
        "customFieldId": "id"
      },
      "drillDown": "true"
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 12
            }
          ]
        }
      ]
    }
  }
}
Option 2 Add "drillDownKey" : custom field to .widget.json. See more Drilldown

not applicable

Live Sample · GitHub

Advanced customization

Validation

Validation allows you to check any business rules for user-entered value. There are types of validation:

1) Exception:Displays a message to notify users about technical or business errors.

Business Exception: Live Sample · GitHub

Runtime Exception: Live Sample · GitHub

2) Confirm: Presents a dialog with an optional message, requiring user confirmation or cancellation before proceeding.

Live Sample · GitHub

3) Field level validation: shows error next to all fields, that validation failed for

Option 1: Live Sample · GitHub

Option 2: Live Sample · GitHub

How does it look?

img_business_error.png

img_runtime_error.png

confirm_form.png

img_javax_stat_list.png

not applicable

img_business_error.png

img_runtime_error.png

confirm_form.png

img_javax_stat_form.png

How to add?

Example

BusinessException describes an error within a business process.

Add BusinessException to corresponding VersionAwareResponseService.

    @Override
    protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
                                                              BusinessComponent bc) {
        if (StringUtils.isNotEmpty(data.getCustomField())
                && !String.valueOf(data.getCustomField()).matches("[A-Za-z]+")
        ) {
            throw new BusinessException().addPopup(ONLY_LETTER);
        }
        if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
            entity.setCustomFieldEntity(data.getCustomFieldId() != null
                    ? entityManager.getReference(MyEntityPick.class, data.getCustomFieldId())
                    : null);
        }
        return new ActionResultDTO<>(entityToDto(bc, entity));
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

RuntimeException describes technical error within a business process.

Add RuntimeException to corresponding VersionAwareResponseService.

    @Override
    protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
                                                              BusinessComponent bc) {
        if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
            entity.setCustomFieldEntity(data.getCustomFieldId() != null
                    ? entityManager.getReference(MyEntityPick.class, data.getCustomFieldId())
                    : null);
            try {
                //call custom function
                throw new Exception("Error");
            } catch (Exception e) {
                throw new RuntimeException("An unexpected error has occurred.");
            }
        }

        return new ActionResultDTO<>(entityToDto(bc, entity));
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Add PreAction.confirm to corresponding VersionAwareResponseService.

    @Override
    public Actions<MyExampleDTO> getActions() {
        return Actions.<MyExampleDTO>builder()
                .action(act -> act
                        .action("save", "save")
                        .withPreAction(PreAction.confirm(cf -> cf
                                .text("You want to save the value?")
                        )))
                .build();
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Add javax.validation to corresponding DataResponseDTO.

Use if:

Requires a simple fields check (javax validation)

@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {

    @SearchParameter(name = "customFieldEntity.customField")
    @Pattern(regexp = "[A-Za-z]+", message = ONLY_LETTER)
    private String customField;

    @SearchParameter(name = "customFieldEntity.id", provider = LongValueProvider.class)
    private Long customFieldId;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customFieldId = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getId())
                .orElse(null);
        this.customField = Optional.ofNullable(entity.getCustomFieldEntity())
                .map(e -> e.getCustomField())
                .orElse(null);
    }

}

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Create custom service for business logic check.

Use if:

Business logic check required for fields

Step 1 Create custom method for check.

    private void validateFields(BusinessComponent bc, MyExampleDTO dto) {
        BusinessError.Entity entity = new BusinessError.Entity(bc);
        if (!String.valueOf(dto.getCustomField()).matches("[A-Za-z]+")) {
            entity.addField(MyExampleDTO_.customField.getName(), "The field 'customField' can contain only letters.");
        }
        if (!String.valueOf(dto.getCustomFieldAdditional()).matches("[A-Za-z]+")) {
            entity.addField(
                    MyExampleDTO_.customFieldAdditional.getName(),
                    "The field 'customFieldAdditional' can contain only letters."
            );
        }
        if (!entity.getFields().isEmpty()) {
            throw new BusinessException().setEntity(entity);
        }
    }
Step 2 Add custom method for check to corresponding VersionAwareResponseService.
    @Override
    protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
                                                              BusinessComponent bc) {
        validateFields(bc, data);
        if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
            entity.setCustomFieldEntity(data.getCustomFieldId() != null
                    ? entityManager.getReference(MyEntityPick.class, data.getCustomFieldId())
                    : null);
        }

        return new ActionResultDTO<>(entityToDto(bc, entity));
    }

Live Sample · GitHub

Sorting

Live Sample · GitHub

Sorting allows you to sort data in ascending or descending order. Sort by value join field.

How does it look?

img_sort_list.png

not applicable

not applicable

How to add?

Example

see more Sorting

Step 1 Add fields.enableSort to corresponding FieldMetaBuilder.

    @Override
    public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                     Long parentId) {
        if (configuration.getForceActiveEnabled()) {
            fields.setForceActive(MyExampleDTO_.customField);
        }
        fields.enableFilter(MyExampleDTO_.customField);
        fields.enableSort(MyExampleDTO_.customField);
        fields.enableSort(MyExampleDTO_.customFieldId);
    }
Live Sample · GitHub

not applicable

not applicable

Required

Live Sample · GitHub

Required allows you to denote, that this field must have a value provided.

How does it look?

img_req_list.png

not applicable

img_req_form.png

How to add?

Example

Add fields.setRequired to corresponding FieldMetaBuilder.

    @Override
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customFieldId);
        fields.setEnabled(MyExampleDTO_.customField);
        fields.setRequired(MyExampleDTO_.customField);
    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub