Skip to content

Commit 54cdfa6

Browse files
committed
Completer: Move autosubmit logic into the timer onFocusOut
1 parent a195165 commit 54cdfa6

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

asset/js/widget/Completer.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ define(["../notjQuery"], function ($) {
269269

270270
complete(input, value, data) {
271271
$(input).focus({ scripted: true });
272-
this.hasBeenManuallyChanged = false;
273272

274273
if (this.instrumented) {
275274
if (! Object.keys(data).length) {
@@ -323,8 +322,12 @@ define(["../notjQuery"], function ($) {
323322

324323
if (! stopAtEdge && this.completedValue !== null) {
325324
if (input === this.completedInput) {
325+
// Re-enable autosubmit for the input in non-instrumented mode when the user moves from suggestions back to the input.
326+
this.hasBeenManuallyChanged = true;
326327
this.suggest(this.completedInput, this.completedValue);
327328
} else {
329+
// Disable the autosubmit for the input in non-instrumented mode while moving through suggestions.
330+
this.hasBeenManuallyChanged = false;
328331
this.suggest(this.completedInput, input.value, { ...input.dataset });
329332
}
330333
}
@@ -478,16 +481,22 @@ define(["../notjQuery"], function ($) {
478481
}
479482

480483
onFocusOut(event) {
481-
// Autosubmit if the user leaves the input and the input has been manually changed.
482-
// Only for non-instrumented mode — instrumented inputs (e.g. TermInput) handle
483-
// autosubmit themselves via BaseInput.autoSubmit() with proper term data.
484-
if (! this.instrumented && this.hasBeenManuallyChanged && this.shouldAutoSubmit()) {
485-
this.hasBeenManuallyChanged = false;
486-
let input = event.target;
487-
setTimeout(() => {
488-
$(input.form).trigger('submit', { submittedBy: input });
489-
}, 300);
490-
}
484+
setTimeout(() => {
485+
// Autosubmit if the user leaves the input and the input has been manually changed.
486+
// Only for non-instrumented mode — instrumented inputs (e.g. TermInput) handle
487+
// autosubmit themselves via BaseInput.autoSubmit() with proper term data.
488+
if (
489+
! this.instrumented
490+
&& this.hasBeenManuallyChanged
491+
&& ! this.hasSuggestions()
492+
&& this.shouldAutoSubmit()
493+
) {
494+
// Reset this flag since the user has navigated away from the input and the submit event
495+
// will be triggered by the input's form submit event handler.
496+
this.hasBeenManuallyChanged = false;
497+
$(this.input.form).trigger('submit', {submittedBy: this.input});
498+
}
499+
}, 300);
491500

492501
if (this.completedInput === null) {
493502
// If there are multiple instances of Completer bound to the same suggestion container
@@ -511,6 +520,9 @@ define(["../notjQuery"], function ($) {
511520
}
512521

513522
this.hideSuggestions();
523+
524+
// This triggers the autosubmit if the user navigates away from the input for non-instrumented mode.
525+
// as the input is reset to the manually changed value once suggestions are hidden.
514526
this.hasBeenManuallyChanged = true;
515527
}
516528
}, 250);
@@ -645,6 +657,11 @@ define(["../notjQuery"], function ($) {
645657

646658
onKeyDown(event) {
647659
let suggestions;
660+
const keys = ['Tab', 'ArrowDown', 'ArrowUp'];
661+
if (keys.includes(event.key) && (event.target === this.input && this.hasSuggestions())) {
662+
// Disable the autosubmit if the user navigates away from the input but is within the suggestions.
663+
this.hasBeenManuallyChanged = false;
664+
}
648665

649666
switch (event.key) {
650667
case ' ':
@@ -669,7 +686,6 @@ define(["../notjQuery"], function ($) {
669686
break;
670687
case 'Tab':
671688
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
672-
this.hasBeenManuallyChanged = false;
673689
if (suggestions.length === 1) {
674690
event.preventDefault();
675691
let input = event.target;
@@ -691,15 +707,16 @@ define(["../notjQuery"], function ($) {
691707
break;
692708
case 'Escape':
693709
if (this.hasSuggestions()) {
710+
this.hideSuggestions();
711+
// This triggers the autosubmit if the user navigates away from the input for non-instrumented mode.
712+
// as the input has the manually changed value.
694713
this.hasBeenManuallyChanged = true;
695-
this.hideSuggestions()
696714
event.preventDefault();
697715
}
698716

699717
break;
700718
case 'ArrowUp':
701719
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
702-
this.hasBeenManuallyChanged = false;
703720
if (suggestions.length) {
704721
event.preventDefault();
705722
this.moveToSuggestion(true);
@@ -708,7 +725,6 @@ define(["../notjQuery"], function ($) {
708725
break;
709726
case 'ArrowDown':
710727
suggestions = this.termSuggestions.querySelectorAll('[type="button"]');
711-
this.hasBeenManuallyChanged = false;
712728
if (suggestions.length) {
713729
event.preventDefault();
714730
this.moveToSuggestion();
@@ -730,8 +746,6 @@ define(["../notjQuery"], function ($) {
730746

731747
onInput(event) {
732748
let input = event.target;
733-
this.hasBeenManuallyChanged = true;
734-
735749
if (input.minLength > 0 && input.value.length < input.minLength) {
736750
return;
737751
}
@@ -749,6 +763,9 @@ define(["../notjQuery"], function ($) {
749763
dataElement.value = input.value;
750764
}
751765

766+
// This flag triggers the autosubmit if the user navigates away from the input for non-instrumented mode
767+
// and the input has the manually changed value.
768+
this.hasBeenManuallyChanged = true;
752769
let [value, data] = this.prepareCompletionData(input);
753770
this.completedInput = input;
754771
this.completedValue = value;

0 commit comments

Comments
 (0)