Home > Enterprise >  Javascript CreateElement in loop go back to previous looped value when button is pressed?
Javascript CreateElement in loop go back to previous looped value when button is pressed?

Time:12-24

I'm working on a project that's a quiz like form. You get multiple questions and answers and you can click on any answer to create a personal result. I've already asked a question about this project because I didn't really know how to loop correctly and I fixed that problem, tho it's still not going great. Right now I'm creating a previous button and it kinda works, but not great.

My code:

<div >
    <div id="question"></div>
    <div id="answer"></div>
    <button onclick="NextQuestion()" id="nextbtn">Next</button>
    <button onclick="PrevQuestion()" id="prevbtn">Previous</button>
    <div id="finalLink"></div>
</div>

JS

    class QuizPart{
        constructor(questionDescription, chosenAnswer, prefix){
            this.questionDescription = questionDescription;
            this.chosenAnswer = chosenAnswer;
            this.prefix = prefix;
        }
    }
    
    class ChosenAnswer{
        constructor(id, name){
            this.id = id;
            this.name = name;
        }
    }

    let Quiz = [
        new QuizPart('Whats your size?', [
            new ChosenAnswer('6595', '41'),
            new ChosenAnswer('6598', '42'),
            new ChosenAnswer('6601', '43'),
        ], 'bd_shoe_size_ids='),

        new QuizPart('What color would you like?', [
            new ChosenAnswer('6053', 'Red'),
            new ChosenAnswer('6044', 'Blue'),
            new ChosenAnswer('6056', 'Yellow'),
            new ChosenAnswer('6048', 'Green'),
        ], 'color_ids='),

        new QuizPart('What brand would you like?', [
            new ChosenAnswer('5805', 'Adidas'),
            new ChosenAnswer('5866', 'Nike'),
            new ChosenAnswer('5875', 'Puma'),
        ], 'manufacturer_ids='),
    ]
    // console.log(Quiz);

    let url = [];

    let questionNumber = 0;
    let button = document.getElementById('answer');
    let questionName = document.getElementById('question');
    let nextbtn = document.getElementById('nextbtn');
    let prevbtn = document.getElementById('prevbtn')
    let resultbtn = document.getElementById('FLink');

    function NextQuestion() {
        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
            answerButton.style.display = 'none';
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y  ) {
            let item = question.chosenAnswer[y];
            // Display answer buttons
            let btn = document.createElement('button');
            btn.value = item.id;
            btn.className = "filter_anwser";
            btn.textContent = item.name;
            button.appendChild(btn);
        }
        // Check if your at the last question so the next button will stop being displayed.
        if (Quiz.length - 1 === questionNumber) {
            nextbtn.style.display = 'none';
            resultbtn.style.display = 'grid';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";

        // adds 1 to question to see a different question
        questionNumber  ;
    }

    function PrevQuestion(){
        questionNumber--;
        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
            answerButton.style.display = 'none';
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y  ) {
            let item = question.chosenAnswer[y];
            // Display answer buttons
            let btn = document.createElement('button');
            btn.value = item.id;
            btn.className = "filter_anwser";
            btn.textContent = item.name;
            button.appendChild(btn);
        }
        //Check if your at the last question so the next button will stop being displayed.
        if (Quiz.length === questionNumber) {
            prevbtn.style.display = 'none';
            resultbtn.style.display = 'grid';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";
    }

Now as you can see I create a new element when I press the previous button (also seen in the next image): Image

I'm trying not to create an entire new set of elements, but going back to the previous set. I tried doing it with a simple if statement like:

let i = 0;
if (i < question.chosenAnswer[y]){
    y--;
}

This is just something I tried but didn 't work. Can anybody help me do this?

Save the information:

    function getLink(url) {
        let tmp = [];
        for (let i = 0; i < url.length; i  ) {
            // Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
            if (url[i].length > 0){
                tmp.push(""   Quiz[i].prefix   url[i].join(","))
            }
        }
        /// If answers are from different quiz parts add a & between answers.
        console.log(url, questionNumber);
        return ""   tmp.join("&");
    };

    button.addEventListener("click", function (e) {
        const tgt = e.target;

        // clear the url array if there's nothing clicked
        if (url.length < questionNumber) {
            url.push([]);
        }

        let quizUrl = url[questionNumber - 1];

        // Check if a button is clicked. Changes color and adds value to the url array.
        if (quizUrl.indexOf(tgt.value) === -1) {
            quizUrl.push(tgt.value);
            e.target.style.backgroundColor = "orange";
        // Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
        } else {
            quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
            e.target.style.backgroundColor = "white";
        }
        console.log(getLink(url));
    })

