Skip to content

Commit 25633da

Browse files
committed
feat(autocomplete): add option to specify minimum characters for autocomplete
1 parent 7a2eda6 commit 25633da

File tree

4 files changed

+22
-4
lines changed

4 files changed

+22
-4
lines changed

src/Autocomplete/assets/dist/controller.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class default_1 extends Controller {
3939
}
4040
connect() {
4141
if (this.urlValue) {
42-
this.tomSelect = __classPrivateFieldGet(this, _instances, "m", _createAutocompleteWithRemoteData).call(this, this.urlValue);
42+
this.tomSelect = __classPrivateFieldGet(this, _instances, "m", _createAutocompleteWithRemoteData).call(this, this.urlValue, this.minCharactersTextValue);
4343
return;
4444
}
4545
if (this.optionsAsHtmlValue) {
@@ -121,7 +121,7 @@ _instances = new WeakSet(), _getCommonConfig = function _getCommonConfig() {
121121
},
122122
});
123123
return __classPrivateFieldGet(this, _instances, "m", _createTomSelect).call(this, config);
124-
}, _createAutocompleteWithRemoteData = function _createAutocompleteWithRemoteData(autocompleteEndpointUrl) {
124+
}, _createAutocompleteWithRemoteData = function _createAutocompleteWithRemoteData(autocompleteEndpointUrl, minCharacterLength) {
125125
const config = __classPrivateFieldGet(this, _instances, "m", _mergeObjects).call(this, __classPrivateFieldGet(this, _instances, "m", _getCommonConfig).call(this), {
126126
firstUrl: (query) => {
127127
const separator = autocompleteEndpointUrl.includes('?') ? '&' : '?';
@@ -134,6 +134,10 @@ _instances = new WeakSet(), _getCommonConfig = function _getCommonConfig() {
134134
.then(json => { this.setNextUrl(query, json.next_page); callback(json.results); })
135135
.catch(() => callback());
136136
},
137+
shouldLoad: function (query) {
138+
const minLength = minCharacterLength ? parseInt(minCharacterLength) : 3;
139+
return query.length >= minLength;
140+
},
137141
score: function (search) {
138142
return function (item) {
139143
return 1;
@@ -173,6 +177,7 @@ default_1.values = {
173177
optionsAsHtml: Boolean,
174178
noResultsFoundText: String,
175179
noMoreResultsText: String,
180+
minCharacters: String,
176181
tomSelectOptions: Object,
177182
};
178183

src/Autocomplete/assets/src/controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ export default class extends Controller {
88
optionsAsHtml: Boolean,
99
noResultsFoundText: String,
1010
noMoreResultsText: String,
11+
minCharacters: String,
1112
tomSelectOptions: Object,
1213
}
1314

1415
readonly urlValue: string;
1516
readonly optionsAsHtmlValue: boolean;
1617
readonly noMoreResultsTextValue: string;
1718
readonly noResultsFoundTextValue: string;
19+
readonly minCharactersTextValue: string;
1820
readonly tomSelectOptionsValue: object;
1921
tomSelect: TomSelect;
2022

@@ -30,7 +32,7 @@ export default class extends Controller {
3032

3133
connect() {
3234
if (this.urlValue) {
33-
this.tomSelect = this.#createAutocompleteWithRemoteData(this.urlValue);
35+
this.tomSelect = this.#createAutocompleteWithRemoteData(this.urlValue, this.minCharactersTextValue);
3436

3537
return;
3638
}
@@ -124,7 +126,7 @@ export default class extends Controller {
124126
return this.#createTomSelect(config);
125127
}
126128

127-
#createAutocompleteWithRemoteData(autocompleteEndpointUrl: string): TomSelect {
129+
#createAutocompleteWithRemoteData(autocompleteEndpointUrl: string, minCharacterLength: string): TomSelect {
128130
const config: Partial<TomSettings> = this.#mergeObjects(this.#getCommonConfig(), {
129131
firstUrl: (query: string) => {
130132
const separator = autocompleteEndpointUrl.includes('?') ? '&' : '?';
@@ -142,6 +144,11 @@ export default class extends Controller {
142144
.then(json => { this.setNextUrl(query, json.next_page); callback(json.results) })
143145
.catch(() => callback());
144146
},
147+
shouldLoad: function (query: string) {
148+
const minLength = minCharacterLength ? parseInt(minCharacterLength) : 3;
149+
150+
return query.length >= minLength;
151+
},
145152
// avoid extra filtering after results are returned
146153
score: function(search: string) {
147154
return function(item: any) {

src/Autocomplete/assets/test/controller.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ describe('AutocompleteController', () => {
8181
data-testid="main-element"
8282
data-controller="check autocomplete"
8383
data-autocomplete-url-value="/path/to/autocomplete"
84+
data-autocomplete-min-characters-value="3"
8485
></select>
8586
`);
8687

src/Autocomplete/src/Form/AutocompleteChoiceTypeExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public function finishView(FormView $view, FormInterface $form, array $options)
7171
$values['max-results'] = $options['max_results'];
7272
}
7373

74+
if ($options['min_characters']) {
75+
$values['min-characters'] = $options['min_characters'];
76+
}
77+
7478
$values['no-results-found-text'] = $this->trans($options['no_results_found_text']);
7579
$values['no-more-results-text'] = $this->trans($options['no_more_results_text']);
7680

@@ -91,6 +95,7 @@ public function configureOptions(OptionsResolver $resolver)
9195
'allow_options_create' => false,
9296
'no_results_found_text' => 'No results found',
9397
'no_more_results_text' => 'No more results',
98+
'min_characters' => 3,
9499
'max_results' => 10,
95100
]);
96101

0 commit comments

Comments
 (0)