JSFiddle - React, Tailwind, and code Playground

by Vladimir

HTML

<script src="https://lodash.com/_js/lodash.js"></script>
<div class="slide" data-slide="1">
  <h1>
  Select themes for your test:
  </h1>
  <ul class="themes-list">
  
  </ul>
  <div>Units in one test: <input type='number' value='3' class='unitsInTest' />
  </div>
  <input type="button" value="Let`s start!" class="startTest" />
  <script type="text/template" id="theme-tpl">
  	<li class="theme-item">
    <input type="checkbox" class="theme-checkbox" data-theme="<%=slug %>" /> <%=theme %> (<%= tasks %>)
    </li>
  </script>
</div>
<div class="slide" data-slide="2">

<ol class="tests">

</ol>
<input type="button" value="Check" class="check" /><input type="button" value="Restart" class="restart" disabled="disabled" /><input type="button" value="Themes selection" class="themeSelection" />
<div class="test-result">
</div>
<script type="text/template" id="test-tpl">
<li class="unit-item"><% if(ru) { %>
<em><%= ru %></em><br />
<% } %>
<%= content %>
<div class="vars">
<% for(var j = 0; j < vars.length; j++) { %>
<span class="variant"><%= vars[j] %></span>
<% } %>
</div>
</li>
</script>
</div>

CSS

body {
  font-family: Verdana, sans-serif;
}
.slide[data-slide="2"] {
  display: none;
}
.unit-item {
  background: #FFF;
  padding: 10px;
  border:1px solid #000;
  margin: 5px;
}
.answer,
.variant {
  display:inline-block;
  width:80px;
  background: #EEF;
  border-radius:5px;
  height: 20px;
  border-bottom: 1px solid transparent;
  cursor: pointer;
  text-align: center;
}
.variant {
  background: #FFE;
}
.ready {
  background: #FEF;
}
.correct {
  border-bottom: 1px solid #0F0;
}
.wrong {
  border-bottom: 1px solid #F00;
}
.correct-unit {
  border: 1px solid #0F0;
  background: #EFE;
}
.wrong-unit {
  border: 1px solid #F00;
  background: #FEE;
}

JavaScript

var testOptions = {
	unitsPerPage: 3
};

var test = test || {};
test.articles = {
	title: 'Articles',
	vars: [' ', 'the', 'a', 'an'],
	units: [{
		txt: '{ } Mary is {an} interesting girl.'
	}, {
		ru: 'Он - лучший.',
		txt: 'He is {the} best.'
	}, {
		ru: 'Он - худший.',
		txt: 'He is {the} worst.',
		vars: ['less']
	}]
};
test.nouns = {
	title: 'Nouns',
	vars: ['is', 'are'],
	units: [{
		txt: 'Police {are} smart.'
	}, {
		txt: 'Sugar {is} sweet.'
	}, {
		txt: 'Water {is} cold.'
	}, {
		txt: 'The weather {is} fine.'
	}]
};

//* gen theme-list
var themeTpl = _.template($("#theme-tpl").text());
_.each(test, function(tst, slug) {
	$('.themes-list').append(themeTpl({
		theme: tst.title,
		slug: slug,
		tasks: tst.units.length
	}));
});



$('body').on('click', '.variant', function() {
	var unit = $(this).closest('.unit-item');
	var position = unit.find('.answer:not(.ready)').eq(0);
	if (position) {
		position.text($(this).text());
		position.addClass('ready');
	}
});

$('body').on('click', '.answer', function() {
	$(this).text('').removeClass('ready');
});

$('.check').click(function() {
	var units = 0;
	var correct = 0;
	var textResult = '';
	$('.tests .unit-item').each(function() {
		units++;
		var isCorrect = 1;
		$(this).find('.answer').each(function() {
			$(this).removeClass('wrong').removeClass('correct');
			if ($(this).text() == $(this).attr('data-answer')) {
				$(this).addClass('correct');
			} else {
				$(this).addClass('wrong');
				$(this).html('<s>' + $(this).text() + '</s> ' + $(this).attr('data-answer'));
				isCorrect = 0;
			}
		});
		$(this).removeClass('wrong-unit').removeClass('correct-unit');
		if (isCorrect) {
			$(this).addClass('correct-unit');
			correct++;
		} else {
			$(this).addClass('wrong-unit');
		}
	});
	textResult += correct + '/' + units;
	$('.test-result').text(textResult);
	$(this).attr('disabled', 'disabled');
	$('.restart').removeAttr('disabled');
});

//* start test
$('.startTest, .restart').click(function()...