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:
- List widget
- AdditionalList widget
- GroupingHierarchy widget
- AssocListPopup widget
- PickListPopup widget
by fulltextsearch
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:
- List widget ( Live Sample GitHub )
- AssocListPopup widget ( Live Sample GitHub )
- PickListPopup widget ( Live Sample GitHub )
How does it look?
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"
}
}
}
Step 2
Add specifications for fulltextsearch fields to corresponding JpaRepository.
@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> {
default Specification<MyEntity> getCustomFieldLikeIgnoreCaseSpecification(String value) {
return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntity_.customField));
}
default Specification<MyEntity> getCustomFieldTextLikeIgnoreCaseSpecification(String value) {
return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntity_.customFieldText));
}
default Specification<MyEntity> getFullTextSearchSpecification(String value) {
return getCustomFieldLikeIgnoreCaseSpecification(value)
.or(getCustomFieldTextLikeIgnoreCaseSpecification(value));
}
}
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": "myEntityPickAssocListPopup",
"title": "AssocListPopup widget property FullTextSearch",
"type": "AssocListPopup",
"bc": "myEntityPick",
"fields": [
{
"title": "Custom Field",
"key": "customField",
"type": "input"
},
{
"title": "Custom Field Text",
"key": "customFieldText",
"type": "text"
}
],
"options": {
"fullTextSearch": {
"enabled": true,
"placeholder": "Find by Custom Field Text or Custom Field"
}
}
}
Step 2
Add specifications for fulltextsearch fields to corresponding JpaRepository.
@Repository
public interface MyEntityPickRepository extends JpaRepository<MyEntityPick, Long>, JpaSpecificationExecutor<MyEntityPick> {
default Specification<MyEntityPick> getCustomFieldLikeIgnoreCaseSpecification(String value) {
return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntityPick_.customField));
}
default Specification<MyEntityPick> getCustomFieldTextLikeIgnoreCaseSpecification(String value) {
return (root, query, cb) -> FullTextSearchExt.likeIgnoreCase(value, cb, root.get(MyEntityPick_.customFieldText));
}
default Specification<MyEntityPick> getFullTextSearchSpecification(String value) {
return getCustomFieldLikeIgnoreCaseSpecification(value)
.or(getCustomFieldTextLikeIgnoreCaseSpecification(value));
}
}
Step 4
Add getSpecification to corresponding VersionAwareResponseService.
@Override
protected Specification<MyEntityPick> 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": "myEntityPickPickPickListPopup",
"title": "PickListPopup widget property FullTextSearch",
"type": "PickListPopup",
"bc": "myEntityPickPick",
"fields": [
{
"title": "Custom Field",
"key": "customField",
"type": "input"
},
{
"title": "Custom Field Text",
"key": "customFieldText",
"type": "text"
}
],
"options": {
"fullTextSearch": {
"enabled": true,
"placeholder": "Find by Custom Field Text or Custom Field"
}
}
}
by personal filter group
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:
-
List ( Live Sample GitHub )
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?
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")
private String customField;
@SearchParameter(name = "customFieldNew")
private String customFieldNew;
@SearchParameter(name = "customFieldMultivalueList.id", provider = LongValueProvider.class)
private MultivalueField customFieldMultivalue;
private String customFieldMultivalueDisplayedKey;
@SearchParameter(name = "customFieldPicklistEntity.customField")
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
Step 3 Add filterSetting to corresponding .widget.json.
enabled
true/false
{
"name": "MyExampleAdditionalList",
"title": "AdditionalList",
"type": "AdditionalList",
"bc": "myexample",
"fields": [
{
"title": "Custom Field Dictionary",
"key": "customFieldDictionary",
"type": "dictionary"
},
{
"title": "customField",
"key": "customField",
"type": "input"
}
],
"options": {
"actionGroups": {
"include": []
},
"filterSetting": {
"enabled": true
}
}
}
by filter group
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.
This function is available:
- List ( Live Sample GitHub )
- AdditionalList ( Live Sample GitHub )
The option to default filter by saved groups is currently unavailable.
How does it look?
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
Add business component in BC_FILTER_GROUPS TABLE
name
- name predefined filter
BC
- name business component
filters
- conditions for filtration
Additional properties
Clear filters
If you have filtered by table, the "Clear all filters" button will appear. It is suggested to indicate the number of applied filters by displaying "Clear n filters" (where n represents the number of columns being filtered).
How does it look?
How to add?
on default