Opening divs within an if statement, closing them outside

Twine Version: 2.10.0

I would like to conditionally open and close divs from within if statements within a for loop. Here’s a simplification of the code I’m using:

<<for _a to 0; _a lt 4; _a++>>

<<if _a == 0>>
<div class="col1">
<</if>>
<<if _a == 1>>
<div class="col2">
<</if>>
<<if _a == 2>>
<div class="col3">
<</if>>
<<if _a == 3>>
<div class="col4">
<</if>>

You are player _a
</div>
<</for>>

This code prints the closing div tags as text and then says it can’t find the closing tags for the divs. Is there any way I can fix this problem?

You could try something like this:

<<for _a to 0; _a lt 4; _a++>>
    
    <<if _a == 0>>
        <<set _class = "col1">>
    <<elseif _a == 1>>
        <<set _class = "col2">>
    <<elseif _a == 2>>
        <<set _class = "col3">>
    <<elseif _a == 3>>
        <<set _class = "col4">>
    <</if>>
    
    <div @class=_class>You are player _a</div>
<</for>>

Instead of opening the <div>, it sets a variable with the desired class, then uses the evaluation directive to add the class to the <div>.

In this specific case, it might also be easier to do something like this:

<<for _a to 0; _a lt 4; _a++>>
    <<set _class = "col"+String(_a+1)>>
    <div @class=_class>You are player _a</div>
<</for>>
1 Like

Thank you! That worked great, but I have a follow-up question.

I’d like to present the results in a tables, with two results in each row, like this:

<table>
	<tr>
		<td>You are player 1</td>
		<td>You are player 2</td>
	</tr>
	<tr>
		<td>You are player 3</td>
		<td>You are player 4</td>
	</tr>
</table>	

I can’t see a way to achieve this using your technique. Is there a way to adapt it to give this result?

Try this:

<<set _table = "<table>">>
<<set _column = 0>>

<<for _a to 0; _a lt 4; _a++>>
    <<set _class = "col"+(_a+1)>>
    
    <<if _column == 0>>
        <<set _table += "<tr>">>
    <</if>>
    
    <<set _table += "<td><div class='"+_class+"'>You are player "+_a+"</div></td>">>
    
    <<if _column == 1>>
        <<set _table += "</tr>">>
    <</if>>
    
    <<set _column = (_column+1)%2>>
<</for>>

<<set _table += "</table>">>

_table

So, basically, it’s impossible to have only a </div> in a conditionally called statement, right? Because the SugarCube2 engine parses the code and doesn’t recognize that the </div> is set correctly?

I have this issue:
I want to have six buttons placed like this:
[1] [2] [3]
[4] [5] [6]
They will have content and mouse-over events dependent on the loop variable, so they should be best placed in a <<for>> loop.
The two rows are rendered by a respective <div class="row"> element.
So the output code should look like this:

<div class="row"> /* first row with [1] [2] [3] */
  <<for _i to 0; _i lt 6; _i++>>
  <div class="button">{button-rendering code}</div>
  <<if _i eq 2>> /* after the first 3 buttons, switch the row */
</div> /* end of first row with [1] [2] [3] */
<div class="row"> /* second row with [4] [5] [6] */
  <</if>>
  <</for>>
</div> /* end of second row with [4] [5] [6] */

When I code it like this, SugarCube says that it can’t find the closing </div> element and refuses to render the sequence.
I can circumvent the problem with two loops, one with _i={0,1,2} and one with _i={3,4,5}. But this is extremely ugly :wink:
Is there no other way to have a simple, singular loop?

Thanks, Pesha.

You could do something like in the code above, where instead of immediately printing the html elements you add them to a string then print that:

<<set _buttons to '<div class="row">'>>
<<for _i to 0; _i lt 6; _i++>>
  <<set _buttons += '<div class="button">{button-rendering code}</div>'>>
  <<if _i eq 2>>
    <<set _buttons += '</div><div class="row">'>>
  <</if>>
<</for>>
<<set _buttons += '</div>'>>

_buttons

I “solved” it like this atm:

<div class="row">

<<set $miniGroupBtnId to 1>><<include MiniGroupBtn>>
<<set $miniGroupBtnId to 2>><<include MiniGroupBtn>>
<<set $miniGroupBtnId to 3>><<include MiniGroupBtn>>

</div>
<br>
<div class="row">

<<set $miniGroupBtnId to 4>><<include MiniGroupBtn>>
<<set $miniGroupBtnId to 5>><<include MiniGroupBtn>>
<<set $miniGroupBtnId to 6>><<include MiniGroupBtn>>

</div>

This is also not the “prettiest” solution but the rendering code in passage MiniGroupBtn is 29 lines long and does “advanced” things like <<capture>>, calculations of the parameters to the passage that will be called when one of the buttons is activated and so on. So I’m not sure if the approach with the print buffer would work. So I won’t check it out now. But thank you for the suggestion. I’m sure it will come handy in the future.

Thanks, Pesha.