CodePudding user response:

You need to use element.remove() instead of element.style.display ="none"

Why? element.remove() - will remove the DOM element altogether. element.style.display ="none" - Will only hide it for the end user. But it will still be there on the DOM tree.

Js Fiddle for solution below:

Fixed a few thing in you code as well. Added comment lines in the places where I fixed things

  1. Next button now disappears on the last question
  2. Previous button now disappears on the first question

class QuizPart{
        constructor(questionDescription, chosenAnswer, prefix){
            this.questionDescription = questionDescription;
            this.chosenAnswer = chosenAnswer;
            this.prefix = prefix;
        }
    }
    
    class ChosenAnswer{
        constructor(id, name){
            this.id = id;
            this.name = name;
        }
    }

    let Quiz = [
        new QuizPart('Whats your size?', [
            new ChosenAnswer('6595', '41'),
            new ChosenAnswer('6598', '42'),
            new ChosenAnswer('6601', '43'),
        ], 'bd_shoe_size_ids='),

        new QuizPart('What color would you like?', [
            new ChosenAnswer('6053', 'Red'),
            new ChosenAnswer('6044', 'Blue'),
            new ChosenAnswer('6056', 'Yellow'),
            new ChosenAnswer('6048', 'Green'),
        ], 'color_ids='),

        new QuizPart('What brand would you like?', [
            new ChosenAnswer('5805', 'Adidas'),
            new ChosenAnswer('5866', 'Nike'),
            new ChosenAnswer('5875', 'Puma'),
        ], 'manufacturer_ids='),
    ]
    console.log(Quiz);

    let url = [];

    let questionNumber = 0;
    let button = document.getElementById('answer');
    let questionName = document.getElementById('question');
    let nextbtn = document.getElementById('nextbtn');
    let prevbtn = document.getElementById('prevbtn')
    let resultbtn = document.getElementById('finalLink');

    function NextQuestion() {
        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
           **//CORRECTION DONE HERE** 
           answerButton.remove();
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y  ) {
            let item = question.chosenAnswer[y];
            // Display answer buttons
            let btn = document.createElement('button');
            btn.value = item.id;
            btn.className = "filter_anwser";
            btn.textContent = item.name;
            button.appendChild(btn);
        }
        //FIX ADDED HERE FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
        // Check if your at the last question so the next button will stop being displayed.
        if (questionNumber > 0 ) {
                prevbtn.style.display = 'grid'
        }
        if (Quiz.length - 1 <= questionNumber) {
            nextbtn.style.display = 'none';
            resultbtn.style.display = 'grid';
        }else{
                nextbtn.style.display = 'grid';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";

        // adds 1 to question to see a different question
        questionNumber  ;
    }

    function PrevQuestion(){
        questionNumber--;
        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
           **//CORRECTION DONE HERE**
            answerButton.remove();
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y  ) {
            let item = question.chosenAnswer[y];
            // Display answer buttons
            let btn = document.createElement('button');
            btn.value = item.id;
            btn.className = "filter_anwser";
            btn.textContent = item.name;
            button.appendChild(btn);
        }
        //FIX ADDED HERE FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
        //Check if your at the last question so the prev button will stop being displayed.
        if (questionNumber < Quiz.length - 1) {
                nextbtn.style.display = 'grid';
        }
        if (questionNumber <= 0) {
            prevbtn.style.display = 'none';
        }else{
                prevbtn.style.display = 'grid';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";
    }
<div >
    <div id="question"></div>
    <div id="answer"></div>
    <button onclick="NextQuestion()" id="nextbtn">Next</button>
    <button onclick="PrevQuestion()" id="prevbtn">Previous</button>
    <div id="finalLink"></div>
</div>

CodePudding user response:

You have to retrieve the previously created buttons to show(*) them.

For instance you can retrieve them using their id which is put in their value attribute:

for (let y = 0; y < question.chosenAnswer.length; y  ) {
    let item = question.chosenAnswer[y];
    // retrieve the button by it's value="id" attribute
    let btn = document.querySelector('button[value="'   item.id   '"]');
    btn.style.display = 'grid';
}

(*) Note that when you say "Deletes questions" you actually are just hiding them, not deleting (i.e. removing from document).

  • Related