Creating a Questionnaire with repeater, images, and checkboxes/radio buttons

Question:
I’m trying to create a Questionnaire with repeater, images, and checkboxes/radio buttons. I tried putting the questions into a collection, but the number of choices and images will be different with each question. What would be the best way to approach this?

Product:
Wix Editor

What are you trying to achieve:
Is it possible to dynamically make a repeater for each question using code? So the number of containers in the repeater would change depending on the question and the repeater will populate based on how many choices the question has? Should I make a collection for each question?

With code you can do whatever you want, almost without any limitations.
You just have to know how.

Should I make a collection for each question?
Yes, first of all make some brainstorming about the structure of your database, because everything will depend on the structure of your DATABASE (collection).

Define clearly all dependencies insdide of your DB first, then start coding.

1 Like

Thanks for your reply, I am working on coming up with a sustainable structure using the collections. I currently have a collection for the Questions and a collection for the Choices. They are linked together with a “multi-reference” field/column. I’m having trouble querying the multi-reference field however. Do you have any suggestions?

I currently do a data query to both collections with each initialization, and with each next button push to display the questions and choices. This is a bit unwieldy and feels a bit laggy. Any advice is welcome.

If you have any suggestions on how to store user inputs/answers short-term, I could use some help there. The questionnaire doesn’t need to be saved to a database.

There are many ways how to solve the issue.

Since i am a coder (i never reccomend to work without CODE).

Why? → Because doing everything the coding way, will give you much more opertunities and flexibility.

Using predefined stuff will be useful in some cases, as long as your setup is more simple, but the more complex your setup gets → the more you will recognize the need to code.

Many running into same issue if it comes to similar setups like yours.

In your case you have 2x databases (Questions / Choices).

That means for each of the QUESTION you will have several (CHOICES).
The count of CHOICES will be variable (as you mentioned it).

Now your question…

…but the number of choices and images will be different with each question. What would be the best way to approach this?

You could use the following…(using just one collection)…

  1. Tags (Selection-Tags)
  2. Array-Field inside your database
  3. Or even an object-field inside of your database.

This way, you can store each of your quesions to one row inside your database, having different amount of options for each question.

I think the best would be to use an OBJECT-FIELD.

Inside of your database it would look like…

TITLE: question-1, ID: 111222333, OPTIONS: {name:‘xxxxx’, lastname: ‘yyyyy’, age:55}

This way you do not need a second DATABASE and your DATA will still be compact and won’t use a lot of queries.

Then you querie your DATABASE…

wixData.query("myCollection")
  .find()
  .then((results) => {
    if(results.items.length > 0) {
      console.log(results.items[0]); //see item below
    } else {
      // handle case where no matching items found
    }
  })
  .catch((err) => { console.log(err);});

Result could be… (example)…

result = {
    title: 'question-1',
    id: '1DREfas11fr',
    options: {
        firstname: 'aaaaaaaa',
        lastname: 'bbbbbbb',
        age: 22
    }
}

So you can see the included options, which are stored inside of an Object-Field inside of your databse. Each of your questions now includes options (with different amount).

Once you have the query, you can pass it to your REPEATER → REPEATER-FEEDING <—

$w('#myRepeaterIDhere').data = queriedDataResults.items

We do not forget, the repeater-data has ordinaty string-data, but also includes OBJECTS…like the following example-pic will show you best…

You can see Click-Rate and Open-Rate, are included objects, in your case → OPTIONS <—. Your repeater accepts such data, but can’t handle them, because you would need a REPEATER inside a REPEATER to do so. But what you can do is manually iterate thgough each of Objects inside each of questions and get your wished data.

Inside of your onItemReady()-Code-Part you can generate a function, which will iterate trough the Object of each of your OPTIONS, in each of your Questions…
This for you can use different approaches…

—> forEach-loop
—> for i - loop
—> map (mapping)


$w('#myRepeater').onItemReady(($i, iData, i)=>{console.log(iData);

    iData.forEach((optionElement) => {        
        console.log('optionElement: ', optionElement);
        console.log('optionElement-Firstname: ', optionElement.firstname);
        console.log('optionElement-Lastname: ', optionElement.lastname);
        console.log('optionElementAge: ', optionElement.age);
    });
    
})

An other example out of my own code, for mapping using → map() in combination with forEach…

 function editObject(data) {
    return data.map(item => {
        const newItem = {};
        Object.entries(item).forEach(([key, value]) => {
            if (key === 'id') {newItem['_id'] = value;} 
			//else if (typeof value !== 'object' || value === null) {newItem[key] = value;}
			newItem[key] = value;
        });
        return newItem;
    });
}

This way → you can even manipulate your objects and edit them.

The last missing part will be, how to show the related data for each of your Questions?
Since a REPATER can’t hold another repeater inside of itself → you can use for example a → TABLE. There are still other options → but giving you more INFORMATIONS → this would become a JOB!

This are only code-parts and not a complete solution.
You will have to complete my thoughts.

If you want to use more simple → then use ARRAY-FIELD or TAG-FIELD instead.

Hi, thank you so much for taking the time to go through this in so much depth and detail. I really appreciate you for going above and beyond to provide help. I’m not a coder, so it’s been beyond helpful for you to show me examples so clearly. It’ll take me some time to process all your advice and add it in, but thank you.

I will try and use the object-field that you recommended to store the choices. Since choices are basically an image and text, I would store the image urls in the objects, and then put the objects in an array? Correct me if i’m wrong, but I would need a structure something like this:
{ [image1: url, choice1: string] , [image2:url, choice2:string] … [lastimage: url. lastchoice: string]}?

Yes —> OBJECT into an ARRAY !!! CORRECT!

RESULT → OBJECT-ARRAY

—> [{data:‘tt’},{data:‘ff’},{data:‘dd’},{data:‘aa’}]

But the same way you can put the ARRAY again into an OBJECT, You can do this infinite.
Also works vice versa. → Will depend on your data and how you want to store it inside database. As i already said, you first have to structure your database, before you start to code. Make clear → how your database will look like at the end.

1 Like

Very similar topic (similar issue) …

1 Like