Skip to content

Filtration

by fields

The availability or unavailability of filtering operations for each field type see Fields.

Each field type requires a distinct filtering operation sent by the frontend. Here are the standard field types with their respective filtering methods see SearchOperation for filtering.

This function is available:

by fulltextsearch

Live Sample GitHub

FullTextSearch - when the user types in the full text search input area, then widget filters the rows that match the search query (search criteria is configurable and will usually check if at least one column has corresponding value). This feature makes it easier for users to quickly find the information they are looking for within a List widget.

This function is available:

How does it look?

fulltextsearch.gif

How to add?

Example

Step 1 Add extension file FullTextSearchExt.java

import java.util.Optional;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.cxbox.core.crudma.bc.BusinessComponent;

@UtilityClass
public class FullTextSearchExt {

    @NonNull
    public static Optional<String> getFullTextSearchFilterParam(BusinessComponent bc) {
        return Optional.ofNullable(bc.getParameters().getParameter("_fullTextSearch"));
    }

    public static Predicate likeIgnoreCase(String value, CriteriaBuilder cb, Path<String> path) {
        return cb.like(cb.lower(path), StringUtils.lowerCase("%" + value + "%"));
    }

}

Step 2 Add specifications for fulltextsearch fields to corresponding JpaRepository.

@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> {
    default Specification<MyEntity> getFullTextSearchSpecification(String value) {
        return getAddressLikeIgnoreCaseSpecification(value)
                .or(getFullNameLikeIgnoreCaseSpecification(value)
                        .or(getCustomFieldLikeIgnoreCaseSpecification(value)));
    }

    default Specification<MyEntity> getFullNameLikeIgnoreCaseSpecification(String value) {
        return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntity_.fullName));
    }


    default Specification<MyEntity> getAddressLikeIgnoreCaseSpecification(String value) {
        return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntity_.address));
    }

    default Specification<MyEntity> getCustomFieldLikeIgnoreCaseSpecification(String value) {
        return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntity_.customField));
    }
}

Step 4 Add getSpecification to corresponding VersionAwareResponseService.

    @Override
    protected Specification<MyEntity> getSpecification(BusinessComponent bc) {
        var fullTextSearchFilterParam = FullTextSearchExt.getFullTextSearchFilterParam(bc);
        var specification = super.getSpecification(bc);
        return fullTextSearchFilterParam.map(e -> and(repository.getFullTextSearchSpecification(e), specification)).orElse(specification);
    }

Step 5 Add fullTextSearch to corresponding .widget.json.

enabled true/false

placeholder - description for fullTextSearch

{
  "name": "MyExampleList",
  "title": "List FullTextSearch",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "Address",
      "key": "address",
      "type": "input"
    },
    {
      "title": "Full Name",
      "key": "fullName",
      "type": "input"
    },
    {
      "title": "customField",
      "key": "customField",
      "type": "input"
    }
  ],
  "options": {
    "fullTextSearch": {
      "enabled": true,
      "placeholder": "Find by Name or Address or Custom Field"
    }
  }
}

by personal filter group

Live Sample GitHub

Personal filter group - a user-filled filter can be saved for each individual user.

A user-filled filter can be saved for each individual user.

This function is available:

The "Save Filters" button is located within the gear icon. When the "Save Filters" button is clicked, a modal window appears displaying all custom filters, which can be deleted if desired.

How does it look?

filtergroup.gif

filtergroup_addlist.gif

How to add?

Example

The availability of filtering function depends on the type. See more field types

For fields where individual filters are intended to be saved, it is essential to configure the filtering options. see Step 1 and Step 2 Step 1 Add @SearchParameter to corresponding DataResponseDTO. (Advanced customization SearchParameter)

@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {
    @SearchParameter(name = "customField", provider = StringValueProvider.class)
    private String customField;
    @SearchParameter(name = "customFieldNew", provider = StringValueProvider.class)
    private String customFieldNew;
    @SearchParameter(name = "customFieldMultivalueList.id", provider = LongValueProvider.class)
    private MultivalueField customFieldMultivalue;
    private String customFieldMultivalueDisplayedKey;
    @SearchParameter(name = "customFieldPicklistEntity.customField", provider = StringValueProvider.class)
    private String customFieldPicklist;
    @SearchParameter(name = "customFieldPicklistEntity.id", provider = LongValueProvider.class)
    private Long customFieldPicklistId;

    public MyExampleDTO(MyEntity entity) {
        this.id = entity.getId().toString();
        this.customField = entity.getCustomField();
        this.customFieldNew = entity.getCustomFieldNew();
        this.customFieldMultivalue = entity.getCustomFieldMultivalueList().stream().collect(MultivalueField.toMultivalueField(
                e -> String.valueOf(e.getId()),
                e -> String.valueOf(e.getCustomField())
        ));
        this.customFieldMultivalueDisplayedKey = StringUtils.abbreviate(entity.getCustomFieldMultivalueList().stream().map(MyEntity::getCustomField
        ).map(e -> e.toString()).collect(Collectors.joining(",")), 12);
        this.customFieldPicklistId = Optional.ofNullable(entity.getCustomFieldPicklistEntity())
                .map(e -> e.getId())
                .orElse(null);
        this.customFieldPicklist = Optional.ofNullable(entity.getCustomFieldPicklistEntity())
                .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) {
        fields.enableFilter(MyExampleDTO_.customFieldPicklist);
        fields.enableFilter(MyExampleDTO_.customFieldMultivalue);
        fields.enableFilter(MyExampleDTO_.customFieldNew);
        fields.enableFilter(MyExampleDTO_.customField);

        fields.enableSort(MyExampleDTO_.customFieldNew);
        fields.enableSort(MyExampleDTO_.customField);
    }

Step 3 Add filterSetting to corresponding .widget.json.

enabled true/false

{
  "name": "MyExampleList",
  "title": "List",
  "type": "List",
  "bc": "myexample",
  "fields": [
    {
      "title": "Custom Field New",
      "key": "customFieldNew",
      "type": "input"
    },
    {
      "title": "customField",
      "key": "customField",
      "type": "input"
    }
  ],
  "options": {
    "filterSetting": {
      "enabled": true
    }
  }
}

by filter group

Live Sample GitHub

Filter group - predefined filters settings that users can use in an application. They allow users to quickly apply specific filtering criteria without having to manually input.

How does it look?

filter_group_save_list.gif

filter_group_save_add_list.gif

How to add?

Example

Tips

To write this drilldown, follow these steps:

    * Add a filter function for fields 
    * Visually fill in the necessary filters in the interface.
    * Open the developer panel.
    * Locate the required request.
    * Use this query to substitute in your code to get a reference

how_add_search_spec.gif

Add business component in BC_FILTER_GROUPS TABLE

name - name predefined filter

BC - name business component

filters - conditions for filtration

  name;bc;filters;ID
  Dictionary = High;myexample3618;customFieldDictionary.equalsOneOf=%5B%22High%22%