Get the values of all Web Blocks to Parent Screen
Application Type
Reactive

Edited to add .oml and link: https://personal-qrlqx9g4.outsystemscloud.com/Survey/

---

Hello!

I am working on a Reactive App, using OutSystems 11.

I have a Block where I have several widgets: text area, checkboxes, radio buttons, dropdown and slider. In reality, each block will only have 1 widget (either the text area or the checkboxes or the radio buttons, etc...) for the user to fill.

In my Parent screen, I have a list of this block. 

So for example, the screen can look like this:

Block 1. Text Area

Block 2. List of checkboxes

Block 3. Radio Button Group 

Block 4. Text Area

Block 5. Dropdown

(...)

How can I send the user input from all the blocks to the parent screen? Later, I will have to store them.

I have been using an OnChange event on all widgets, with an input parameter that sends the value to the parent screen.

In the parent screen I have a button to submit all the answers, but in the web-block there is no button.

I am having some difficulties on trying to understand the best way to do this. What should the input parameter data type be? How do I get the values from all the inputs of all blocks? 

Thank you šŸ˜Š



Survey_120722_01.oml

Hello instead of calling each bock on a Screen What you can do here is

Create A Parent block for your all Widgets block and call all of your input widgets block into them

the create handlers on your parent block, either define a structure or take all the values and then pass them on screen by creating a Event on a parent block,

and hance then call your parent block to screen, and get all the values by the handler that is define on screen.

I hope this can clear you ou, if you can provide me a oml or a poc with blocks that you are using I can create the scenario for you.

Thanks

Hello Tousif, I only have 1 block for all the widgets, but in my parent screen I have a list of this block.

Right now I am trying to get all the inputs to the parent screen by logging things to the console - I am still not trying to store it anywhere. I have attached .oml and link to app, thank you very much for your help!

I have updated your Oml  have a look in case of doubt, please ask!

Survey.oml

Hi Cute Bear,

you are on the right track.  

What is currently missing is

1) information going to your parent about what of the questions has gotten it's value changed

You could add the QuestionId as second attribute in your OnChangedData event for this, passing back to the parent what is sent into the block as input questionId

2) in your parent screen, Survey, you will need to store the answers for all the questions

In your handler, AnswerOnChangedData, you can index into that list with the passed back question id, and update the value with the passed back text value

3) for storing the answers, you still need to do some data modeling, and once that is done, you could probably use that datamodel as structure for the list as discussed in 2), probably retrieved in a join with the list of questions

I don't want to say too much about how to set up or model all this, that's besides the question of this post, and I don't want to spoil the discovery / exploration for you.

Dorine


EDIT : I did something kind of similar (a bit more complex / extensive) in forge component DataWorkshop, you could check that out : block EntityForm handler AttributeValueChanged and block FormWidgetSelector event ValueChanged

Hello @Tousif Khan and @Dorine Boudry, thank you very much for your help! I am attaching the updated version of my .oml and also the app: https://personal-qrlqx9g4.outsystemscloud.com/Survey/Survey?SurveyId=1.

I have however still some troubles:

  • Whenever data is changed, the event is triggered and data is saved. For open text fields, this means that as soon as I write a letter, the data gets saved immediately. For questions with choices (dropdowns, checkboxes, radiogroups, etc), this means that if, for example, I select Option 1, then unclick it and select Option 2, both of them will be saved.

  •  In the screen, I am displaying a list widget. The first step for the pagination of this list is to clear the list in the PaginationOnNavigate Client Action. This means that when I move from page to page, my answers are deleted as well. For example, I want to be able to fill in the answers on page 2, and then go back to page 1 and see my answers.
    • Is there another way in which I can paginate it, without clearing the list? Or another workaround to be able to see all my answers?

Do you have any ideas on how I can solve these topics?

Thank you very much once again!

Survey_120722_01.oml

You are correct @Dorine Boudry, here is the updated .oml. Thank you once again for your tips and comments, I will take them into account again šŸ˜Š

Survey_14072022_01.oml

Hi Cute Bear,

i don't think you attached the correct oml, i don't see any datamodel part yet to allow a person to take the survey, and to store that person's answers, or any logic to save answers.

But from your screenprints, it looks like you do a create everytime, that should be a createorupdate so it updates the previous answer of the same PersonTakesSurvey occasion, instead of creating new entry.  Also, you don't necessarily have to save every keystroke to the database if you don't want, you can wait until user choosed save button or navigates.

