Skip to content

suggestionPickList

suggestionPickList is a component that allows you to select values from a dropdown list and display data from various external sources, such as microservices, files, and others.

Basics

Live Sample · GitHub

How does it look?

img_list.gif

not applicable

img_form.gif

How to add?

Example
  • Step 1. Create Popup

    In the following example, we use a microservice as the data source. The example entity creation in microservices described in Microservices

    • Step 1.1 Create Popup List .widget.json. We create based on an entity that accesses the microservice.
      {
        "name": "MyExampleSuggest",
        "title": "PickListPopup",
        "type": "PickListPopup",
        "bc": "myexamplesuggection",
        "limit": 20,
        "fields": [
          {
            "title": "customFieldSuggestion",
            "key": "customFieldSuggestion",
            "type": "input"
          },
          {
            "title": "customFieldSuggestionDate",
            "key": "customFieldSuggestionDate",
            "type": "dateTime"
          }
        ]
      }
      
  • Step 2 Add Popup to .view.json.

    {
      "name": "myexamplelist",
      "title": "MyExample Form",
      "template": "DashboardView",
      "url": "/screen/myexample/view/myexamplelist",
      "widgets": [
        {
          "widgetName": "SecondLevelMenu",
          "position": 1,
          "gridWidth": 24
        },
        {
          "widgetName": "ThirdLevelMenu",
          "position": 2,
          "gridWidth": 24
        },
        {
          "widgetName": "MyExampleList",
          "position": 20,
          "gridWidth": 12
        },
        {
          "widgetName": "MyExampleSuggest",
          "position": 30,
          "gridWidth": 24
        }
      ],
      "rolesAllowed": [
        "CXBOX_USER"
      ]
    }
    
    {
      "name": "myexampleform",
      "title": "MyExample Form",
      "template": "DashboardView",
      "url": "/screen/myexample/view/myexampleform",
      "widgets": [
        {
          "widgetName": "MyExampleSuggest",
          "position": 0,
          "gridWidth": 24
        },
        {
          "widgetName": "SecondLevelMenu",
          "position": 1,
          "gridWidth": 24
        },
        {
          "widgetName": "ThirdLevelMenu",
          "position": 2,
          "gridWidth": 24
        },
        {
          "widgetName": "MyExampleForm",
          "position": 20,
          "gridWidth": 12
        }
      ],
      "rolesAllowed": [
        "CXBOX_USER"
      ]
    }
    
  • Step3 Add bc myexamplesuggection to corresponding EnumBcIdentifier.

        myexample(MyExampleService.class),
        myexamplesuggectioncsv(MyExampleService.class),
    
        myexample(MyExampleService.class),
        myexamplesuggection(MyExampleSuggestionService.class);
    

Step4 Add suggestionPickList and pickMap to .widget.json.

popupBcName — the name of the BC (Business Component) that opens in the pop-up. Requirements 2 and 3 must be satisfied.

pickMap: Maps fields between the parent BC and popup(child) BC

  • customField (parent BC) <- customFieldSuggestion (popup(child) BC).
  • customFieldDate (parent BC) <- customFieldSuggestionDate (popup(child) BC).
{
  "name": "MyExampleList",
  "title": "List Widget with suggestionPickList basic",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "Custom Field Date",
      "key": "customFieldDate",
      "type": "date"
    },
    {
      "title": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexamplesuggection",
      "pickMap": {
        "customField": "customFieldSuggestion",
        "customFieldDate": "customFieldSuggestionDate"
      }
    }
  ]
}

not applicable

Step4 Add suggestionPickList and pickMap to .widget.json.

popupBcName — the name of the BC (Business Component) that opens in the pop-up. Requirements 2 and 3 must be satisfied.

