Home > Net >  Javascripts multiple choice onclick modify all questions
Javascripts multiple choice onclick modify all questions

Time:09-29

I build this multiple choice questions but not in quiz format. I have in the page an sequence of divs with questions and each question have their own choices and check button, so they are independent and free for the users to respond one, all or none. I made the content (questions and answers) wrote directly on HTML file because I have others working with me and they have only contact with the HTML files to implement some classes.

My problem is that I made one question and it's working, but when a duplicated the div with another question the interaction affects all the divs. For exemple:

  • when you select an option, the check button turns from disable to enable, but if you select an option from the second question, the check button from the first question change.
  • if you want to interact with two question in the same time, when you select an option in the first question, when you select an option in the second question on the first that you selected turns unselected.

So I want to make each div with question be independent, in a way that we can create as many questions as we want.

I created this https://jsfiddle.net/1yLwrcek/2/

let mcqCard = document.querySelectorAll('.mcq-card');
let answerOption = document.querySelectorAll('.mcq__answers li');
let submitButton = document.querySelector('.mcq__submit button');
let submitFeedback = document.querySelector('.mcq__submit--feedback');
let score = 0;

(function () {
    // Select option, clear the others and enable submit
    answerOption.forEach(option => {
        option.addEventListener('click', function () {
            console.log(submitButton.getAttribute('type'));

            answerSelect(option);
        });
    });

    //Submit button to check only selected class option.
    submitButton.addEventListener('click', function () {
        if (submitButton.getAttribute('type') === 'submit' && submitButton.getAttribute('aria-disabled') === 'false') {
            butttonCheck();
        } else {
            buttonReset();
        }
    });
})();

function answerSelect(e) {
    if (submitButton.getAttribute('type') === 'submit') {
        for (let i = 0; i < answerOption.length; i  ) {
            const element = answerOption[i];
            element.classList.remove('mcq__answers--selected');
        }
        e.classList.add('mcq__answers--selected');
        submitButton.setAttribute('aria-disabled', 'false');
    }
}

function incorrectAnswer(event) {
    event.classList.remove('mcq__answers--selected');
    event.classList.add('mcq__answers--incorrect');

    submitFeedback.innerHTML = `<span >cancel</span>Resposta errada! <br  />Tente novamente.`;
    submitFeedback.classList.remove('d-none', 'mcq__submit__feedback--correct');
    submitFeedback.classList.add('mcq__submit__feedback--incorrect');
}

function correctAnswer(event) {
    event.classList.remove('mcq__answers--selected');
    event.classList.add('mcq__answers--correct');

    submitFeedback.innerHTML = `<span >check_circle</span>Resposta correta! <br  />Você acertou em ${score} tentativa(s).`;
    submitFeedback.classList.remove('d-none', 'mcq__submit__feedback--incorrect');
    submitFeedback.classList.add('mcq__submit__feedback--correct');
}

function blockAnswerOption() {
    for (let i = 0; i < answerOption.length; i  ) {
        const element = answerOption[i];

        element.classList.add('mcq__answers--blocked');
    }
}

function butttonCheck() {
    if (submitButton.getAttribute('type') === 'submit') {
        score  ;

        for (let i = 0; i < answerOption.length; i  ) {
            const element = answerOption[i];

            if (element.classList.contains('mcq__answers--selected')) {
                if (!element.hasAttribute('correct')) {
                    incorrectAnswer(element);
                    blockAnswerOption();
                } else {
                    correctAnswer(element);
                    blockAnswerOption();
                }
            }
        }
        submitButton.setAttribute('type', 'reset');
        submitButton.innerHTML = 'Reset';
    }
}

