6161import com .vaadin .flow .component .select .Select ;
6262import com .vaadin .flow .component .textfield .BigDecimalField ;
6363import com .vaadin .flow .component .textfield .TextField ;
64+ import com .vaadin .flow .data .value .ValueChangeMode ;
6465import com .vaadin .flow .router .BeforeEnterEvent ;
6566import com .vaadin .flow .router .BeforeEnterObserver ;
6667import com .vaadin .flow .router .QueryParameters ;
6768
6869import software .xdev .vaadin .builder .CustomizableFilterBuilder ;
70+ import software .xdev .vaadin .comparators .ContainsComparator ;
6971import software .xdev .vaadin .comparators .FilterComparator ;
7072import software .xdev .vaadin .comparators .utl .DateHelper ;
7173import software .xdev .vaadin .daterange_picker .business .DateRange ;
@@ -102,11 +104,13 @@ public class FilterComponent<T> extends Composite<VerticalLayout> implements Bef
102104 public static final String BTN_CANCEL_FILTER_FILTER_COMPONENT = "btnCancelFilterFilterComponent" ;
103105 public static final String DATE_RANGE_PICKER_QUERY_FILTER_COMPONENT = "dateRangePickerQueryFilterComponent" ;
104106 public static final String DELETED_INITIAL_CONDITION_STRING = "deletedInitialCondition" ;
107+ public static final String BTN_RESET_FILTER_FILTER_COMPONENT = "btnResetFilterFilterComponent" ;
105108
106109 private final UI ui ;
107110 private final Button btnAddNewFilter = new Button ("Add filter" );
108111 private final Button btnAcceptFilter = new Button (VaadinIcon .CHECK .create ());
109112 private final Button btnCancelFilter = new Button (VaadinIcon .CLOSE .create ());
113+ private final Button btnResetFilter = new Button (VaadinIcon .ROTATE_RIGHT .create ());
110114 private final Select <FilterField <T , ?>> selFields = new Select <>();
111115 private final Select <FilterComparator > selOperations = new Select <>();
112116 private final TextField txtSearchQuery = new TextField ();
@@ -130,6 +134,7 @@ private static DateRangePicker<DateRange> createDateRangePicker()
130134
131135 // Data
132136 private final List <ChipBadgeExtension <FilterCondition <T , ?>>> chipBadges = new ArrayList <>();
137+ private final List <ChipBadgeExtension <FilterCondition <T , ?>>> initialChipBadges = new ArrayList <>();
133138
134139 private int initialConditionIdCounter = 1 ;
135140 private String editingBadgeId ;
@@ -160,12 +165,13 @@ public FilterComponent(final Grid<T> dataGrid)
160165 private void initUI ()
161166 {
162167 final VerticalLayout vlRoot = this .getContent ();
163- vlRoot .add (this .btnAddNewFilter , this .hlFilter , this .hlChipBadges );
168+ vlRoot .add (new HorizontalLayout ( this .btnAddNewFilter , this . btnResetFilter ) , this .hlFilter , this .hlChipBadges );
164169
165170 // click listener
166171 this .btnAddNewFilter .addClickListener (e -> this .onShowFilterInput ());
167172 this .btnCancelFilter .addClickListener (e -> this .hlFilter .removeAll ());
168173 this .btnAcceptFilter .addClickListener (e -> this .onAcceptFilter ());
174+ this .btnResetFilter .addClickListener (e -> this .onResetFilter ());
169175
170176 // value change listener
171177 this .selFields .addValueChangeListener (e -> this .onFieldChange (this .selFields .getValue ()));
@@ -182,6 +188,11 @@ private void initUI()
182188 this .btnAcceptFilter .setEnabled (e .getValue () != null && this .selOperations .getValue () != null ));
183189 this .selSearchQuery .addValueChangeListener (e ->
184190 this .btnAcceptFilter .setEnabled (e .getValue () != null && this .selOperations .getValue () != null ));
191+ this .txtSearchQuery .addValueChangeListener (e ->
192+ this .btnAcceptFilter .setEnabled (!e .getValue ().isBlank () && this .selOperations .getValue () != null ));
193+
194+ this .nmbSearchQuery .setValueChangeMode (ValueChangeMode .EAGER );
195+ this .txtSearchQuery .setValueChangeMode (ValueChangeMode .EAGER );
185196
186197 // renderer
187198 this .selFields .setTextRenderer (FilterField ::getDescription );
@@ -193,9 +204,12 @@ private void initUI()
193204 this .btnAcceptFilter .addClickShortcut (Key .ENTER );
194205 this .btnCancelFilter .addClickShortcut (Key .ESCAPE );
195206
207+ this .btnResetFilter .setEnabled (false );
208+
196209 // ids
197210 this .btnAcceptFilter .setId (BTN_ACCEPT_FILTER_FILTER_COMPONENT );
198211 this .btnCancelFilter .setId (BTN_CANCEL_FILTER_FILTER_COMPONENT );
212+ this .btnResetFilter .setId (BTN_RESET_FILTER_FILTER_COMPONENT );
199213 this .selFields .setId (SEL_FIELDS_FILTER_COMPONENT );
200214 this .selOperations .setId (SEL_OPERATIONS_FILTER_COMPONENT );
201215 this .txtSearchQuery .setId (TXT_SEARCH_QUERY_FILTER_COMPONENT );
@@ -207,6 +221,30 @@ private void initUI()
207221 this .dateRangePickerQuery .setId (DATE_RANGE_PICKER_QUERY_FILTER_COMPONENT );
208222 }
209223
224+ private void onResetFilter ()
225+ {
226+ final List <ChipBadgeExtension <FilterCondition <T , ?>>> copyChipBadges = new ArrayList <>(this .chipBadges );
227+ for (final ChipBadgeExtension <FilterCondition <T , ?>> chipBadge : copyChipBadges )
228+ {
229+ this .removeChipBadgeCondition (chipBadge );
230+ }
231+
232+ // Creating the initial filter again
233+ this .chipBadges .addAll (this .initialChipBadges );
234+ this .initialChipBadges .forEach (this .hlChipBadges ::add );
235+ this .updateGridFilter ();
236+
237+ // Remove query parameter
238+ this .ui .getPage ().fetchCurrentURL (currentUrl ->
239+ this .ui
240+ .getPage ()
241+ .getHistory ()
242+ .replaceState (null , currentUrl .getPath ()));
243+
244+ // Disable reset button again
245+ this .btnResetFilter .setEnabled (false );
246+ }
247+
210248 private void onOperatorChanged ()
211249 {
212250 this .btnAcceptFilter .setEnabled (this .shouldTheAcceptButtonBeEnabled ());
@@ -219,10 +257,14 @@ private void onOperatorChanged()
219257
220258 // Change to a text field if the field is of type enum with condition 'contains'
221259 if (isSelSearchQueryVisible
222- && this .selOperations .getValue ().getDescription ().contains ("contains" ))
260+ && this .selOperations .getValue ()
261+ .getDescription ()
262+ .equals (ContainsComparator .CONTAINS_COMPARATOR_DESCRIPTION ))
223263 {
224264 this .selSearchQuery .setVisible (false );
225265 this .txtSearchQuery .setVisible (true );
266+
267+ this .btnAcceptFilter .setEnabled (this .shouldTheAcceptButtonBeEnabled ());
226268 }
227269 else if (!isSelSearchQueryVisible )
228270 {
@@ -260,6 +302,10 @@ private void onShowFilterInput()
260302
261303 if (this .hlFilter .getChildren ().findAny ().isEmpty ())
262304 {
305+ // Needed if the previous condition was an editable initial condition
306+ // The editable initial condition makes the cancel button invisible
307+ this .btnCancelFilter .setVisible (true );
308+
263309 this .selFields .setValue (null );
264310 this .selOperations .setItems (Collections .emptyList ());
265311 this .selOperations .setEnabled (false );
@@ -334,6 +380,9 @@ private void onAcceptFilter()
334380
335381 // Removing all filter components after accepting
336382 this .hlFilter .removeAll ();
383+
384+ // When something changes from the initial start, enable the reset button
385+ this .btnResetFilter .setEnabled (true );
337386 }
338387
339388 private ChipBadgeExtension <FilterCondition <T , ?>> createBadgeConditionAndApplyFilter (
@@ -402,7 +451,7 @@ private void onAcceptFilter()
402451 }
403452
404453 this .chipBadges .add (badge );
405- this .hlChipBadges .add (badge , badge );
454+ this .hlChipBadges .add (badge );
406455
407456 this .updateGridFilter ();
408457
@@ -421,11 +470,16 @@ private void deactivateDeleteButtonFromChipComponents(
421470 {
422471 this .removeChipBadgeCondition (badge );
423472
424- if (badge .getBadgeId () != null && !badge .getBadgeId ().equals (NO_BADGE_ID_STRING ))
473+ if (!this .identifier .isBlank ()
474+ && badge .getBadgeId () != null
475+ && !badge .getBadgeId ().equals (NO_BADGE_ID_STRING ))
425476 {
426477 badge .setBadgeId (DELETED_INITIAL_CONDITION_STRING );
427478 this .addQueryParameter (badge );
428479 }
480+
481+ // Activate the reset button
482+ this .btnResetFilter .setEnabled (true );
429483 });
430484 }
431485 }
@@ -436,8 +490,10 @@ private void deactivateDeleteButtonFromChipComponents(
436490 @ SuppressWarnings ("PMD.CognitiveComplexity" ) // Fixed in v2
437491 private void formatLocalDateChipBadgeText (final ChipBadge <FilterCondition <T , ?>> chipBadge )
438492 {
493+ final FilterCondition <T , ?> filterField = chipBadge .getItem ();
494+
439495 if (this .dateRangePickerQuery .isVisible ()
440- && chipBadge . getItem () .getSelectedCondition ().getDescription ().equals (IS_BETWEEN_COMPARATOR_DESCRIPTION ))
496+ && filterField .getSelectedCondition ().getDescription ().equals (IS_BETWEEN_COMPARATOR_DESCRIPTION ))
441497 {
442498 chipBadge .setItemLabelGenerator ((ItemLabelGenerator <FilterCondition <T , ?>>)tFilterCondition ->
443499 {
@@ -476,7 +532,7 @@ private void formatLocalDateChipBadgeText(final ChipBadge<FilterCondition<T, ?>>
476532 return createChipComponentString (tFilterCondition , dateString );
477533 });
478534 }
479- else if (this .dateSearchQuery .isVisible ())
535+ else if (this .dateSearchQuery .isVisible () && filterField . getItem (). getType (). equals ( LocalDate . class ) )
480536 {
481537 chipBadge .setItemLabelGenerator ((ItemLabelGenerator <FilterCondition <T , ?>>)tFilterCondition ->
482538 {
@@ -506,7 +562,7 @@ else if(this.dateSearchQuery.isVisible())
506562 return createChipComponentString (tFilterCondition , dateString );
507563 });
508564 }
509- else if (this .dateTimeSearchQuery .isVisible ())
565+ else if (this .dateTimeSearchQuery .isVisible () && filterField . getItem (). getType (). equals ( LocalDateTime . class ) )
510566 {
511567 chipBadge .setItemLabelGenerator ((ItemLabelGenerator <FilterCondition <T , ?>>)tFilterCondition ->
512568 {
@@ -657,7 +713,7 @@ else if(this.selSearchQuery.isVisible())
657713 else
658714 {
659715 // For txtSearchQuery
660- valueNotNull = true ;
716+ valueNotNull = ! this . txtSearchQuery . getValue (). isBlank () ;
661717 }
662718
663719 return valueNotNull && this .selOperations .getValue () != null ;
@@ -1116,6 +1172,8 @@ public void beforeEnter(final BeforeEnterEvent beforeEnterEvent)
11161172
11171173 this .removeInitialConditionIfBadgeIdAlreadyExists (this .queryBadgeIdList );
11181174 this .createConditionsFromQueryParameters ();
1175+
1176+ this .btnResetFilter .setEnabled (true );
11191177 }
11201178 }
11211179 }
@@ -1318,7 +1376,7 @@ public FilterComponent<T> withInitialFilter(
13181376 this .selFields .setItems (this .filterFieldList );
13191377 }
13201378
1321- final ChipBadge <FilterCondition <T , ?>> chipBadge = this .createBadgeConditionAndApplyFilter (
1379+ final ChipBadgeExtension <FilterCondition <T , ?>> chipBadge = this .createBadgeConditionAndApplyFilter (
13221380 finalFilterField ,
13231381 selectedCondition ,
13241382 searchQuery ,
@@ -1328,6 +1386,9 @@ public FilterComponent<T> withInitialFilter(
13281386 // Just needed if the url parameters are activated
13291387 chipBadge .setBadgeId (badgeId );
13301388
1389+ // Needed for resetting the conditions
1390+ this .initialChipBadges .add (chipBadge );
1391+
13311392 return this ;
13321393 }
13331394
0 commit comments