0 votes

Hi all,

I want to make sure the user selects at least one option of a checkbox question.
The trick is that the checkbox is inside a for loop.

The simple scenario is if we ought to ask the user's favourite vacation spot (single answer) and then ask in which seasons she likes to go there (checkbox).
However, to my understanding, a checkbox-type question allows blank answer (i.e.: no alternative selected).
Thus, if I wanted to enforce the selection of at least one alternative, I'd check the answer size and use label and goto to send the user back to the question with a message. The user cannot proceed until she selects at least one alternative.

Here's a sample code.

>>selection_warning = 0
*header: Single Selection
*question: What's your favourite vacation spot?
	*save: vacation_spot
	Beach
	Mountain
	City
    
*label: season_selection
*if: selection_warning = 1
	*html
		<p style="color:red; font-style:italic;">Please, select a season.</p>

*question: In which seasons do you like to go to the *{vacation_spot}*?
	*save: seasons
	*type: checkbox
	Summer
	Spring
	Winter
	Fall

*if: seasons.size=0
	>>selection_warning = 1
	*goto: season_selection

In *{seasons}* you like going to the *{vacation_spot}*.
>>selection_warning = 0

Now, let's say that I want to allow multiple selections for the favourite vacation spots.
Then, I'd like to loop over each selected vacation spot to know the preferred seasons for each spot.
However, the for loop doesn't allow me to use a *goto (understandably).

Here's an example:

>>selection_warning = 0
*header: Multiple Selection - For Loop
*question: Which vacation spots do you like?
	*save: vacation_spots
	*type: checkbox
	Beach
	Mountain
	City

>>spot_seasons = {}

*for: spot in vacation_spots
	--*label: season_selection
	*if: selection_warning=1
		*html
			<p style="color:red; font-style:italic;">Please, select a season.</p>
	
	*question: In which seasons do you like to go to the *{spot}*?
		*save: seasons
		*type: checkbox
		Summer
		Spring
		Winter
		Fall
	
	*if: seasons.size=0
		>>selection_warning = 1
		--*goto: season_selection
		-- How can I make sure the user selects at least one checkbox?
	
	>>spot_seasons[spot] = seasons

*for: spot,season in seasons
	In *{season}* you like going to the {spot}. 

Then, the question is: How to enforce that each checkbox question inside the loop has at least one selection?
Any ideas or thoughts would be greatly appreciated!

Thanks in advance!

by (440 points)

1 Answer

+1 vote
Best answer

The reason *for doesn't allow *goto within its block is that *goto could be used to prematurely break out of the loop. If that were to happen there could be unexpected behavior if that *for loop is ever executed again. The reason for that is that *for needs to automatically keep track of where it is in the loop and what the next element in the collection ought to be.

Most of the time these constraints don't matter and we recommend using *for, because it's easier to use than the alternatives. However, since in your case the constraints *for imposes are getting in the way of accomplishing the task, I'd recommend switching to a *while loop. You'd need to do a little bit more manual work to loop, but you'll be able to use *goto.

To convert your *for loop into a *while, you'll need to declare an indexing variable and increment it at the end of the loop:

>> i = 1
*while: i < vacation_spots.size
	-- the code you currently have in *for, with *goto where you need it
	...
	>> i = i + 1
by (1.8k points)
selected by

That's very neat! Thanks for the idea of the *while loop. It works perfectly!

I thought it worked similarly as the *for, but it makes sense how it's different.
I just had to change a few variables to use the {i}, otherwise, minimal changes and full functionality.

Many thanks!

I copy the adapted code for reference on the changes:

*header: Multiple Selection - While Loop
*question: Which vacation spots do you like?
	*save: vacation_spots
	*type: checkbox
	Beach
	Mountain
	City

>>spot_seasons = {}

>>i = 1
>>selection_warning = 0
*while: i <= vacation_spots.size
	*label: season_selection_while
	*if: selection_warning=1
		*html
			<p style="color:red; font-style:italic;">Please, select a season.</p>
	
	*question: In which seasons do you like to go to the *{vacation_spots[i]}*?
		*save: seasons
		*type: checkbox
		Summer
		Spring
		Winter
		Fall
	
	*if: seasons.size=0
		>>selection_warning = 1
		*goto: season_selection_while
		-- How can I make sure the user selects at least one checkbox?
	
	>>spot_seasons[vacation_spots[i]] = seasons
	>>selection_warning = 0
	>> i = i+1

*for: spot,season in spot_seasons
	In *{season}* you like going to the {spot}.
Welcome to Guidedtrack Q&A, where you can ask questions and receive answers from other members of the community.
123 questions
133 answers
55 comments
195 users