function buttonReset() {
    if (submitButton.getAttribute('type') === 'reset') {
        for (let i = 0; i < answerOption.length; i  ) {
            const element = answerOption[i];

            element.classList.remove('mcq__answers--correct', 'mcq__answers--incorrect', 'mcq__answers--blocked', 'mcq__answers--selected');
            submitButton.setAttribute('type', 'submit');
            submitButton.innerHTML = 'Check';
            submitButton.setAttribute('aria-disabled', 'true');
        }

        if (submitFeedback.classList.contains('mcq__submit__feedback--correct')) {
            score = 0;
        }
        submitFeedback.classList.remove('mcq__submit__feedback--correct', 'mcq__submit__feedback--incorrect');
        submitFeedback.classList.add('d-none');
    }
}
:root {
    /* Colors */
    --primary-color: #d27f7d;
    --primary-color-light: #ee9b9a;
    --primary-color-dark: #bb6564;

    --secondary-color: #8a6580;
    --secondary-color-extra-light: #fae9f5;
    --secondary-color-light: #c28cb4;
    --secondary-color-dark: #5a3751;

    --text-color: #1e1e1e;
    --text-color-light: #535658;

    --color-dark: #1e1e1e;
  --color-light: #eef2f6;
    --color-light-hover: #e6e6e625;
}



.mcq-card {
    padding: 0px 30px;
}
.mcq-card .mcq__question {
    padding: 30px 0;
    border-bottom: 1px solid var(--secondary-color-light);
    font-family: 'DM Sans Bold', sans-serif;
    font-size: 1.25rem;
}

/* Answers List */
.mcq-card .mcq__answers {
    padding: 30px 0;
}
.mcq-card .mcq__answers ul {
    list-style-type: none;
    margin: 0;
}
.mcq-card .mcq__answers ul li {
    padding: 10px 20px;
    margin-bottom: 20px;
    border: 2px solid var(--primary-color-light);
    border-radius: 8px;
    cursor: pointer;
    font-size: 1rem;
    transition: 0.1s;
}
.mcq-card .mcq__answers ul li:last-child {
    margin-bottom: 0;
}
.mcq-card .mcq__answers ul li:not(.mcq__answers--blocked, .mcq__answers--selected, .mcq__answers--correct, .mcq__answers--incorrect):hover {
    border-color: var(--primary-color-dark);
    /* background-color: var(--color-light-hover); */
}
.mcq-card .mcq__answers ul li.mcq__answers--selected {
    background-color: var(--secondary-color-extra-light);
    border-color: var(--secondary-color-light);
    color: var(--secondary-color-dark);
}
.mcq-card .mcq__answers ul li.mcq__answers--correct {
    background-color: #c0ffce;
    border-color: #28a745;
    color: #014811;
    cursor: not-allowed;
}
.mcq-card .mcq__answers ul li.mcq__answers--incorrect {
    background-color: #ffc5cb;
    border-color: #dc3545;
    color: #81000c;
    cursor: not-allowed;
}
.mcq-card .mcq__answers ul li.mcq__answers--blocked:not(.mcq__answers--correct, .mcq__answers--incorrect) {
    cursor: not-allowed;
    border-color: var(--color-light);
    color: var(--text-color-light);
}

/* Submit Button */
.mcq-card .mcq__submit {
    display: flex;
    flex-direction: row;
    justify-content: start;
    align-items: center;
    padding: 30px 0;
    border-top: 1px solid var(--secondary-color-light);
}
.mcq-card .mcq__submit button[aria-disabled='true'] {
    background-color: #909599;
    border-color: #909599;
    cursor: not-allowed;
}

/* Feedback mensage */
.mcq-card .mcq__submit .mcq__submit--feedback {
    font-family: 'DM Sans Bold', sans-serif;
    margin-left: 20px;
    line-height: 1.2;
}
.mcq-card .mcq__submit .mcq__submit--feedback .material-symbols-rounded {
    font-weight: 700;
    margin-right: 10px;
}
.mcq-card .mcq__submit .mcq__submit--feedback.mcq__submit__feedback--correct {
    display: block !important;
    color: #28a745;
}
.mcq-card .mcq__submit .mcq__submit--feedback.mcq__submit__feedback--incorrect {
    display: block !important;
    color: #dc3545;
}
<div >
  <div >1. Question</div>
  <div >
    <ul>
      <li tabindex="0">Option 1</li>
      <li tabindex="0">Option 2</li>
      <li tabindex="0" correct>Option 3</li>
    </ul>
  </div>
  <div >
    <button  aria-disabled="true" type="submit">Check</button>
    <span ></span>
  </div>
</div>

