Some issues with card javascript

I wrote some code for a multiple choice card template and am having 3 issues.

  1. When I set the background color on the back side (green or red depending on if the answer is correct) using document.body.style.backgroundColor = “/” it carries over to the next card.

  2. What is the text content of an empty field? I would like to check for this and if so, not draw the field.

  3. The input checkboxes do not work on the ankimobile app. They are hidden and nested within labels so that if you click anywhere on the label it checks the checkbox. It works on desktop but on mobile it just brings you to the back of the card instead.

Does anyone know of solutions to any of these issues?

Here is my code:

Front Template
<header>
	{{Front}}
</header>
<div id="fcontainer"></div>
<label class="front">
	<input type="checkbox" id="A">
	{{Choice 1}}
</label>
<label class="front">
	<input type="checkbox" id="B">
	{{Choice 2}}
</label>
<label class="front">
	<input type="checkbox" id="C">
	{{Choice 3}}
</label>
<label class="front">
	<input type="checkbox" id="D">
	{{Choice 4}}
</label>

<script>
document.body.style.backgroundColor = "navy";
var fcontainer = document.querySelector("#fcontainer");
var fchoices = document.querySelectorAll(".front");
var randomSet = new Set();

/* Draw choices in random order */
while(randomSet.size < 4) {
	randomSet.add(Math.floor(Math.random()*4));
}
for (var f of randomSet) {
//TO DO: find a way to filter out empty field
		fcontainer.appendChild(fchoices[f]);
		fchoices[f].hidden = false;
}
</script>
Back Template
<header>
	{{Front}}
</header>

<div id="bcontainer"></div>
<div class="back">{{Choice 1}}</div>
<div class="back">{{Choice 2}}</div>
<div class="back">{{Choice 3}}</div>
<div class="back">{{Choice 4}}</div>

<script>
var bcontainer = document.querySelector("#bcontainer");
var bchoices = document.querySelectorAll(".back");
var questionCorrect = true;
var answers = "{{Answer #}}".split(",");

for (var b of randomSet) {
	var finput = fchoices[b].querySelector("input");
	var checked = finput.checked;
	var correct = answers.includes(finput.id);
	var bchoice = bchoices[b];

/* Re-draw choices in the same random order */
	bcontainer.appendChild(bchoice);
	bchoice.hidden = false;

/* Change the border if checked */
	if(checked) {
		bchoice.style.borderStyle = "inset";
	} else {
		bchoice.style.borderStyle = "outset";
	}

/* Change the color if correct or incorrect */
	if(correct) {
		bchoice.style.backgroundColor = "#00ff00";
		bchoice.style.borderColor = "#00cc00";
	} else {
		bchoice.style.backgroundColor = "#ff0000";
		bchoice.style.borderColor = "#cc0000";
	}

/* Set question as incorrect if choice is wrong */
	if (!checked===correct) {
		questionCorrect = false;
	}
}

/* Change the to the appropriate background color if correct or not */
if(questionCorrect){
	document.body.style.backgroundColor = "#009900";
} else {
	document.body.style.backgroundColor = "#990000";}
</script>

You can try these, but I’m not 100% they will work:

For 1: I think instead of grabbing the body tag try grabbing the .card class element since it is the default they give in the styles section.

For 2: You can go into you script and use alert(“{{FieldThatIsEmpty}}”); to see what gets printed out. It’s an alternative to using console.log for debugging be sure to delete it right after so you don’t have a bunch of alerts while studying.

I’m pretty sure it’s just an empty string, but sometimes special characters can get resolved into HTML entities which causes issues sometimes.

For 3: I don’t know too much on how to fix this, but I can offer an alternative way to do it. I’d probably just recode to where the divs are the selections and wrap it in a parent div with event listener that uses event propagation. Use ids to differentiate the options and use a class to depict which one was selected.

Hope this helps :slight_smile:

Thanks for the reply.

So grabbing the .card class works as long as the next card’s .card background color is specified. Otherwise it still carries over. I guess it could be ok as long as I always set the .card background for every card type.

The alert showed an empty string. Since I am redrawing each field anyways my plan was to just add an if statement to only draw it if the textContent is not “”. However if I do this it still draws the empty field. Same if I check for the newline character or any whitespaces. Not sure how to check exactly what it is since it is blank in the alert and in a console.log.

For #3, it is perhaps More Features - AnkiMobile Manual

That worked. Just had to add class “tappable” to the labels as it says there. Thanks!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.