From 9490ad323b8d4815a9238eb013ca01ef574e17f3 Mon Sep 17 00:00:00 2001 From: Alejandro Cremaschi Date: Thu, 7 Mar 2024 17:28:52 -0700 Subject: [PATCH] Issue #3166: Retain field focus after autosubmit replaces a form element. By @argiepiano, @klonos, @antijingoist, @yorkshire-pudding, @indigoxela, and @quicksketch. --- core/misc/autosubmit.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/core/misc/autosubmit.js b/core/misc/autosubmit.js index c91cc20743f..4b978316757 100644 --- a/core/misc/autosubmit.js +++ b/core/misc/autosubmit.js @@ -37,12 +37,37 @@ Backdrop.behaviors.autosubmit = { attach: function(context) { // 'this' references the form element - function triggerSubmit (e) { + function triggerSubmit (element) { var $this = $(this); + + // Variable "element" will have a value only when text fields trigger + // this. If element is undefined, then remove the data to prevent + // potential focus on a previously processed element. + if (element === undefined) { + $('body').removeData('autosubmit-last-focus-id'); + } + else { + $('body').data('autosubmit-last-focus-id', $(element).attr('id')); + } + + // Submit the form. $this.find('.autosubmit-click').trigger('click'); } - // the change event bubbles so we only need to bind it to the outer form + // Listener to ajaxStop will re-focus on the text field as needed. + $(document).off('ajaxStop.autosubmit').on('ajaxStop.autosubmit', function () { + let id = $('body').data('autosubmit-last-focus-id'); + if (id === undefined) { + return; + } + let $textInput = $('#' + id); + let pos = $textInput.val().length; + $textInput.focus(); + $textInput[0].setSelectionRange(pos, pos); + $('body').removeData('autosubmit-last-focus-id'); + }); + + // The change event bubbles so we only need to bind it to the outer form. $('form.autosubmit-full-form', context) .add('.autosubmit', context) .filter('form, select, input:not(:text, :submit)') @@ -86,12 +111,14 @@ Backdrop.behaviors.autosubmit = { }) .on('keyup', function(e) { if ($.inArray(e.keyCode, discardKeyCode) === -1) { - timeoutID = setTimeout($.proxy(triggerSubmit, this.form), 500); + // Provide the target element to triggerSubmit. + timeoutID = setTimeout($.proxy(triggerSubmit, this.form, e.target), 500); } }) .on('change', function (e) { if ($.inArray(e.keyCode, discardKeyCode) === -1) { - timeoutID = setTimeout($.proxy(triggerSubmit, this.form), 500); + // Provide the target element to triggerSubmit. + timeoutID = setTimeout($.proxy(triggerSubmit, this.form, e.target), 500); } }); });