<div >
  <div >2. Question</div>
  <div >
    <ul>
      <li tabindex="0">Option 1</li>
      <li tabindex="0">Option 2</li>
      <li tabindex="0" correct>Option 3</li>
    </ul>
  </div>
  <div >
    <button  aria-disabled="true" type="submit">Check</button>
    <span ></span>
  </div>
</div>

Thanks

CodePudding user response:

Because each question has exact same structure, you'll need either assign an unique ID for each or go by its index. But most simple solution is to query each element of each question separately:

let mcqCard = document.querySelectorAll('.mcq-card');
let score = 0;

(function () {
  mcqCard.forEach(mcq =>
  {
    let answerOption = mcq.querySelectorAll('.mcq__answers li');
    let submitButton = mcq.querySelector('.mcq__submit button');
    let submitFeedback = mcq.querySelector('.mcq__submit--feedback');
    // Select option, clear the others and enable submit
    answerOption.forEach(option => {
        option.addEventListener('click', function () {
            console.log(submitButton.getAttribute('type'));

            answerSelect(option, submitButton, answerOption);
        });
    });

    //Submit button to check only selected class option.
    submitButton.addEventListener('click', function () {
        if (submitButton.getAttribute('type') === 'submit' && submitButton.getAttribute('aria-disabled') === 'false')         {
            butttonCheck();
        } else {
            buttonReset();
        }
    });
    
    function answerSelect(e, submitButton) {
        if (submitButton.getAttribute('type') === 'submit') {
            for (let i = 0; i < answerOption.length; i  ) {
                const element = answerOption[i];
                element.classList.remove('mcq__answers--selected');
            }
            e.classList.add('mcq__answers--selected');
            submitButton.setAttribute('aria-disabled', 'false');
        }
    }

    function incorrectAnswer(event) {
        event.classList.remove('mcq__answers--selected');
        event.classList.add('mcq__answers--incorrect');

        submitFeedback.innerHTML = `<span >cancel</span>Resposta errada! <br  />Tente novamente.`;
        submitFeedback.classList.remove('d-none', 'mcq__submit__feedback--correct');
        submitFeedback.classList.add('mcq__submit__feedback--incorrect');
    }

    function correctAnswer(event) {
        event.classList.remove('mcq__answers--selected');
        event.classList.add('mcq__answers--correct');

        submitFeedback.innerHTML = `<span >check_circle</span>Resposta correta! <br  />Você acertou em ${score} tentativa(s).`;
        submitFeedback.classList.remove('d-none', 'mcq__submit__feedback--incorrect');
        submitFeedback.classList.add('mcq__submit__feedback--correct');
    }

    function blockAnswerOption() {
        for (let i = 0; i < answerOption.length; i  ) {
            const element = answerOption[i];

            element.classList.add('mcq__answers--blocked');
        }
    }

    function butttonCheck() {
        if (submitButton.getAttribute('type') === 'submit') {
            score  ;

            for (let i = 0; i < answerOption.length; i  ) {
                const element = answerOption[i];

                if (element.classList.contains('mcq__answers--selected')) {
                    if (!element.hasAttribute('correct')) {
                        incorrectAnswer(element);
                        blockAnswerOption();
                    } else {
                        correctAnswer(element);
                        blockAnswerOption();
                    }
                }
            }
            submitButton.setAttribute('type', 'reset');
            submitButton.innerHTML = 'Reset';
        }
    }

    function buttonReset() {
        if (submitButton.getAttribute('type') === 'reset') {
            for (let i = 0; i < answerOption.length; i  ) {
                const element = answerOption[i];

                element.classList.remove('mcq__answers--correct', 'mcq__answers--incorrect', 'mcq__answers--blocked', 'mcq__answers--selected');
                submitButton.setAttribute('type', 'submit');
                submitButton.innerHTML = 'Check';
                submitButton.setAttribute('aria-disabled', 'true');
            }

            if (submitFeedback.classList.contains('mcq__submit__feedback--correct')) {
                score = 0;
            }
            submitFeedback.classList.remove('mcq__submit__feedback--correct', 'mcq__submit__feedback--incorrect');
            submitFeedback.classList.add('d-none');
        }
    }
});
})();
:root {
    /* Colors */
    --primary-color: #d27f7d;
    --primary-color-light: #ee9b9a;
    --primary-color-dark: #bb6564;

    --secondary-color: #8a6580;
    --secondary-color-extra-light: #fae9f5;
    --secondary-color-light: #c28cb4;
    --secondary-color-dark: #5a3751;

    --text-color: #1e1e1e;
    --text-color-light: #535658;

    --color-dark: #1e1e1e;
  --color-light: #eef2f6;
    --color-light-hover: #e6e6e625;
}



