Hi, I was wondering if it would be possible to add a little “correct” tick inside a dropdown menu to indicate that the correct answer has been selected. Or, alternatively, if it would be possible to allow a fixed space for “correct” ticks, so that the next question doesn’t get pushed to the right by the tick appearing, as in the code below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>English</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="index, follow"/>
<meta name="description" content=""/>
<meta name="author" content="johnk" />
<meta name="keywords" content=""/>
<style>
ol li {
background-image: none;
padding:10px;
display : inline;
}
</style>
</head>
<body>
<div id="pagewrap">
<div id="container">
<div id="content">
<h4>For, since or ago?</h4>
<div class="scroll">
<form method="post" id="myForm" name="f">
<ol>
<li>
It's been raining
<select name="question1">
<option value="na"> </option>
<option value="a"> for </option>
<option value="b"> since </option>
<option value="c"> ago </option>
</select>
2 hours.
</li>
<li>
They have lived here
<select name="question2">
<option value="na"> </option>
<option value="a"> for </option>
<option value="b"> since </option>
<option value="c"> ago </option>
</select>
1990.
</li>
</ol>
<input type="submit" id="submit" value="Result" />
<input type="reset" class="reset" id="reset" name="reset" value="Start again" />
</form>
<div id="score"></div>
<div class="address">
</div>
</div>
</div>
</div>
</div>
<script>
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
(function(){
"use strict";
window.checkAnswers = function(opts){
function validateInput(){
var question,
answer;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
answer = f.elements[question].options[f.elements[question].selectedIndex].value;
if(answer === "na"){
opts[question].state = "not-filled-in";
} else if(answer === opts[question].answer){
opts[question].state = "correct";
} else {
opts[question].state = "error";
}
}
}
}
function markCorrectOrIncorrect(){
var question,
li;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
var img = new Image(),
li = f.elements[question].parentElement,
feedbackImg = li.getElementsByTagName('img')[0];
if (feedbackImg){
li.removeChild(feedbackImg);
}
if(opts[question].state === "correct"){
img.src = "http://www.littletherese.com/tick.jpg";
li.appendChild(img)
} else if(opts[question].state === "error"){
img.src = "http://www.littletherese.com/x.jpg";
li.appendChild(img)
}
}
}
}
function displayScore(){
var correct = 0,
error = 0,
score = document.getElementById("score"),
totalQuestions = Object.size(opts),
question;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
if(opts[question].state === "correct"){
correct ++
} else if(opts[question].state === "error"){
error ++
}
}
}
score.innerHTML = "You got " + correct + " out of " + totalQuestions;
}
function init(){
validateInput();
markCorrectOrIncorrect();
displayScore();
}
init();
}
}());
f.onsubmit = function(){
checkAnswers({
question1: {answer: "a"},
question2: {answer: "b"},
})
return false;
}
f.reset.onclick = function(){
var imgs = document.querySelectorAll('img');
for(var i=0; i<imgs.length; i++){
imgs[i].parentNode.removeChild(imgs[i]);
}
document.getElementById("score").innerHTML = "";
}
</script>
</body>
</html>
Basically, no.
A standard select element either cannot be styled, or is limited in what can be styled.
Instead, you might want to try using a widget that looks and acts like a select box, but is made with HTML & Javascript.
For example: http://www.marghoobsuleman.com/jquery-image-dropdown
This is by far the easier option, but essentially a CSS question.
If you would prefer to go this route, let me know and I’ll move the question to the CSS forum.
Sounds like a good idea about the fixed space. But the jQuery dropdown looks nice too. I will have a look at it too.So, I suppose better to move to CSS forum then. Thanks.
In your earlier example with the select element you could have done similar and absolutely placed the arrow/cross over the end of the select although you would have needed smaller arrows. It’s probably better to have the arrow/cross outside the input/select though.
That padding-right:30px; looks like an excellent solution, but why would the images being outside the input /select elements be better? And how would I go about doing it? Thanks!
Just in case the content in the control overlaps the image if for example you had more words in there. As long as you can manually control the data then you should be ok with the tick inside.
Something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>English</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="index, follow"/>
<meta name="description" content=""/>
<meta name="author" content="johnk" />
<meta name="keywords" content=""/>
<style>
ol li {
background-image: none;
padding:10px;
display : inline-block;
}
.check {
display : inline-block;
position:relative;
}
.check img {
position:absolute;
right:25px;
top:50%;
margin-top:-6px;
}
.scroll select { width:125px }
</style>
</head>
<body>
<div id="pagewrap">
<div id="container">
<div id="content">
<h4>For, since or ago?</h4>
<div class="scroll">
<form method="post" id="myForm" name="f">
<ol>
<li> It's been raining <span class="check">
<select name="question1">
<option value="na"> </option>
<option value="a"> for </option>
<option value="b"> since </option>
<option value="c"> ago </option>
</select>
<img src="http://www.littletherese.com/tick.jpg" width="15" height="12"></span> 2 hours. </li>
<li> They have lived here <span class="check">
<select name="question2">
<option value="na"> </option>
<option value="a"> for </option>
<option value="b"> since </option>
<option value="c"> ago </option>
</select>
<img src="http://www.littletherese.com/x.jpg" width="15" height="12"></span> 1990. </li>
</ol>
<input type="submit" id="submit" value="Result" />
<input type="reset" class="reset" id="reset" name="reset" value="Start again" />
</form>
<div id="score"></div>
<div class="address"> </div>
</div>
</div>
</div>
</div>
<script>
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
(function(){
"use strict";
window.checkAnswers = function(opts){
function validateInput(){
var question,
answer;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
answer = f.elements[question].options[f.elements[question].selectedIndex].value;
if(answer === "na"){
opts[question].state = "not-filled-in";
} else if(answer === opts[question].answer){
opts[question].state = "correct";
} else {
opts[question].state = "error";
}
}
}
}
function markCorrectOrIncorrect(){
var question,
li;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
var img = new Image(),
li = f.elements[question].parentElement,
feedbackImg = li.getElementsByTagName('img')[0];
if (feedbackImg){
li.removeChild(feedbackImg);
}
if(opts[question].state === "correct"){
img.src = "http://www.littletherese.com/tick.jpg";
li.appendChild(img)
} else if(opts[question].state === "error"){
img.src = "http://www.littletherese.com/x.jpg";
li.appendChild(img)
}
}
}
}
function displayScore(){
var correct = 0,
error = 0,
score = document.getElementById("score"),
totalQuestions = Object.size(opts),
question;
for (question in opts) {
if(opts.hasOwnProperty(question)) {
if(opts[question].state === "correct"){
correct ++
} else if(opts[question].state === "error"){
error ++
}
}
}
score.innerHTML = "You got " + correct + " out of " + totalQuestions;
}
function init(){
validateInput();
markCorrectOrIncorrect();
displayScore();
}
init();
}
}());
f.onsubmit = function(){
checkAnswers({
question1: {answer: "a"},
question2: {answer: "b"},
})
return false;
}
f.reset.onclick = function(){
var imgs = document.querySelectorAll('img');
for(var i=0; i<imgs.length; i++){
imgs[i].parentNode.removeChild(imgs[i]);
}
document.getElementById("score").innerHTML = "";
}
</script>
</body>
</html>
I’ve just shown the image by default but you would of course append it with your js routine as per normal. The image will need to be smaller to fit as shown in the demo above.