AutoComplete for suggestions with array of type string
Goal: Add AutoComplet String
Add an AutoComplete for suggestions with array of type string as a search criteria input field for your search page.
1. Parameters
Please define the member for your <%= featurePropertyName %>SearchCriteriasSchema here
Please replace all occurences of exampleStringArray with the actual name in the following code snippets. |
Adapt in File: <feature>-search.parameters.ts
exampleStringArray: z
.union([z.string(), z.array(z.string())])
.transform((v: string | string[] | undefined): string[] | undefined =>
v instanceof Array || !v
? (v as string[] | undefined)
: ([v] as string[]),
)
.transform((v: string[] | undefined) => v?.map((e) => e))
.optional(),
2. State & viewmodel
Add additional array member for the autocomplete suggestions in your state and viewmodel:
Adapt in Files: <feature>-search.viewmodel.ts
and <feature>-search.state.ts
...
exampleStringArrayOptions: string[]
...
3. Actions
Create following actions to handle the events regarding autocomplete:
Adapt in File: <feature>-search.actions.ts
...
events: {
'exampleStringArray data text entered': props<{ exampleStringArrayInputValue: string }>(),
'exampleStringArray data received ': props<{ exampleStringArrayOptions: string[] }>(),
'exampleStringArray data loading failed': emptyProps(),
'exampleStringArray selected': props<{ selectedExampleStringArrayValue: string }>(),
'exampleStringArray unselected': props<{ unSelectedExampleStringArrayValue: string }>(),
},
...
4. HTML
Add the following code to your formGroup in the html file:
Adapt in File: <feature>-search.component.html
<span class="p-float-label">
<p-autoComplete
id="exampleStringArray"
formControlName="exampleStringArray"
(completeMethod)="searchExampleStringArrayData($event)"
[suggestions]="vm?.exampleStringArrayOptions ?? []"
[forceSelection]="true"
[multiple]="true" <-- ONLY NECESSARY IF MULTIPLE VALUES CAN BE SELECTED
[showEmptyMessage]="true"
[emptyMessage]="
vm?.exampleStringArrayOptions?.length === 0
? ('YOUR_PRODUCT_SEARCH.CRITERIA.EXAMPLE_ID_NOT_FOUND' | translate)
: ''
"
(onSelect)="selectExampleStringArrayValue($event)"
(onUnselect)="unSelectExampleStringArrayValue($event)"
>
</p-autoComplete>
<label for="exampleStringArray">{{
'YOUR_PRODUCT_SEARCH.CRITERIA.ID' | translate
}}</label>
</span>
5. Component
Add the respective methods to handle the different events:
Adapt in File: <feature>-search.component.ts
...
searchExampleStringArrayData(event: AutoCompleteCompleteEvent) {
this.store.dispatch(
<feature>SearchActions.exampleStringArrayDataTextEntered({
exampleStringArrayInputValue: event.query,
}),
);
}
selectExampleStringArrayValue(event: AutoCompleteSelectEvent) {
this.store.dispatch(
<feature>SearchActions.exampleStringArraySuggestionSelected({
selectedExampleStringArrayValue: event.value,
}),
);
}
unSelectExampleStringArrayValue(event: AutoCompleteUnselectEvent) {
this.store.dispatch(
<feature>SearchActions.exampleStringArraySuggestionUnselected({
unSelectedExampleStringArrayValue: event.value,
}),
);
}
...
6. Reducers
In the reducers file you need to define the functions:
Adapt in File: <feature>-search.reducers.ts
...
on(
<%= featureClassName %>SearchActions.exampleStringArrayDataReceived,
(state: <%= featureClassName %>SearchState, { exampleStringArrayOptions }): <%= featureClassName %>SearchState => ({
...state,
exampleStringArrayOptions: exampleStringArrayOptions,
}),
),
on(
<%= featureClassName %>SearchActions.exampleStringArrayDataLoadingFailed,
(state: <%= featureClassName %>SearchState): <%= featureClassName %>SearchState => ({
...state,
exampleStringArrayOptions: [],
}),
),
on(
<%= featureClassName %>SearchActions.exampleStringArraySuggestionSelected,
(
state: <%= featureClassName %>SearchState,
{ selectedExampleStringArrayValue },
): <%= featureClassName %>SearchState => {
const isValuePresent =
state.exampleStringArraySelectedValues.includes(selectedExampleStringArrayValue);
return {
...state,
exampleStringArraySelectedValues: isValuePresent
? state.exampleStringArraySelectedValues
: [...state.exampleStringArraySelectedValues, selectedExampleStringArrayValue],
exampleStringArrayOptions: [],
};
},
),
on(
<%= featureClassName %>SearchActions.exampleStringArraySuggestionUnselected,
(
state: <%= featureClassName %>SearchState,
{ unSelectedExampleStringArrayValue },
): <%= featureClassName %>SearchState => ({
...state,
exampleStringArraySelectedValues: state.exampleStringArraySelectedValues.filter(
(exampleStringArray) => exampleStringArray !== unSelectedExampleStringArrayValue,
),
exampleStringArrayOptions: [],
}),
),
...
7. Selectors
Add the missing selectors:
Adapt in File: <feature>-search.selectors.ts
...
export const select<%= featureClassName %>SearchViewModel = createSelector(
...
<feature>SearchSelectors.
selectExampleStringArrayOptions,
...
(
...
exampleStringArrayOptions,
...
): <%= featureClassName %>SearchViewModel => ({
...
exampleStringArrayOptions,
...
}),
);
...
8. Effects
Create the effect for getting the suggestions
Adapt in File: <feature>-search.effects.ts
...
searchExampleStringArray$ = createEffect(() =>
this.actions$.pipe(
ofType(<%= featureClassName %>SearchActions.exampleStringArrayDataTextEntered),
mergeMap((action) => {
return this.<feature>Service
.searchExampleStringArray(action.exampleStringArrayInputText)
.pipe(
map((response) =>
<%= featureClassName %>SearchActions.exampleStringArrayDataReceived({
exampleStringArrayOptions: response.exampleStringArray, <-- NAME OF THE MEMBER WHICH IS DEFINED IN THE RESPONSE OBJECT
}),
),
catchError(() =>
of<%= featureClassName %>SearchActions.exampleStringArrayDataLoadingFailed()),
),
);
}),
),
);
...
Don’t forget to add the translations to your de.json and en.json. |