.mcq-card {
    padding: 0px 30px;
}
.mcq-card .mcq__question {
    padding: 30px 0;
    border-bottom: 1px solid var(--secondary-color-light);
    font-family: 'DM Sans Bold', sans-serif;
    font-size: 1.25rem;
}

/* Answers List */
.mcq-card .mcq__answers {
    padding: 30px 0;
}
.mcq-card .mcq__answers ul {
    list-style-type: none;
    margin: 0;
}
.mcq-card .mcq__answers ul li {
    padding: 10px 20px;
    margin-bottom: 20px;
    border: 2px solid var(--primary-color-light);
    border-radius: 8px;
    cursor: pointer;
    font-size: 1rem;
    transition: 0.1s;
}
.mcq-card .mcq__answers ul li:last-child {
    margin-bottom: 0;
}
.mcq-card .mcq__answers ul li:not(.mcq__answers--blocked, .mcq__answers--selected, .mcq__answers--correct, .mcq__answers--incorrect):hover {
    border-color: var(--primary-color-dark);
    /* background-color: var(--color-light-hover); */
}
.mcq-card .mcq__answers ul li.mcq__answers--selected {
    background-color: var(--secondary-color-extra-light);
    border-color: var(--secondary-color-light);
    color: var(--secondary-color-dark);
}
.mcq-card .mcq__answers ul li.mcq__answers--correct {
    background-color: #c0ffce;
    border-color: #28a745;
    color: #014811;
    cursor: not-allowed;
}
.mcq-card .mcq__answers ul li.mcq__answers--incorrect {
    background-color: #ffc5cb;
    border-color: #dc3545;
    color: #81000c;
    cursor: not-allowed;
}
.mcq-card .mcq__answers ul li.mcq__answers--blocked:not(.mcq__answers--correct, .mcq__answers--incorrect) {
    cursor: not-allowed;
    border-color: var(--color-light);
    color: var(--text-color-light);
}

/* Submit Button */
.mcq-card .mcq__submit {
    display: flex;
    flex-direction: row;
    justify-content: start;
    align-items: center;
    padding: 30px 0;
    border-top: 1px solid var(--secondary-color-light);
}
.mcq-card .mcq__submit button[aria-disabled='true'] {
    background-color: #909599;
    border-color: #909599;
    cursor: not-allowed;
}

/* Feedback mensage */
.mcq-card .mcq__submit .mcq__submit--feedback {
    font-family: 'DM Sans Bold', sans-serif;
    margin-left: 20px;
    line-height: 1.2;
}
.mcq-card .mcq__submit .mcq__submit--feedback .material-symbols-rounded {
    font-weight: 700;
    margin-right: 10px;
}
.mcq-card .mcq__submit .mcq__submit--feedback.mcq__submit__feedback--correct {
    display: block !important;
    color: #28a745;
}
.mcq-card .mcq__submit .mcq__submit--feedback.mcq__submit__feedback--incorrect {
    display: block !important;
    color: #dc3545;
}
<div >
  <div >1. Question</div>
  <div >
    <ul>
      <li tabindex="0">Option 1</li>
      <li tabindex="0">Option 2</li>
      <li tabindex="0" correct>Option 3</li>
    </ul>
  </div>
  <div >
    <button  aria-disabled="true" type="submit">Check</button>
    <span ></span>
  </div>
</div>

<div >
  <div >2. Question</div>
  <div >
    <ul>
      <li tabindex="0">Option 1</li>
      <li tabindex="0">Option 2</li>
      <li tabindex="0" correct>Option 3</li>
    </ul>
  </div>
  <div >
    <button  aria-disabled="true" type="submit">Check</button>
    <span ></span>
  </div>
</div>

  • Related