Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
How do I use Editing Logic Function to change input value in array using enum preset value?
Caleb_Kehoe
Member, HDM Posts: 28 PRO
I have two tabs in my UI: Array Input and an Enum input type. While the user can input the value into the array directly, I would like to enable the option of a dropdown in a different tab to override the array value if the dropdown enum is used/changed. Almost like the array input value is a default. I've seen examples close to this and @NeilCooke suggested the Spur Gear script to someone else as it drives a third input from two other ones concurrently (I believe). It sounds like Editing Logic Function is the way to do this but I'm having some issues and I suspect the culprit is the data type being an array. I'm also just getting started with FS so perhaps there are a host of other reasons. Any input would be greatly appreciated.
I attempted to copy the FS code below but not sure if the formatting is going to come through in the cleanest way. I can make a public version of this doc if that's easier.
--------> ------->
I attempted to copy the FS code below but not sure if the formatting is going to come through in the cleanest way. I can make a public version of this doc if that's easier.
--------> ------->
<div><br></div><div>export enum tabTYPE</div><div>{</div><div> annotation { "Name" : "Array Input" }</div><div> Array_Input,</div><div> annotation { "Name" : "Dropdown Input" }</div><div> Dropdown_Input,</div><div>}</div><div><br></div><div>export enum optionTYPE</div><div>{</div><div> annotation { "Name" : "Set #VAR1 = 115" }</div><div> VAR115,</div><div> annotation { "Name" : "Set #VAR1 = 285" }</div><div> VAR285,</div><div>}</div><div><br></div><div>annotation { "Feature Type Name" : "Onshape troubleshooting", "Editing Logic Function" : "InputOverride", "UI Hint" : "NO_PREVIEW_PROVIDED" }</div><div>export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)</div><div><br></div><div> precondition</div><div> {</div><div> annotation { "Name" : "Tab", "UIHint" : "HORIZONTAL_ENUM" }</div><div> definition.tabTYPE is tabTYPE;</div><div><br></div><div> if (definition.tabTYPE == tabTYPE.Array_Input)</div><div> {</div><div><br></div><div> annotation { "Item name" : "", "Item label template" : "#(#inputname) = #inputvalue", "Driven query" : "query", "UIHint" : ["COLLAPSE_ARRAY_ITEMS", "NO_PREVIEW_PROVIDED"] }</div><div> definition.arrayVars is array;</div><div><br></div><div> for (var arrayVar in definition.arrayVars)</div><div> {</div><div> annotation { "Name" : "Var Name", "Default" : "VAR1", "UIHint" : "SHOW_LABEL" }</div><div> arrayVar.inputname is string;</div><div> annotation { "Name" : "Var Value" }</div><div> isLength(arrayVar.inputvalue, LENGTH_BOUNDS);</div><div> annotation { "Name" : "Entities", "Filter" : SketchObject.NO, "MaxNumberOfPicks" : 1, "UI Hint" : ["ALWAYS_HIDDEN", "CONTROL_VISIBILITY", "REMEMBER_PREVIOUS_VALUE"] }</div><div> arrayVar.query is Query;</div><div><br></div><div> }</div><div> }</div><div><br></div><div> if (definition.tabTYPE == tabTYPE.Dropdown_Input)</div><div> {</div><div> annotation { "Name" : "Select Input", "UIHint" : ["SHOW_LABEL", "REMEMBER_PREVIOUS_VALUE"] }</div><div> definition.optionTYPE is optionTYPE;</div><div> }</div><div><br></div><div> }</div><div> {</div><div> // Define the function's action</div><div> for (var arrayVar in definition.arrayVars)</div><div> {</div><div> setVariable(context, arrayVar.inputname, arrayVar.inputvalue);</div><div> }</div><div><br></div><div> });</div><div><br></div><div>export function InputOverride(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean, specifiedParameters is map) returns map</div><div>{</div><div> for (var arrayVar in definition.arrayVars)</div><div> {</div><div> if (oldDefinition.optionTYPE != definition.optionTYPE) // this means if the value has been changed by the user</div><div> {</div><div> if (definition.optionTYPE == optionTYPE.VAR115)</div><div> {</div><div> setVariable(context, arrayVar.inputname, 115);</div><div> }</div><div> if (definition.optionTYPE == optionTYPE.VAR285)</div><div> {</div><div> setVariable(context, arrayVar.inputname, 285);</div><div> }</div><div> }</div><div> }</div><div> return definition;</div><div>}</div><div></div>
Tagged:
0
Best Answers
-
Jake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646@Caleb_Kehoe
You need something more like this:export function InputOverride(...) { if (oldDefinition.optionTYPE != definition.optionTYPE) { for (var i = 0; i < size(definition.arrayVars); i += 1) { if (definition.optionTYPE == optionTYPE.VAR115) { definition.arrayVars[i].inputName = 115; } else if (...) ... } } return definition; }
A couple notes on what I've changed here:- You were checking the optionTYPE != optionTYPE in every iteration of the for loop. Since that variable is not part of the array, it will always evaluate the same way, so you may as well only check once.
- The goal of this function is to change the `definition`, and then return that altered definition. `setVariable` will set a variable on the context (the same thing that the Variable feature does in a part studio), but does not change the definition.
- the `for (arrayVar in definition.arrayVars)` type of loop is actually providing you with a copy of each member of the array. So altering this `arrayVar` won't alter the definition itself. This is why I have changed it to a index loop, that syntax will actually alter the definition.
Jake Rosenfeld - Modeling Team5 -
Jake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646@Caleb_Kehoe
The code may be useful. I'm not sure I fully understand the question. To answer all the parts I can:
For the first question, it sounds like you could easily do:if (some condition met) { definition.arrayVars[i].inputValue1 = definition.arrayVars[i].inputValue2; }
For the second question, it sounds like if the manual override is something that just sits on the definition directly, you could do:if (some condition met) { definition.arrayVars[i].inputValue = definition.userManualOverrideValue; }
To answer the general question, yes, no matter which "tab" is selected (in more general terms, no matter whether a parameter is visible in the feature dialog or not), it's value is always retained, and available in both the oldDefinition and the definition of the editing logic. When the editing logic is called, oldDefinition and definition will match each other in every parameter, except the one parameter that the user changed. You can then edit the definition as much as you want, and return it from the editing logic function to adjust the underlying parameters of the dialog.Jake Rosenfeld - Modeling Team5
Answers
You need something more like this:
A couple notes on what I've changed here:
i.e.
Going one step further, I made an option in the enum selection to create a manual entry override that I would also like to pass to inputvalue1 when selected. The manual entry input box is populated below the enum on the same 'tab'. Struggling to get that to work as well.
Regardless of the tabs that these values live on, they are currently all part of the same context and map, correct? So, where am I getting caught out by calling their unique id at any moment in time (regardless of oldDefinition or definition)?
I can provide some code if needed. Thanks in advance!
The code may be useful. I'm not sure I fully understand the question. To answer all the parts I can:
For the first question, it sounds like you could easily do:
For the second question, it sounds like if the manual override is something that just sits on the definition directly, you could do:
To answer the general question, yes, no matter which "tab" is selected (in more general terms, no matter whether a parameter is visible in the feature dialog or not), it's value is always retained, and available in both the oldDefinition and the definition of the editing logic. When the editing logic is called, oldDefinition and definition will match each other in every parameter, except the one parameter that the user changed. You can then edit the definition as much as you want, and return it from the editing logic function to adjust the underlying parameters of the dialog.
On the second question, my error was in thinking that the "ManualOverrideValue" needed to be specified as part of the Enum that enabled its entry rather than just being simply called as a definition of the main feature dialog.