-
Notifications
You must be signed in to change notification settings - Fork 0
Bug Fix: Mutliple filter components overwrite each others conditions when filtering the same grid #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug Fix: Mutliple filter components overwrite each others conditions when filtering the same grid #7
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,7 +47,11 @@ | |
| import java.util.stream.IntStream; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import com.vaadin.flow.component.AttachEvent; | ||
| import com.vaadin.flow.component.ComponentEvent; | ||
| import com.vaadin.flow.component.ComponentUtil; | ||
| import com.vaadin.flow.component.Composite; | ||
| import com.vaadin.flow.component.DetachEvent; | ||
| import com.vaadin.flow.component.ItemLabelGenerator; | ||
| import com.vaadin.flow.component.Key; | ||
| import com.vaadin.flow.component.UI; | ||
|
|
@@ -65,6 +69,7 @@ | |
| import com.vaadin.flow.router.BeforeEnterEvent; | ||
| import com.vaadin.flow.router.BeforeEnterObserver; | ||
| import com.vaadin.flow.router.QueryParameters; | ||
| import com.vaadin.flow.shared.Registration; | ||
|
|
||
| import software.xdev.vaadin.builder.CustomizableFilterBuilder; | ||
| import software.xdev.vaadin.comparators.ContainsComparator; | ||
|
|
@@ -369,6 +374,7 @@ private void onAcceptFilter() | |
| final boolean editable; | ||
|
|
||
| // Check if it's an initial condition | ||
| // Set editable/deletable and the customization degree | ||
| if(this.editingBadgeId != null && !this.editingBadgeId.equals(NO_BADGE_ID_STRING)) | ||
| { | ||
| deletable = this.deletingBadgeEnabled; | ||
|
|
@@ -396,6 +402,7 @@ private void onAcceptFilter() | |
| editable, | ||
| customizationDegree); | ||
|
|
||
| // Query parameter | ||
| if(!this.identifier.isBlank()) | ||
| { | ||
| if(this.editingBadgeId != null && !this.editingBadgeId.equals(NO_BADGE_ID_STRING)) | ||
|
|
@@ -478,7 +485,7 @@ private void onAcceptFilter() | |
| }); | ||
| } | ||
|
|
||
| this.deactivateDeleteButtonFromChipComponents(deletableCondition, badge); | ||
| this.setBtnDeleteClickListenerWhenConditionShouldBeDeletable(deletableCondition, badge); | ||
|
|
||
| // Format chip badge text if it contains LocalDate/LocalDateTime | ||
| if(TemporalAccessor.class.isAssignableFrom(badge.getItem().getItem().getType()) | ||
|
|
@@ -490,12 +497,12 @@ private void onAcceptFilter() | |
| this.chipBadges.add(badge); | ||
| this.hlChipBadges.add(badge); | ||
|
|
||
| this.updateGridFilter(); | ||
| this.addFilterConditionToGrid(badge); | ||
|
|
||
| return badge; | ||
| } | ||
|
|
||
| private void deactivateDeleteButtonFromChipComponents( | ||
| private void setBtnDeleteClickListenerWhenConditionShouldBeDeletable( | ||
| final boolean conditionDeletable, | ||
| final ChipBadgeExtension<FilterCondition<T, ?>> badge) | ||
| { | ||
|
|
@@ -812,32 +819,18 @@ else if(type.isAssignableFrom(Enum.class) || type.isAssignableFrom(Boolean.class | |
| } | ||
| } | ||
|
|
||
| private void updateGridFilter() | ||
| private void addFilterConditionToGrid(final ChipBadgeExtension<FilterCondition<T, ?>> chipBadge) | ||
| { | ||
| if(this.chipBadges.isEmpty()) | ||
| { | ||
| this.dataGrid.getListDataView().removeFilters(); | ||
| return; | ||
| } | ||
| Objects.requireNonNull(chipBadge); | ||
|
|
||
| this.dataGrid.getListDataView().setFilter(item -> | ||
| this.dataGrid.getListDataView().addFilter(item -> | ||
| { | ||
| final List<Predicate<T>> predicates = new ArrayList<>(); | ||
| final FilterCondition<T, ?> item1 = chipBadge.getItem(); | ||
| final String inputValue = item1.getInputValue(); | ||
| final Predicate<T> predicate = | ||
| item1.getSelectedCondition().compare(item1.getItem().getValueProvider(), inputValue); | ||
|
|
||
| for(final ChipBadge<FilterCondition<T, ?>> chipBadge : this.chipBadges) | ||
| { | ||
| final FilterCondition<T, ?> item1 = chipBadge.getItem(); | ||
| final String inputValue = item1.getInputValue(); | ||
|
|
||
| predicates.add( | ||
|
|
||
| item1.getSelectedCondition().compare( | ||
| item1.getItem().getValueProvider(), | ||
| inputValue) | ||
| ); | ||
| } | ||
|
|
||
| return predicates.stream().map(p -> p.test(item)).reduce(Boolean::logicalAnd).orElseThrow(); | ||
| return predicate.test(item); | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -938,10 +931,21 @@ private void removeChipBadgeCondition(final ChipBadgeExtension<FilterCondition<T | |
| { | ||
| this.chipBadges.remove(chip); | ||
| this.hlChipBadges.remove(chip); | ||
| // Have to set all filter when removing a condition again because we cannot remove just one filter from the | ||
| // grid | ||
| this.updateGridFilter(); | ||
| this.removeQueryParameter(chip); | ||
| } | ||
|
|
||
| private void updateGridFilter() | ||
| { | ||
| // Remove all filters from the grid | ||
| this.dataGrid.getListDataView().removeFilters(); | ||
| // Fire grid removed all filters event | ||
| // Every filter component in the current ui should add his filter back again to the grid | ||
| ComponentUtil.fireEvent(UI.getCurrent(), new FilterComponentResetGridFilterEvent(this, false)); | ||
| } | ||
|
|
||
| /** | ||
| * Sets the internationalization properties for the datePicker. | ||
| * | ||
|
|
@@ -1289,7 +1293,7 @@ private String createMultipleQueryParameterString() | |
| /** | ||
| * Method for adding a specific filter condition as query parameter. | ||
| * | ||
| * @param filterCondition The condition which should be converted to query parameter. | ||
| * @param chipBadge The condition which should be converted to query parameter. | ||
| */ | ||
| private void addQueryParameter(final ChipBadgeExtension<FilterCondition<T, ?>> chipBadge) | ||
| { | ||
|
|
@@ -1500,4 +1504,65 @@ public FilterComponent<T> withInitialFilter( | |
|
|
||
| return filterComponent; | ||
| } | ||
|
|
||
| // Needed for interacting with other filter components on the same ui | ||
| private Registration registration; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be protected so that it can be overriden |
||
|
|
||
| @Override | ||
| protected void onAttach(final AttachEvent attachEvent) | ||
| { | ||
| super.onAttach(attachEvent); | ||
| // Register to events from the event bus | ||
| this.registration = ComponentUtil.addListener( | ||
| attachEvent.getUI(), | ||
| FilterComponentResetGridFilterEvent.class, | ||
| event -> | ||
| { | ||
| if(this.chipBadges.isEmpty()) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // Get all conditions from filter component and add them to the grid | ||
| this.dataGrid.getListDataView().addFilter(item -> this.isItemMatchingFilter(item, this.chipBadges)); | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| private boolean isItemMatchingFilter( | ||
| final T item, | ||
| final List<ChipBadgeExtension<FilterCondition<T, ?>>> chipBadges) | ||
| { | ||
| final List<Predicate<T>> predicates = new ArrayList<>(); | ||
|
|
||
| for(final ChipBadge<FilterCondition<T, ?>> chipBadge : chipBadges) | ||
| { | ||
| final FilterCondition<T, ?> item1 = chipBadge.getItem(); | ||
| final String inputValue = item1.getInputValue(); | ||
|
|
||
| predicates.add( | ||
| item1.getSelectedCondition().compare( | ||
| item1.getItem().getValueProvider(), | ||
| inputValue) | ||
| ); | ||
| } | ||
|
|
||
| return predicates.stream().map(p -> p.test(item)).reduce(Boolean::logicalAnd).orElseThrow(); | ||
|
Comment on lines
+1536
to
+1550
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can likely be written with Streaming API |
||
| } | ||
|
|
||
| @Override | ||
| protected void onDetach(final DetachEvent detachEvent) | ||
| { | ||
| super.onDetach(detachEvent); | ||
| // Unregister from the event bus | ||
| this.registration.remove(); | ||
| } | ||
|
|
||
| private static class FilterComponentResetGridFilterEvent extends ComponentEvent<FilterComponent> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type is missing, see sonar for more details |
||
| { | ||
| public FilterComponentResetGridFilterEvent(final FilterComponent source, final boolean fromClient) | ||
| { | ||
| super(source, fromClient); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method is called
updateGridFilterbut it just removes filters and throws aFilterComponentResetGridFilterEvent.Should likely be called
resetGridFiltersor?