pickMap: Maps fields between the parent BC and popup(child) BC

  • customField (parent BC) <- customFieldSuggestion (popup(child) BC).
  • customFieldDate (parent BC) <- customFieldSuggestionDate (popup(child) BC).
{
  "name": "MyExampleForm",
  "title": "Form Widget with suggestionPickList basic",
  "type": "Form",
  "bc": "myexample",
  "fields": [
    {
      "label": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexamplesuggection",
      "pickMap": {
        "customField": "customFieldSuggestion",
        "customFieldDate": "customFieldSuggestionDate"
      }
    }
  ],
  "options": {
    "layout": {
      "rows": [
        {
          "cols": [
            {
              "fieldKey": "customField",
              "span": 24
            }
          ]
        }
      ]
    }
  }
}

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

How does it look?

img_plchldr_list.png

not applicable

img_plchldr_form.png

How to add?

Example

Add fields.setPlaceholder to corresponding FieldMetaBuilder.

    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customField);
        fields.setPlaceholder(MyExampleDTO_.customField,"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 {

    private String customField;
    private String customFieldDate;
    private String customFieldColor;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customField = entity.getCustomField();
        this.customFieldDate = entity.getCustomFieldDate();
        this.customFieldColor = "#edaa";
    }
}

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

{
  "name": "MyExampleList",
  "title": "List Widget with suggestionPickList color",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "bgColorKey": "customFieldColor"
    }
  ]
}

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

{
  "name": "MyExampleInfo",
  "title": "Info Widget with suggestionPickList color",
  "type": "Info",
  "bc": "myexample",
  "fields": [
    {
      "label": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "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 Widget with suggestionPickList color",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "bgColor": "#edaa"
    }
  ]
}

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

{
  "name": "MyExampleInfo",
  "title": "Info Widget with suggestionPickList color",
  "type": "Info",
  "bc": "myexample",
  "fields": [
    {
      "label": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "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

not applicable

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_.customField)) {
            entity.setCustomField(data.getCustomField());
        }
        return new ActionResultDTO<>(entityToDto(bc, entity));
    }
Step2 Add fields.setEnabled to corresponding FieldMetaBuilder.
    public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
                                      Long id, Long parentId) {
        fields.setEnabled(MyExampleDTO_.customField);

    }

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Option 1 Enabled by default.

    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. Search uses in operator which compares ids in this case.

How does it look?

img_filtr_list.gif

img_filtr_list_field.gif

not applicable

not applicable

How to add?

Example

The dropdown list filtering is performed either by an external service or by the logic described in getList.

see more microservices

@Service
@RequiredArgsConstructor
public class MyEntityDao extends AbstractAnySourceBaseDAO<MyEntityOutServiceDTO> implements AnySourceBaseDAO<MyEntityOutServiceDTO> {
    private final IntegrationConfiguration integrationConfig;

    private final RestTemplate restTemplate;

    private final IntegrationURLBuilder integrationURLBuilder;

    @Override
    public String getId(final MyEntityOutServiceDTO entity) {
        return entity.getId();
    }

    @Override
    public void setId(final String id, final MyEntityOutServiceDTO entity) {
        entity.setId(id);
    }


    @Override
    public MyEntityOutServiceDTO getByIdIgnoringFirstLevelCache(final BusinessComponent bc) {
        return restTemplate.exchange(
                fromUriString(integrationConfig.getSuggestionMicroservicesDataServerUrl() + "/{id}").build()
                        .expand(bc.getIdAsLong()).normalize().encode()
                        .toUriString(),
                GET, null, MyEntityOutServiceDTO.class
        ).getBody();
    }


