No internet connection
  1. Home
  2. How to

Enter Variable into Text or Number Field

By Kitch Membery @Kitch2019-09-07 23:12:42.934Z

Hi all,

I'm new to Javascript, so sorry if this is a Javascript 101 question.

I need to enter a variables text, or number value (eventually a loop from an array) individually from a script I have created into the "Edit Selection Length" , in the Edit Window and also into the "Rename Clip" Popup.

i.e.
When setting Var x=0.01.100
Click ui interface element then "Edit Selection Length" - Paste or type in Var x (0.01.100)

An example script would be great. Thanks
Kitch

Solved in post #2, click to view
  • 38 replies

There are 38 replies. Estimated reading time: 29 minutes

  1. No need to apologize :) We're here to help with any question big or small!

    The code to set the selection length to for example 3 seconds when in Timecode is as follows:

    sf.ui.proTools.appActivateMainWindow();
    
    sf.ui.proTools.selectionSet({
        selectionLength: '00:00:03:00'
    });
    

    If you had a variable x set to 00:00:03:00, it would look like this:

    var x = "00:00:03:00";
    sf.ui.proTools.appActivateMainWindow();
    sf.ui.proTools.selectionSet({
        selectionLength: x
    });
    
    Reply1 LikeSolution
    1. Feel free to ask more specifically as well - ie. what is the workflow you're building here?

      1. In reply tochrscheuer:
        Kitch Membery @Kitch2019-09-07 23:25:47.612Z

        Wonderful I'll try that out thank you Christian.
        Great to meet you the other night. :-) I'm really enjoying Soundflow so far!

        1. Happy to hear it! Great meeting you too :)

        2. In reply tochrscheuer:
          Kitch Membery @Kitch2019-09-07 23:43:20.096Z

          This script works great in Timecode mode but not in Mins:Secs mode.

          Is there a standard way to enter Hours. Minutes, Seconds and Miliseconds in Mins:Secs mode?

          1. Oh - good catch I see that it isn't working as expected in min:secs mode. That's a bug, we'll look into it.

            What you can do for now is to use the selectionSetTimecode action instead, which will quickly switch to Timecode while setting the length and then switch back to whatever Time base you had before.

            sf.ui.proTools.appActivateMainWindow();
            
            sf.ui.proTools.selectionSetTimecode({
                selectionLength: '00:00:03:00'
            });
            
            1. Kitch Membery @Kitch2019-09-08 21:08:45.280Z

              Thanks for that Christian. Let me know when you get a chance to fix it. Till then I have a work around.

              By pressing the "/" key 3 times allows me to get to the the "Edit Selection Length" then I can enter the "0.00.000" Mins:Secs format.

              1. In reply tochrscheuer:
                Kitch Membery @Kitch2019-09-08 23:11:40.412Z

                Once that bug is fixed and I can enter Mins:Secs" into the "Edit Selection Length" this looped array script is gonna work a treat;

                Let me know if you can see any improvements.

                //This script will cut up room tone lengths from a piece of clean room tone that is longer than the largest array value.
                
                //Set Variable Array for room tone Clip lengths.
                var myList = [
                    '00:00:01:00',
                    '00:00:02:00',
                    '00:00:03:00',
                    '00:00:04:00',
                    '00:00:05:00',
                ];
                
                //Activate Protools Main Window
                sf.ui.proTools.appActivateMainWindow();
                
                //Create loop for the Array
                for (var i = 0; i < myList.length; i++) {
                
                    //Enter Array variable into "Edit Selection Length"
                    sf.ui.proTools.selectionSet({
                        selectionLength: myList[i]
                    });
                
                    //Press the Menu Item for renaming clips.
                    sf.ui.proTools.menuClick({
                        menuPath: ["Clip", "Capture..."],
                    });
                
                    //Wait for the "Name" window to appear:
                    sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor();
                
                    //Enter "_RT " and Variable into "Name" window text field.
                    sf.ui.proTools.windows.whoseTitle.is('Name').first.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                        value: "_RT " + myList[i],
                    });
                
                    //Press Enter
                    sf.ui.proTools.windows.whoseTitle.is('Name').first.buttons.whoseTitle.is('OK').first.elementClick();
                }
                

                Room Tone Slicer 480.mov (468.41 kB)

                1. Very very nice @Kitch!
                  Great job.

                  There is room for a few improvements.
                  2 improvements that I didn't tell you about before but that will make the script slightly more stable.
                  And a few improvements to code quality/readability which I'll offer just for the Javascript lesson there is in it.

                  First things first.
                  It would make sense after you press the OK (nit: it's not Enter, but an actual button-press on the OK button) you wait for the window to disappear, just like we wait for the window to appear in the first case. This is not super important for an action like this which we can assume would always be fast, but if Pro Tools for some reason was a little slow to close the window, the selectionSet command would fail on your next iteration.

                  To wait for the "Name" window to disappear, add this at the end of your loop:

                  //Wait for "Name" window to disappear
                  sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitForNoElement: true });
                  

                  The 2nd functional improvement to the script is to add this line of code at the start of your loop:

                  sf.engine.checkForCancellation();
                  

                  This line will check to make sure that the user didn't ask for us to cancel the command (for example by pressing Ctrl+Shift+Escape with default SoundFlow triggers enabled).
                  It's always a good idea to include this at the beginning of long-running loops.

                  Now your entire script looks like this:

                  //This script will cut up room tone lengths from a piece of clean room tone that is longer than the largest array value.
                  
                  //Set Variable Array for room tone Clip lengths.
                  var myList = [
                      '00:00:01:00',
                      '00:00:02:00',
                      '00:00:03:00',
                      '00:00:04:00',
                      '00:00:05:00',
                  ];
                  
                  //Activate Protools Main Window
                  sf.ui.proTools.appActivateMainWindow();
                  
                  //Create loop for the Array
                  for (var i = 0; i < myList.length; i++) {
                      sf.engine.checkForCancellation();
                  
                      //Enter Array variable into "Edit Selection Length"
                      sf.ui.proTools.selectionSet({
                          selectionLength: myList[i]
                      });
                  
                      //Press the Menu Item for renaming clips.
                      sf.ui.proTools.menuClick({
                          menuPath: ["Clip", "Capture..."],
                      });
                  
                      //Wait for the "Name" window to appear:
                      sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor();
                  
                      //Enter "_RT " and Variable into "Name" window text field.
                      sf.ui.proTools.windows.whoseTitle.is('Name').first.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                          value: "_RT " + myList[i],
                      });
                  
                      //Click OK
                      sf.ui.proTools.windows.whoseTitle.is('Name').first.buttons.whoseTitle.is('OK').first.elementClick();
                  
                      //Wait for "Name" window to disappear
                      sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitForNoElement: true });
                  }
                  

                  I'll add the mechanical (non-functional) improvement suggestions in my next post.

                  1. In reply tochrscheuer:

                    For the mechanical improvements:

                    1. Rename myList to something more descriptive, for example loopLengths. This is a general rule - choosing good names is half of coding since you're essentially distilling the concept, ie. what does this variable describe.
                    2. Instead of referring to myList[i] multiple times in your loop, assign myList[i] to a variable (myItem, or loopLength) in the beginning of the loop and refer to that. This improves readability and makes it easier to make other changes later.
                    3. Lastly, since we're referring to the "Name" window multiple times in the last half of the loop, we can do what's known as "Common Subexpression Elimination" or variable harvesting. Basically, assign sf.ui.proTools.windows.whoseTitle.is('Name').first to a variable that you can name nameWindow and then use that variable to access the window.


                    I'm posting a little gif here of the process. Note since this is a purely mechanical change, there's no functional change to the script, it's only about improving the code quality.


                    1. Here's the script with my mechanical changes:

                      //This script will cut up room tone lengths from a piece of clean room tone that is longer than the largest array value.
                      
                      //Set Variable Array for room tone Clip lengths.
                      var loopLengths = [
                          '00:00:01:00',
                          '00:00:02:00',
                          '00:00:03:00',
                          '00:00:04:00',
                          '00:00:05:00',
                      ];
                      
                      //Activate Protools Main Window
                      sf.ui.proTools.appActivateMainWindow();
                      
                      //Create loop for the Array
                      for (var i = 0; i < loopLengths.length; i++) {
                          var loopLength = loopLengths[i];
                      
                          //Check if user cancelled our command. This will stop the script if the user cancelled
                          sf.engine.checkForCancellation();
                      
                          //Enter Array variable into "Edit Selection Length"
                          sf.ui.proTools.selectionSet({
                              selectionLength: loopLength
                          });
                      
                          //Press the Menu Item for renaming clips.
                          sf.ui.proTools.menuClick({
                              menuPath: ["Clip", "Capture..."],
                          });
                      
                          //Define "Name" window variable
                          var nameWindow = sf.ui.proTools.windows.whoseTitle.is('Name').first;
                      
                          //Wait for the "Name" window to appear:
                          nameWindow.elementWaitFor();
                      
                          //Enter "_RT " and Variable into "Name" window text field.
                          nameWindow.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                              value: "_RT " + loopLength,
                          });
                      
                          //Click OK
                          nameWindow.buttons.whoseTitle.is('OK').first.elementClick();
                      
                          //Wait for "Name" window to disappear
                          nameWindow.elementWaitFor({ waitForNoElement: true });
                      }
                      
                      1. In reply tochrscheuer:
                        Kitch Membery @Kitch2019-09-08 23:38:55.788Z

                        Awesome! I shall implement all of these mechanical improvements.

                        1. Kitch Membery @Kitch2019-09-09 00:04:09.691Z

                          It seems that the var loopLength = loopLengths[i]; mechanical changes broke the script. As it is breaking down at line 24.

                          1. I don't think that's the source of the error. The script works fine here (as long as I'm in Timecode mode before running the script).
                            If you want it to work in min:secs mode you'll need to change the selectionSet to selectionSetTimecode

                            1. Kitch Membery @Kitch2019-09-09 00:09:39.192Z

                              As soon as I posted my last post, I realized I had changed it back to Min:Secs.... Sorry for that.

                              1. No problem :)

                                1. For this case, actually let's make another change to the script.
                                  All actions in SoundFlow take a 2nd parameter where you can add the error message it should show if the action fails.
                                  The 1st parameter is the {...} stuff, so after the closing curly bracket, you can add the error message.
                                  So change these lines:

                                    sf.ui.proTools.selectionSet({
                                          selectionLength: loopLength
                                      });
                                  

                                  to:

                                    sf.ui.proTools.selectionSet({
                                          selectionLength: loopLength
                                      }, "Could not set selection. Are you in Timecode mode?");
                                  

                                  And if you're in min:secs mode or the selection set fails for any other reason, it will show the error message "Could not set selection. Are you in Timecode mode?"

                                  1. Kitch Membery @Kitch2019-09-09 00:25:20.919Z

                                    You are too good mate!!

                                  2. In reply tochrscheuer:
                                    Kitch Membery @Kitch2019-09-09 20:50:32.196Z

                                    How do I switch the Counter display from Timecode to Min:Secs, Bars:Beats, Samples, Feet+Frames etc?

                                    1. For example like this:

                                      sf.ui.proTools.mainCounterSetValue({
                                          targetValue: 'Timecode'
                                      });
                                      
                                      sf.ui.proTools.mainCounterSetValue({
                                          targetValue: 'Min:Secs'
                                      });
                                      
                                      //Etc..
                                      

                                      The string needs to correspond to the View->Main Counter->... menu items.

                                      1. Kitch Membery @Kitch2019-09-10 03:51:42.134Z

                                        Perfect!... Here is my updated code with an "If then else" to change the name of the last piece of room tone to "_Fill". I have also added a hack to get the Min:Secs entry into the "Edit Loop Selection" (It seems that it wanted an extra "0." before it would accept the Minutes, Seconds, Miliseconds.

                                        //This script will cut up room tone lengths from a piece of clean room tone that is longer than the largest array value.
                                        
                                        //Set Variable Array for room tone Clip lengths.
                                        var loopLengths = [
                                            '0.00.400',
                                            '0.00.500',
                                            '0.00.600',
                                            '0.00.700',
                                            '0.00.800',
                                            '0.00.900',
                                            '0.01.000',
                                            '0.01.100',
                                            '0.01.200',
                                            '0.01.300',
                                            '0.01.400',
                                            '0.01.500',
                                            '0.01.600',
                                            '0.01.700',
                                            '0.01.800',
                                            '0.01.900',
                                            '0.02.000',
                                            '0.02.500',
                                            '0.04.000',
                                            '0.04.000',
                                        ];
                                        
                                        //Create variable for Min:Secs input into Edit Selection Length field. (Till Bug is fixed)
                                        var timehack = '0.';
                                        
                                        //Activate Protools Main Window
                                        sf.ui.proTools.appActivateMainWindow();
                                        
                                        //Set main Counter to Min:Secs view
                                        sf.ui.proTools.mainCounterSetValue({
                                            targetValue: 'Min:Secs'
                                        });
                                        
                                        //Create loop for the Array
                                        for (var i = 0; i < loopLengths.length; i++) {
                                            var loopLength = loopLengths[i];
                                        
                                            //Check if user cancelled our command. This will stop the script if the user cancelled
                                            sf.engine.checkForCancellation();
                                        
                                            //Select the Edit Selection Length Field
                                            sf.ui.proTools.mainWindow.groups.whoseTitle.is('Counter Display Cluster').first.textFields.whoseTitle.is('Edit Selection Length').first.elementClick({});
                                        
                                            //Enter Array variable into "Edit
                                            sf.keyboard.type({
                                                text: timehack + loopLength
                                            });
                                        
                                            //Press return to make Edit Selection Length accept loopLength
                                            sf.keyboard.press({
                                                keys: "return"
                                            });
                                        
                                            //Enter Array variable into "Edit Selection Length" (Disabled this step till bug is fixed)
                                            //sf.ui.proTools.selectionSet({
                                            //    selectionLength: loopLength
                                            //});
                                        
                                            //Press the Menu Item for renaming clips.
                                            sf.ui.proTools.menuClick({
                                                menuPath: ["Clip", "Capture..."],
                                            });
                                        
                                            //Define "Name" window variable
                                            var nameWindow = sf.ui.proTools.windows.whoseTitle.is('Name').first;
                                        
                                            //Wait for the "Name" window to appear:
                                            nameWindow.elementWaitFor();
                                        
                                            //Lables the last array item as "_Fill"
                                            if (i == loopLengths.length - 1) {
                                        
                                                //Enter "_RT " and Variable into "Name" window text field.
                                                nameWindow.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                                                    value: '_Fill',
                                                });
                                        
                                                //Click OK
                                                nameWindow.buttons.whoseTitle.is('OK').first.elementClick();
                                        
                                                //Wait for "Name" window to disappear
                                                nameWindow.elementWaitFor({ waitForNoElement: true });
                                        
                                            } else {
                                        
                                                //Enter "_RT " and Variable into "Name" window text field.
                                                nameWindow.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                                                    value: "_RT " + loopLength,
                                                });
                                        
                                                //Click OK
                                                nameWindow.buttons.whoseTitle.is('OK').first.elementClick();
                                        
                                                //Wait for "Name" window to disappear
                                                nameWindow.elementWaitFor({ waitForNoElement: true });
                                            }
                                        }
                                        
                                        
                                        

                                        My next step is to get the room tone and fill to export and reimport as whole audio files.

                                        Thanks a million for your help Christian :-)

                                        1. Sounds great, @Kitch!
                                          You should definitely publish this as part of a package some time :)

                                          1. Kitch Membery @Kitch2019-09-10 04:09:06.665Z

                                            Absolutly!

                                            1. In reply tochrscheuer:
                                              Kitch Membery @Kitch2019-09-13 03:24:13.266Z

                                              Christian, Sorry to bother you... I just tried to run this script today and It could not get past Line 93 (it was working yesterday and I dont remember changing anything). Would you be able to to take a look at it. I must have accidently changed somthing before I saved it.
                                              Rock on
                                              Kitch

                                              //This script will cut up room tone lengths from a piece of clean room tone that is longer than the largest array value.
                                              
                                              //Set Variable Array for room tone Clip lengths.
                                              var loopLengths = [
                                                  '0.00.400',
                                                  '0.00.500',
                                                  '0.00.600',
                                                  '0.00.700',
                                                  '0.00.800',
                                                  '0.00.900',
                                                  '0.01.000',
                                                  '0.01.100',
                                                  '0.01.200',
                                                  '0.01.300',
                                                  '0.01.400',
                                                  '0.01.500',
                                                  '0.01.600',
                                                  '0.01.700',
                                                  '0.01.800',
                                                  '0.01.900',
                                                  '0.02.000',
                                                  '0.02.500',
                                                  '0.04.000',
                                                  '0.04.000',
                                              ];
                                              
                                              //Create variable for Min:Secs input into Edit Selection Length field. (Till Bug is fixed)
                                              var timehack = '0.';
                                              
                                              //Activate Protools Main Window
                                              sf.ui.proTools.appActivateMainWindow();
                                              
                                              //Set main Counter to Min:Secs view.
                                              sf.ui.proTools.mainCounterSetValue({
                                                  targetValue: 'Min:Secs'
                                              });
                                              
                                              //Create loop for the Array
                                              for (var i = 0; i < loopLengths.length; i++) {
                                                  var loopLength = loopLengths[i];
                                              
                                                  //Check if user cancelled our command. This will stop the script if the user cancelled
                                                  sf.engine.checkForCancellation();
                                              
                                                  //Select the Edit Selection Length Field
                                                  sf.ui.proTools.mainWindow.groups.whoseTitle.is('Counter Display Cluster').first.textFields.whoseTitle.is('Edit Selection Length').first.elementClick({});
                                              
                                                  //Enter Array variable into "Edit
                                                  sf.keyboard.type({
                                                      text: timehack + loopLength
                                                  });
                                              
                                                  //Press return to make Edit Selection Length accept loopLength
                                                  sf.keyboard.press({
                                                      keys: "return"
                                                  });
                                              
                                                  //Enter Array variable into "Edit Selection Length" (Disabled this step till bug is fixed)
                                                  //sf.ui.proTools.selectionSet({
                                                  //    selectionLength: loopLength
                                                  //});
                                              
                                              
                                                  //Press the Menu Item for renaming clips.
                                                  sf.ui.proTools.menuClick({
                                                      menuPath: ["Clip", "Capture..."],
                                                  });
                                              
                                                  //Define "Name" window variable
                                                  var nameWindow = sf.ui.proTools.windows.whoseTitle.is('Name').first;
                                              
                                                  //Wait for the "Name" window to appear:
                                                  nameWindow.elementWaitFor({ waitForNoElement: true });
                                              
                                                  //Lables the last array item as "_Fill"
                                                  if (i == loopLengths.length - 1) {
                                              
                                                      //Enter "_RT " and Variable into "Name" window text field.
                                                      nameWindow.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                                                          value: '_Fill',
                                                      });
                                              
                                                      //Click OK
                                                      nameWindow.buttons.whoseTitle.is('OK').first.elementClick();
                                              
                                                      //Wait for "Name" window to disappear
                                                      nameWindow.elementWaitFor({ waitForNoElement: true });
                                              
                                                  } else {
                                              
                                                      //Enter "_RT " and Variable into "Name" window text field.
                                                      nameWindow.groups.whoseTitle.is('Name').first.textFields.whoseTitle.is('').first.elementSetTextFieldWithAreaValue({
                                                          value: "_RT " + loopLength,
                                                      });
                                              
                                                      //Click OK
                                                      nameWindow.buttons.whoseTitle.is('OK').first.elementClick();
                                              
                                                      //Wait for "Name" window to disappear
                                                      nameWindow.elementWaitFor({ waitForNoElement: true });
                                                  }
                                              }
                                              
                                              
                2. In reply tochrscheuer:
                  Kitch Membery @Kitch2019-09-08 00:38:22.610Z

                  Also, How do you enter a Variables Text or Value into the menu Item Clip>Capture... "Rename" popup. Thanks again.

                  1. Kitch Membery @Kitch2019-09-08 09:36:46.893Z2019-09-08 20:34:49.212Z

                    I figured out how to get the variable into the text field (using sf.keyboard.type function).... Unless there is a better way?

                    sf.ui.proTools.appActivateMainWindow();
                    
                    var x = "00:00:03:00";
                    
                    sf.ui.proTools.selectionSet({
                        selectionLength: x
                    });
                    
                    sf.ui.proTools.menuClick({
                        menuPath: ["Clip", "Capture..."],
                    });
                    
                    sf.keyboard.type({
                        text: x
                    });
                    
                    1. Interesting! I don't know what the Capture dialog does.. How do I bring it up - mine is greyed out?

                      1. Kitch Membery @Kitch2019-09-08 21:03:26.992Z

                        It brings up the Rename popup. It is grey until you have to have a selection of audio selected. :-)

                        1. I see. Ok so the best way to set the value of that text field is like this:

                          sf.ui.proTools.windows.whoseTitle.is('Name').first.groups.whoseTitle.is('Name').first.textFields.first.elementSetTextFieldWithAreaValue({
                              value: "test 1.2.3",
                          });
                          

                          This is how I got that code:

                          --

                          But first you'll need to wait for the window to appear. (In a macro this would be the "Wait for UI Element" action.
                          In code this all looks like this:

                          
                          sf.ui.proTools.menuClick({
                              menuPath: ["Clip", "Capture..."],
                          });
                          
                          //Wait for the window to appear:
                          sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor();
                          
                          //Now set the Name to the value of the x variable
                          sf.ui.proTools.windows.whoseTitle.is('Name').first.groups.whoseTitle.is('Name').first.textFields.first.elementSetTextFieldWithAreaValue({
                              value: x,
                          });
                          
                          //Click OK
                          sf.ui.proTools.windows.whoseTitle.is('Name').first.buttons.whoseTitle.is('OK').first.elementClick();
                          
                          1. Kitch Membery @Kitch2019-09-08 22:27:42.231Z

                            Out of interest... How do I make my coding show up as a script, and not as plain text in the forum?

                            1. You use 3 backticks on a line by itself, before and after the code, like this: ```
                              You can edit your posts to see how I did it :)

                              1. Kitch Membery @Kitch2019-09-08 22:29:50.596Z

                                Thanks Legend!

                3. Progress
                4. Confirmed: Setting selection in min:secs mode is going to work in 3.0.1.

                  1. Kitch Membery @Kitch2019-09-18 06:05:14.055Zreplies tochrscheuer:

                    You are a legend! Thank you Christian :-)

                    1. Kitch Membery @Kitch2019-09-21 23:47:44.917Zreplies tochrscheuer:

                      Hi Christian,

                      I've tried the following code in Soundflow 3.0.1 and setting the Edit Selection Length in Min:Secs is still not working.

                      var clipDuration = "0.04.400";
                      
                      //Activate Pro Tools Main Window
                      sf.ui.proTools.appActivateMainWindow();
                      
                      //Set main Counter to Min:Secs view.
                      sf.ui.proTools.mainCounterSetValue({
                          targetValue: 'Min:Secs'
                      });
                      
                      //Set the Edit Selection Length to clipDuration.
                      sf.ui.proTools.selectionSet({
                          selectionLength: clipDuration
                      });
                      

                      When you have a chance, could you take a look at my code just in case I've made an error.

                      Rock on
                      Kitch

                      1. Christian Scheuer @chrscheuer2019-09-22 02:54:24.642Zreplies toKitch:

                        Hi @Kitch

                        You had an error in the format, it needs to be m:ss.fff (ie. colon instead of dot):

                        If you fix your first line to this, it should work:

                        var clipDuration = "0:04.400";
                        
                        1. Kitch Membery @Kitch2019-09-22 04:17:44.213Zreplies tochrscheuer:

                          Perfect. Thank you.