Wasteland
Wasteland

Reputation: 5399

JavaScript - iterating over a series of questions (array/object)

In this snippet of code a user is supposed to select a word that matches the definition (definition and matching word is stored in an array). Now I've got the functionality of checking whether the selected word is matching the first element of the array. If the right word is selected, a success message gets displayed. At the moment, the user gets asked to click on the word matching the first definition from the array. I'd like to have an option to move to the next one, once the first has been answered correctly. I'll add more words and definitions later.

Here's what I've got:

var onA = [
    {t: "grooming", d: "an activity when someone builds an emotional connection with a child to gain their trust for the purposes of sexual abuse or exploitation."},
    {t: "cyberbullying", d: "an activity that involves the use of ICT, particularly mobile phones and the internet, deliberately to upset, threaten and intimidate someone else."}
];

function get_selection() {
    var txt = '';
    var feedback = document.querySelector("#onA .feedback");
    if (window.getSelection) {
        txt = window.getSelection().toString();
    } else if (document.selection) {
        txt = document.selection.createRange().text;
    }

    document.querySelector("#onA .word").innerHTML = txt;

    function feed(oldClass, newClass, message) {
        feedback.classList.remove(oldClass);
        feedback.classList.add(newClass);
        feedback.innerHTML = message.bold();
    }

    if (txt === onA[0].t) {
        feed("alert-warning", "alert-success", "Well done!");
    } else {
        feed("alert-success", "alert-warning", "Try again!");
    }    
}

document.getElementById("onA").onclick = get_selection;
document.querySelector("#onA .def").innerHTML += onA[0].d;

Edit: First problem I've got is when I want the get_selection() function to take an argument (eg. an index for the array to be used in the if conditional statement within the function, it stops working:

function get_selection(i) {
    var txt = '';
    var feedback = document.querySelector("#onA .feedback");
    if (window.getSelection) {
    txt = window.getSelection().toString();
    } else if (document.selection) {
    txt = document.selection.createRange().text;
    }

    document.querySelector("#onA .word").innerHTML = txt;
    function feed(oldClass, newClass, message) {
    feedback.classList.remove(oldClass);
    feedback.classList.add(newClass);
    feedback.innerHTML = message.bold();
    }

    if (txt === onA[i].t) {
    feed("alert-warning", "alert-success", "Well done!");
    } else {
    feed("alert-success", "alert-warning", "Try again!");
    }    
}





document.getElementById("onA").onclick = get_selection(0);


document.querySelector("#onA .def").innerHTML += onA[0].d;

It doesn't show any error in the console, just the feedback whether the right/wrong word has been selected does not work any more. Thank you.

Upvotes: 0

Views: 77

Answers (1)

GregL
GregL

Reputation: 38131

What you actually need to do is have your get_selection() function return a function itself. Otherwise, the following line:

document.getElementById("onA").onclick = get_selection(0);

just runs the function, which returns undefined and effectively clears out the onclick handler for the onA element.

Change your get_selection function to the following structure:

function create_get_selection_handler(index) {
    return function click_handler() {
        // (rest of code goes here and uses "index" variable)
    };
}

Then change the onclick line to:

document.getElementById("onA").onclick = create_get_selection_handler(0);

If you want the technical reason why this works, look up how closures work in Javascript and why they are awesome (essentially, the inner function has access to the index variable in the outer function). The Javascript Garden is a good starting point, and the rest of the page is worth reviewing as well.

Upvotes: 1

Related Questions