    @Override
    public Page<MyEntityOutServiceDTO> getList(final BusinessComponent bc, final QueryParameters queryParameters) {

        //Page size
        String page = bc.getParameters().getParameter("_page");

        //Limit
        String limit = bc.getParameters().getParameter("_limit");

        //Filter
        List<String> filterCustomField = getFilterFieldName(queryParameters);
        Optional<String> filter = filterCustomField.isEmpty() ? Optional.empty() : Optional.of(filterCustomField.get(0));

        //Sorting
        List<String> sortCustomField = getSortFieldName(queryParameters, "customFieldSuggestion");
        Optional<String> sort = sortCustomField.isEmpty() ? Optional.empty() : Optional.of(sortCustomField.get(0));

        String urlTemplate = UriComponentsBuilder.fromHttpUrl(integrationConfig.getSuggestionMicroservicesDataServerUrl())
                .queryParam("number", page)
                .queryParam("size", limit)
                .queryParamIfPresent("filterCustomFieldSuggestion", filter)
                .queryParamIfPresent("sortCustomFieldSuggestion", sort)
                .encode()
                .toUriString();

        ResponseEntity<RestResponsePage<MyEntityOutServiceDTO>> responseEntity = restTemplate.exchange(
                urlTemplate,
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<>() {
                },
                filter
        );
        return responseEntity.getBody();
    }


    private List<String> getSortFieldName(QueryParameters queryParameters, String fieldName) {
        return queryParameters.getParameters().entrySet().stream()
                .filter(f -> f.getKey().contains("_sort"))
                .filter(f -> f.getValue().contains(fieldName))
                .map(m -> {
                            String[] splitOperation = m.getKey().split("\\.");
                            return splitOperation[splitOperation.length - 1];
                        }
                ).toList();
    }

    private List<String> getFilterFieldName(QueryParameters queryParameters) {
        return queryParameters.getParameters().entrySet().stream()
                .filter(f -> f.getKey().contains("query"))
                .map(Map.Entry::getValue)
                .toList();
    }

    @Override
    public void delete(BusinessComponent bc) {
        restTemplate.exchange(
                fromUriString(integrationConfig.getSuggestionMicroservicesDataServerUrl()  + "/{id}").build().expand(bc.getIdAsLong()).normalize().encode()
                        .toUriString(),
                DELETE, null, Void.class
        );
    }


    @Override
    public MyEntityOutServiceDTO create(BusinessComponent bc, MyEntityOutServiceDTO entity) {
        entity.setId(null);
        return restTemplate.exchange(
                fromUriString(integrationConfig.getSuggestionMicroservicesDataServerUrl()).build().normalize().encode().toUriString(),
                POST, new HttpEntity<>(entity), MyEntityOutServiceDTO.class
        ).getBody();
    }

    @Override
    public MyEntityOutServiceDTO update(BusinessComponent bc, MyEntityOutServiceDTO entity) {
        return restTemplate.exchange(
                fromUriString(integrationConfig.getSuggestionMicroservicesDataServerUrl()).build().normalize().encode().toUriString(),
                PUT, new HttpEntity<>(entity), MyEntityOutServiceDTO.class
        ).getBody();
    }



}
@Service
@RequiredArgsConstructor
public class MyEntityDao extends AbstractAnySourceBaseDAO<MyEntityOutServiceDTO> implements AnySourceBaseDAO<MyEntityOutServiceDTO> {
    private static final String DELIMITER = ",";
    private final IntegrationConfiguration integrationConfig;

    private final RestTemplate restTemplate;

    private final IntegrationURLBuilder integrationURLBuilder;

    @Override
    public String getId(final MyEntityOutServiceDTO entity) {
        return entity.getId();
    }

    @Override
    public void setId(final String id, final MyEntityOutServiceDTO entity) {
        entity.setId(id);
    }


    @Override
    public MyEntityOutServiceDTO getByIdIgnoringFirstLevelCache(final BusinessComponent bc) {
        return getData().stream().filter(s -> Objects.equals(s.getId(), bc.getId())).findFirst().orElse(null);
    }


    @Override
    public Page<MyEntityOutServiceDTO> getList(final BusinessComponent bc, final QueryParameters queryParameters) {
        String filterCustomField = getFilterFieldName(queryParameters);
        if (filterCustomField == null) {
            return new PageImpl<>(getData());
        }
        return new PageImpl<>(getData().stream()
                .filter(f -> f.getCustomField().toUpperCase().contains(filterCustomField.toUpperCase()))
                .toList());

    }


