Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-66530

Creating new item job cursor annoyingly jumps to top entry box if "Copy from" is completed while "Item name" is empty

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • core
    • None
    • 2.441

      With Jenkins 2.289.2 creating a new job from another job is annoying (using Firefox).

      If I start typing in the "Copy From" box, it quickly jumps to the top "new name" box messing up my type. Then I have to delete the mistake and go back to the box I want to type in. This can happen more than once sometimes and then finally I get the focus to type in the box. I don't get why this would happen. I should not have to type the new name first.

      Typically, I want to find a job using the type ahead feature in the from box to see existing jobs. Then I cut and paste the name to new name where I will then change the name (such as ProjABuild5 to ProjBBuild5). And then I have to de-select the "Add to view" but that would be a separate issue I guess (why is that always defaulted on?).

      While this is minor, it sure is annoying.

          [JENKINS-66530] Creating new item job cursor annoyingly jumps to top entry box if "Copy from" is completed while "Item name" is empty

          Mark Waite added a comment - - edited

          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.

          Mark Waite added a comment - - edited 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.

          HerveLeMeur added a comment -

          Got the same behavior in Firefox 110.0.1 and Jenkins 2.375.3 (current LTS) and 2.393 (current Weekly), quite annoying indeed.

          HerveLeMeur added a comment - Got the same behavior in Firefox 110.0.1 and Jenkins 2.375.3 (current LTS) and 2.393 (current Weekly), quite annoying indeed.

          Stefan added a comment -

          This repeatedly annoys my users and me. I have traced this back to the function call setTimeout() in add-item.js line 336 (current master):
          https://github.com/jenkinsci/jenkins/blob/8cbe60bc2f7d35e66b007975f5277cd81b7917f3/war/src/main/js/add-item.js#L336

          If I remove that setTimeout call completely and rebuild jenkins, the behaviour no longer occurs.

          As far as I understand that part of the code, that call is expendable. Would this be a viable solution?

          Stefan added a comment - This repeatedly annoys my users and me. I have traced this back to the function call setTimeout() in add-item.js line 336 (current master): https://github.com/jenkinsci/jenkins/blob/8cbe60bc2f7d35e66b007975f5277cd81b7917f3/war/src/main/js/add-item.js#L336 If I remove that setTimeout call completely and rebuild jenkins, the behaviour no longer occurs. As far as I understand that part of the code, that call is expendable. Would this be a viable solution?

          Mark Waite added a comment -

          As far as I understand that part of the code, that call is expendable. Would this be a viable solution?

          I'm not confident that will be a viable solution. I think that you may not be understanding all the places where that code is used.

          Have you checked the impact of deleting that timeout on:

          • Create a new freestyle job, wait for the timeout, then press tab to attempt to create a Freestyle job with an empty name
          • Create a new Pipeline job, do not wait for the timeout, then click OK to create a Pipeline job with an empty name
          • Create a new organization folder
          • Create a new matrix project
          • Create a new external job

          Mark Waite added a comment - As far as I understand that part of the code, that call is expendable. Would this be a viable solution? I'm not confident that will be a viable solution. I think that you may not be understanding all the places where that code is used. Have you checked the impact of deleting that timeout on: Create a new freestyle job, wait for the timeout, then press tab to attempt to create a Freestyle job with an empty name Create a new Pipeline job, do not wait for the timeout, then click OK to create a Pipeline job with an empty name Create a new organization folder Create a new matrix project Create a new external job

          Stefan added a comment -

          Thanks for the quick feedback. While I believe to understand your doubts, I would contest them, since this timeout/focus is only within the context of the CopyFromField, and only if the NameField is invalid/empty. I don't get the point why one would want the focus to switch to the NameField in this situation.

          But I shall walk through your test cases, maybe a second time after editing line 337 to refer to the "from" field instead of the "name" field. Then I shall get back, hopefully in a few days. 

          Stefan added a comment - Thanks for the quick feedback. While I believe to understand your doubts, I would contest them, since this timeout/focus is only within the context of the CopyFromField, and only if the NameField is invalid/empty. I don't get the point why one would want the focus to switch to the NameField in this situation. But I shall walk through your test cases, maybe a second time after editing line 337 to refer to the "from" field instead of the "name" field. Then I shall get back, hopefully in a few days. 

          Stefan added a comment -

          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) {
                          //if "name" is invalid, but "from" is a valid job, then switch focus to "name"
                          $('input[name="name"][type="text"]', "#createItem").focus();
                        }
                      })
                    }, 400);
          

          Stefan added a comment - 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) { // if "name" is invalid, but "from" is a valid job, then switch focus to "name" $( 'input[name= "name" ][type= "text" ]' , "#createItem" ).focus(); } }) }, 400);

          Mark Waite added a comment -

          Thanks very much dsrink. My interactive testing of your pull request detected no issues either. I ran my tests with the web developer console open and saw no unexpected messages. I've approved the pull request. Since it is a JavaScript change, the Jenkins security team may also want to review it.

          Mark Waite added a comment - Thanks very much dsrink . My interactive testing of your pull request detected no issues either. I ran my tests with the web developer console open and saw no unexpected messages. I've approved the pull request. Since it is a JavaScript change, the Jenkins security team may also want to review it.

            Unassigned Unassigned
            catonyx Todd B
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: