How can I access a variable defined in Modifiers Tab in Button's JScript?

Can I reference a variable defined in the Modifiers tab of a button script? For example I want to leverage variables set with @set modifier and then retrieve them within a button's OnClick JScript (without a User Command and Template or global variables).

Clarification:

I tried the following JScript code, but it did not work.

// Modifiers Tab in Button Command Editor
@Set: ScriptName = "01.01 Performance"
//Script Code tab in Button Command Editor - JScript Button Code
function OnClick(clickData) {
    // Retrieve the ScriptName variable set in the Modifiers tab
    var scriptName = clickData.func.command.vars.Exists("ScriptName");

    if (scriptName) {
        DOpus.Output("ScriptName is: " + scriptName);
    } else {
        DOpus.Output("ScriptName variable not found.");
    }
}

Use Case:

The variable I am setting is also used a one of several conditions for @enableIf modifier command.

Additional Info:

Func Object

Might be able to do it with a certain scope, like I think you can do it with global variables at least.

I keep a personal collection of random script and function examples I've made that I can reference, and this is what I have noted in the past for global variables usage in standard functions:

// Can set arbitrary global variables like this. 'Whatever' is a string, no quotes needed
@set glob:CommandExitCode=whatever

//// Can set global variables in JScript like
//DOpus.vars.Set("CommandExitCode", exitCode);

// Testing if a global variable is set
@if:$glob:CommandExitCode
// Optionally can do an else after
@if:else
// Note: To end an if block can do. Code below this will always execute
@if:common

// Can compare global variable to another variable like:
@if:&&exitCode&&=0
@Output Here I am

// Using a global variable, normal variable notation
@Output Initial Test: {$glob:CommandExitCode}

// Can run external command which can set the global variable which you can use here
RunCommandGetExitCode COMMAND="cmd.exe /k @echo 'Hello, World!'"

// Store the global variable value in a local variable
@set exitCode={$glob:CommandExitCode}
@Output {$exitCode}

So apparently you can set variables in JScript like this, and you could Get them in a similar way.

//// Can set global variables in JScript like
DOpus.vars.Set("CommandExitCode", exitCode);

And then presumably for your specific case, you could try to see if maybe the variables you set in the modifiers tab show up in the script scope?

Note I don't know if all the stuff in my notes are 100% accurate so you'll want to test each thing yourself.

Edit: Actually it seems like maybe the Script object isn't accessible to user command script functions, but only add-in scripts (could be wrong though), so global variables via DOpus.vars might be the only way to do it, not sure.

That being said this wiki page mentions using resources like those defined in the resources tab via Script.LoadResources which implies access to the Script object.

Thank you for your detailed response.

Although global scopes do work, that solution does not work in my use case.

This is because a global variable requires using a unique global variable for every button script.

Instead of global variables, I simply want to access the script variable name. the script variable name is the same across all of the buttons, although the variable's value is unique.

Therefore, given your suggestions, I have updated my original question and detail to include not using global variables.

You mean unique as different in each button ?

As a side note :
It seems you're struggling with that kind of goal in many posts.
The thing is, every time you come with a very deep and specific question about something you want to do that does not really seem possible.
Maybe you could expose what you're trying to achieve globally from a full and high level perspective and see if anyone has an idea about how to reach that goal (which could be quite different from the routes you've explored so far, apparently without fully succeeding, but I may be wrong).

Here's an idea. Instead of embedding a script in a button (or several), you can simply create a user command, which can receive as arguments any values you want to send to it.

That's the kind of thing I have in mind, but it seems that @grosner wants (at some point) to be able to use the variables in @enableif.

Moreover, he specifically requests not to use User Command ... but we don't really know why, hence my suggestion to submit the overall goal he is trying to achieve rather than bits and pieces, adding more constraints as solutions are proposed not going along with that unknown (at least to us) goal.

Thanks again for the feedback. It is very much appreciated.

Use Case - Clarification:

  1. Goal: Conditionally toggle enabling a menu button in a drop down set of button items.
  2. Desire: Reference variable defined in Modifier tab (and @enableIf) so there is a single location where the variable's value is defined.

That's all there is to my use case!!!

Here's a simplified example of the undesired workaround (duplicating the variable's definition):

// Modifier Tab: Enable button if window exists or if ctrl key is pressed when button is clicked.
@eval: GridName = "03.00 Indices"
@enableif:=KeyDown("ctrl") || FindWindow("",GridName)
// Call the common button script with GridName argument.
function OnClick(clickData)
{      
   GridName = "03.00 Indices";
   commandString = "ShowSDProfile " +  '"'+GridName+'"';
   var cmd = clickData.func.command;
   cmd.RunCommand(commandString);
}

Imagine having several more variables and many more buttons to maintain, and I think you can understand the desire for having one place to define the variable's value (for each button's script).

Again, thanks for your feedback.

I'll have to give this a try, but if I understand correctly, you defined a user command ShowDSProfile that creates some window with a name you give as a parameter.

What if, instead of a script button, you transform your button in a Standard function (Opus or external) ?
In that case, you loose the "modifier" tab, but can still enter modifiers.
Your button "code" can then be :

@enableif:=KeyDown("ctrl") || FindWindow("","MyWindowNameForThisButton")
ShowSDProfile "MyWindowNameForThisButton"

I was unable to get something like your example to work. For example, the FindWindow() did not reliably work in this context, but works fine in the JScript button Modifier tab.

Please let me know if you get any sample code to reliably work. Keep in mind, I want to assign the value (e.g. "MyWindowNameForThisButton") only one time to a variable, and use the variable everywhere it is needed.

Thanks again for your feedback.

In a quick test, this works, if I have a fresh Notepad window open or the Ctrl key is pressed down. (Some of the text is in Spanish, but you get the idea :slightly_smiling_face:)

@evalalways:=value="Sin título: Bloc de notas";
@enableif:=(KeyDown("ctrl")||FindWindow("",value))
=return "DummyCommand VALUE=" + value;

with DummyCommand set as :

Please note that:

  • The button must be inside a menu or similar, not directly in a toolbar, otherwise it won’t automatically update its state and won’t register keydown state either.
1 Like

@errante Thank you. Your example works but I was unable to get this to work when passing multiple values. For example, when using two arguments like this: VALUE/O,VALUETWO/O DummyCommand returns &value& &valuetwo instead of the variable's values.

Otherwise, it looks like this solution would work (for me) if we could find a way to pass several values.

Other Info:
@evalalways:

WIth two or more values :
(the difference is that VALUE is not a raw argument, so quotes are needed)

@evalalways:=value1="Sin título: Bloc de notas";value2="Another value";
@enableif:=(KeyDown("ctrl")||FindWindow("",value1))
=return "DummyCommand VALUE1=""" + value1 + """ VALUE2="""+ value2 +""";

This works perfectly!

Note: Here is your command with 2 minor cosmetic updates:

  • Spacing increased to emphasize the surrounding of value1 and value2 with quotes.
  • Added a trailing (optional) quote to balance out the very first quote.
=return "DummyCommand VALUE1=  """+value1+"""  VALUE2=  """+value2+""" ";

Observations (for future readers!)

  1. The surrounding quotes are concatenated to the variable names.
  2. @EvalAlways is required (runs on Ui update and on button click).
  3. @PassThePeas was correct in that although the original question was not answered in our discussions, we found alternative path that accomplishes the upfront goal.

Again thanks!