As requested, I have tested and analysed the scenarios described in Marks comment from 2023-11-22.
It took me a few weeks since priorities at my customer had shifted.
My tests show that removing the setTimeout/focus call in L336/L337/L338 of add-item.js is safe and does not seem to create side effects. Further details can be read below the horizontal separator line, if needed.
As an alternate solution (referred by "CS6" below), I have enhanced that setTimeout call to check whether the "from" field points to an existing job.
Only if this condition is true, the focus is switched to the "name" field. Note that the setTimeout call is only reached if the "name" field is invalid.
The details below also contain a rationale and a code snippet for this idea.
Mark, it would be great if you could approve either of these approaches. Then I would submit a pull request.
Test scenarios:
- T1: Create a new freestyle job, wait for the timeout, then press tab to attempt to create a Freestyle job with an empty name
- T2: Create a new Pipeline job, do not wait for the timeout, then click OK to create a Pipeline job with an empty name
- T3: Create a new organization folder
- T4: Create a new matrix project
- T5: Create a new external job
I have tested several code situations / changes:
- CS1: unchanged jenkins-2.426.2 (latest LTS at time of testing)
- CS2: change setTimeout to focus "from" field instead of "name" field
- CS3: remove setTimeout call
- (CS4 and CS5 were further debugging which is not relevant here)
- CS6: enhance setTimeout with validation of "from" field, switch focus only if job in "from" exists
preconditions before each test:
- before testing new CS:
- git clean -xdf, create new local branch from base (used jenkins-2.246.2 at time of testing)
- prepare new code state, commit to local branch
- build .war file with "mvn -am -pl war,bom -Pquick-build clean install" (as given by CONTRIBUTING.md)
- remove all existing jobs from JENKINS_HOME
- restart jenkins with new/apropriate .war file
- select apropriate plugins, if not yet done
- make sure at least one (dummy) job exists, otherwise the "copy from" field would be hidden
- reload /view/all/newJob page so that both fields are empty and validationMessage is clean/empty
Test notes:
- CS1 / base test:
- T1: successfully copied fsjob1->fsjob2
- T2: creating job with empty name is not possible (submit button disabled), successfully created new pipelinejob1
- T3: successfully created new orgfolder1
- T4: successfully created new matrixjob1
- T5: successfully created new extjob1
- CS2: if "from" field is filled and "name" field is empty, then focus always jumps to "from" after timeout. ==> not useful.
- CS3 (remove setTimeout with focus)
- having empty "name", editing "from" shows the validationMessage, but focus stays on "from" (as desired).
- However, clicking any of "Free Style", "pipeline", "External Job" et al. shows the validationMessage but switches focus on "name".
- Either way, submit button is enabled in only legitimate cases, and disabled otherwise.
- While I was able to trick the form into trying to create an already-existing project, this failed with a proper error message on the next step.
- Other results of CS1 apply identically.
- the situations T3 / T4 / T5 do not interact with the "from" field (only with the "item" radio selection). Therefore, changing the setTimeout call cannot have any effect on those situations.
Rationale for the code change of CS6:
- problem is the ambiguity of the "input" event on the "from" field, which cannot differentiate a regular keystroke from the autocompletion selection
- It would help have an event after selecting the autocompletion.
- However, autocompletion in /lib/form/textbox (referenced in newJob.jelly) does not seem to provide such a mechanism or event
- alternate idea: verify that the job name in "from" field is existing before switching focus
CS6 code change in add-item.js:
setTimeout(function () {
var parentName = $('input[name="from"]', "#createItem").val();
$.get("job/" + parentName + "/api/json?tree=name").done(function (data) {
if (data.name === parentName) {
$('input[name="name"][type="text"]', "#createItem").focus();
}
})
}, 400);
Thanks for the report. I see the same behavior in Google Chrome with 2.303.1 and with Jenkins 2.277.4.
If I leave the "Item name" field empty and start typing in the "Copy from" field, after a few characters the focus shifts from the "Copy from" field to the item name field. The workaround is to enter a non-empty string in the item name field, then use the type ahead that is available in the "Copy from" field to complete it, then return to the item name field to enter the final desired name.