On the pagination, I would keep it simple and save answers of a given page before executing the pagination.


Dorine

Here's a number of things to still work on :

  • in your datamodel, you are now only relating your answers to a given question, but I think you probably want more than one person to take your survey, so you will still need to model the person taking your survey, and attach all answers to that (up to you to choose if each person can only take the survey once, or if they should be able to take it several times, each with it's own set of answers)  You will probably will want to relate that to the logged in user  (for sake of argument, let's call a new entity UserTakesSurvey, with a FK to user and survey.
  • so your screen survey detail will probably be UserTakesSurvey detail, and in your aggregates, you need to also read the answers given by that user on those questions, that will solve your problem with pagination, because right now, all you are fetching in the aggregates is the question, not the answer.  Up to you to choose if you are going to read this extra info in the survey screen and pass it into the block, or in the block aggregate.  Right now, you are kind of going with 2 ideas, you retrieve more than just the question id in the survey screen, but than the only thing you pass into the answer block is the id, and read all you need there, again.  I think, if you put the task of saving to the database in the screen, you need to read previous answers there, and update them on each changed event, until you get the save action.  You could pass the answer id into the block along with the question id, and get the details there, or you could pass all answer details to the block, that's a matter of preference, but I personally prefer to keep interface between screens and blocks as small as possible, at the cost of some performance penalty.
  • There is the complexity of different types of answers being given, If I were you, I'd concentrate on making it work completely for only free text answers, and then add other types one by one, right now, you have a bit too much going on and not working yet
  • In the handler AnswerOnChangeData, you have to implement much more logic than just appending to a list !  See point 2 of my previous answer.  The reason you are not doing this right, is part of the reason why you get entries in your database for each keystroke.
  • In the SaveTextAnswers, you are always creating an answer, you should do a create or an update, dependant on whether this user has already previously answered this question or not.  This is the other part of the reason you get so many entries in your database

Dorine

Hello @Dorine Boudry, thank you very much for your input, very useful.

I am attaching my .oml even though not much has changed.

I have created a Respondent entity, to save the user who answered the survey, the timestamp and which survey. I added Respondent Foreign Key to my other 2 entitites: the one that saves the open text answers, and the one that saves the multiple choice answers. I believe that for my app, a respondent should only be able to answer the survey once.

Right now I am focusing on open text answers, as you suggested.

I have also changed the create to create/update, but not sure how that is helping right now.

I think my problem is on the AnswerOnChangeData handler. What I would like to do is: everytime data is changed, it updates my list of answers, instead of appending to it (it only appends, if it's the first time). However, I can't quite create this logic.

What I created instead was something a bit dumb (in my opinion) which I didn't include in the .oml that I sent you:

1. Just append everytime something is changed.

2. Save everything into a temporary entity for open text answers.

3. Apply a SQL query to the temporary entity, that gets the answer with the highest ID for each question.

Meaning I go from having something like this:

To something like this:

(3, def, 35)

(1, abc, 33).

And then I only save these to the official/final entity of open text answers.

This works, but seems very inefficient and my temporary entity immeadiately goes to hundreds/thousands of rows. Maybe I could delete the temporary entity at the end of the process, but it's still not ideal. Can you help me further with creating the other logic?

(I still haven't thought much about storing the answers so when I test the app, I only answer the questions of the first page šŸ˜…)

Survey_15072022_01.oml

Sorry, 

I'm going to have to let this pass.  

This is becoming a whole project instead of simply a post about how to pass info from a block to it's parent.

For the handler, I want to refer again to what i said before :

  • In the handler AnswerOnChangeData, you have to implement much more logic than just appending to a list !  See point 2 of my previous answer.  The reason you are not doing this right, is part of the reason why you get entries in your database for each keystroke.
  • 2) in your parent screen, Survey, you will need to store the answers for all the questions

    In your handler, AnswerOnChangedData, you can index into that list with the passed back question id, and update the value with the passed back text value

  • EDIT : I did something kind of similar (a bit more complex / extensive) in forge component DataWorkshop, you could check that out : block EntityForm handler AttributeValueChanged and block FormWidgetSelector event ValueChanged 

But looking at your oml, there is soo much more that needs improvement, and I think you would benefit greatly from training courses.  For example, the fact that you didn't make QuestionType a Static Entity, leads me to think that you still have very much to gain from just doing the training.

Good luck,

Dorine

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.