Hi, I am building a questionnaire tool where I use a loop layout to auto populate the question and includes answer buttons. This is set up as a child module containing variable QuestionText (populated based on audit type) and 3 interactive metric cards each with a stored static variable (variable names = YesValue, NoValue, NAValue). I am now writing a function in typescript to loop over all instances in the loop and generate new objects for all values of QuestionText and the selected answer variable. I have tried:
Without looping, I previously mapped the selected answer variable (YesValue, NoValue, NAValue) to selectedAnswer variable but mapping like this to a variable in the child module does not work within the loop layout as each instance can be answered differently
I tried using the above and mapping selectedAnswer which sits under “Other interface variables” in the loop layout config to a variable in the parent module but this prevents it being dynamic across instances.
I am now trying to generate a function that maps the string values selected to a string array that the ontology edit can iterate over.
How can I either
a) map the answer selected (either the metric specific variables directly or selectedAnswer mapped in the child module) to a variable in the parent module but maintain the dynamic nature of answering
Or
b) set the function up to directly call the metric specific variables (YesValue, NoValue, NAValue) from the child module directly in the typescript file?
The goal is to create a typescript function (partially written) that creates objects in the loop for all values of QuestionText and associated answer.
Finally, how do I call a variable in my workshop app in my typescript?
I’m not sure that you can accomplish this using the mechanics of Workshop - maybe someone from the team can chime in.
When, in the past, I’ve wanted to build more complicated survey or data entry workflows, I’ve normally reached for Slate, in which the Variable and Event model, as well as the layout engine is more flexible. There is a higher configuration burden, and I’ve normally ended up using the Code Sandbox widget to either reuse an existing javascript form library or write something simple myself, but we can be much more free in each aspect of building your application.
As an example of a pattern I’ve built in the past:
Define a survey data model that has object types for: survey, survey_page, question, answer, response and the appropriate links between them.
Build a workshop app for creating new survey instances (this is for the folks looking to run a survey)
Write a Slate app that can load a survey and all it’s linked objects and render a form, normally using Code Sandbox. You could also do this with a custom React app + OSDK, potentially even easier than using Slate, but I’m less familiar with that path, and captures the user input into a JSON data structure.
Write a typescript function that can parse that JSON output and write back the responses.
Again, hopefully someone can answer your more direct question about capturing variable values from within looped layouts, but maybe this gives you some other avenues to explore that have less constraints.
Loop layouts doesn’t have a great way of supporting this workflow currently. As you probably found, “Other interface variables” provides the same variable to each instance in the loop layout - see Sharing variables in the loop layouts docs.
Loop layouts work best to display content in an object set, and optionally allow acting on each piece of content within each instance of the embedded module, but do not have a great way to “aggregate interactions” across all instances. You may be able to do something with separate “save” actions within each loop layout which write to some temporary “in progress” form object state, which can then be committed as answers in a separate action from the parent module.
As an alternative to Slate, you could also look into embedding a custom OSDK app as a custom widget through the Workshop iframe widget - see docs here.
Thank you @lrhyne and @evanj for your responses. This is super helpful guidance and has opened a few avenues to try! I’m going to start with the intermediary table before testing out slate or developer console if needed.
For the temporary “in progress” form object state, I was going to create an object type and action that links to the child module and then write a function linked to submit button that pulls the final values through to the final desired table. Is this what you also had in mind @evanj ?