    @Override
    public void delete(BusinessComponent bc) {
        throw new IllegalStateException();
    }


    @Override
    public MyEntityOutServiceDTO create(BusinessComponent bc, MyEntityOutServiceDTO entity) {
        throw new IllegalStateException();
    }

    @Override
    public MyEntityOutServiceDTO update(BusinessComponent bc, MyEntityOutServiceDTO entity) {
        throw new IllegalStateException();
    }

    @NonNull
    private List<MyEntityOutServiceDTO> getData() {
        try {
            ClassLoader classLoader = getClass().getClassLoader();
            Path pathUri = Paths.get(classLoader.getResource("db/data/custom/product.csv").toURI());
            return Files.readAllLines(pathUri)
                    .stream()
                    .map(line -> line.split(DELIMITER))
                    .map(parts -> {
                        MyEntityOutServiceDTO dto = new MyEntityOutServiceDTO();
                        dto.setId(parts[0]);
                        dto.setCustomField(parts[1]);
                        return dto;
                    })
                    .toList();
        } catch (Exception e) {
            return List.of();
        }
    }


    private String getFilterFieldName(QueryParameters queryParameters) {
        return queryParameters.getParameters().entrySet().stream()
                .filter(e -> e.getKey().contains("query"))
                .findFirst()
                .map(Map.Entry::getValue)
                .orElse(null);
    }
}

For fields of type suggestionPickList, the filtering matches the configuration of the corresponding field type in the database.

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

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

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

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customField = entity.getCustomField();
    }
}
Step 2 Add fields.enableFilter to corresponding FieldMetaBuilder.
    @Override
    public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription, Long parentId) {
        fields.enableFilter(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

img_drilldown_info

not applicable

How to add?

Example

Option 1

Step 1 Add fields.setDrilldown to corresponding FieldMetaBuilder.

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

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

{
  "name": "MyExampleList",
  "title": "List Widget with suggestionPickList drilldown",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "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 Widget with suggestionPickList drilldown",
  "type": "Info",
  "bc": "myexample",
  "fields": [
    {
      "label": "customField",
      "key": "customField",
      "type": "suggestionPickList",
      "popupBcName": "myexample",
      "pickMap": {
        "customField": "customFieldSuggestion"
      },
      "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

img_runtime_error

confirm_form

img_javax_stat_list

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 (data.isFieldChanged(MyExampleDTO_.customField)) {
        entity.setCustomField(data.getCustomField());
        if (StringUtils.isNotEmpty(data.getCustomField())
                && !String.valueOf(data.getCustomField()).matches("[A-Za-z]+")
        ) {
          throw new BusinessException().addPopup(ONLY_LETTER);
        }
      }
        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_.customField)) {
            entity.setCustomField(data.getCustomField());
            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("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 = "customField")
    @Pattern(regexp = "[A-Za-z]+", message = ONLY_LETTER)
    private String customField;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customField = entity.getCustomField();
    }
}

Works for List.

not applicable

Works for Form.

Live Sample · GitHub

Create сustom service for business logic check.

Use if:

Business logic check required for fields

Step 1 Create сustom 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 сustom method for check to corresponding VersionAwareResponseService.
    @Override
    protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data, BusinessComponent bc) {
        validateFields(bc, data);
        if (data.isFieldChanged(MyExampleDTO_.customField)) {
            entity.setCustomField(data.getCustomField());
        }
        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

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) {
        fields.enableSort(MyExampleDTO_.customField);
    }
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.gif

not applicable

img_req_form.gif

How to add?

Example

Add fields.setRequired to corresponding FieldMetaBuilder.

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

Works for List.

not applicable

Works for Form.

Live Sample · GitHub