Home > Software design >  How to open a modal with a form inside when any button within my table is clicked in one function
How to open a modal with a form inside when any button within my table is clicked in one function

Time:04-28

I have a modal within a div I want to pop up when any button inside my table is clicked. it will be fetching data from an API as the question and the form is for the user to answer and it will display either correct or incorrect and each button will show it's been 'used' after being clicked. The table has 5 columns and 6 rows including the title row. I am trying to create an onclick function for this.

       

          <tr>
            <td><button id="21" data-category="255">500</button></td>
            <td><button id="22" data-category="190">500</button></td>
            <td><button id="23" data-category="135">500</button></td>
            <td><button id="24" data-category="145">500</button></td>
            <td><button id="25" data-category="130">500</button></td>
          </tr>
        </table>
      </div>
      <div >
        <!-- categories get injected here -->
     </div>
      <!-- answers container -->
      <div >
        <button type="button"  data-open="modal1">...</button>
        <div class=card-modal-inner>
          <button type="button"  data-dismiss="modal">&times;</button>
           <h2 ><!-- clue gets added here --></h2>
           <form autocomplete="off">
              <input name="user-answer" type="text" />
              <button type="submit">Answer</button>
           </form>
           <div >
              <p >CORRECT</p>
              <p >INCORRECT</p>
              <p >
                 The correct answer is <span ><!--answer gets injected here--></span>
              </p>
           </div>
        </div>
     </div>
 </div>

CodePudding user response:

So here is the edit after the comment you've made to clear what you wanted to do.

I have made the code, with a really deep commenting, you should understand each part of it, and why they are written on. I've tried to keep it simple, and not too technical, keeping the logic simple, not using fancy methods or properties, just the essential that you should know as a beginner.

I have added a bunch of console.log() for you to be able to understand what is happening, and when, if you were to try the code out. Even though the comments are extremely clear, and the logic self-explainatory. Do not hesitate to comment for me to explain something, but I am sure that you'll get everything. I have added a little trick that will prevent users from cheating by sending another answer.

const tr = document.querySelector("#tr")
const trChildrens = Array.from(tr.children)
const modal = document.querySelector("#modal")
const answerInput = document.querySelector("#answerInput")
const answerButton = document.querySelector("#answerButton")
const result = document.querySelector("#result")
const isCorrect = document.querySelector("#isCorrect")

let modalToggle = false // We're setting it in the global scope in case you need to access it further on.
let answer = "" // Same reason, else we'd put it on the function scope, which would works in your case. Answer is empty per default.

// We will use forEach, which will apply the code for each entry of our array, see it as a for loop, and read about it if you don't know about it.
trChildrens.forEach(child => { 
  child.addEventListener("click", () => {
    console.log("Hey, I've been clicked, so I'll open up the modal!")
    modalToggle = !modalToggle  // We're putting modalToggle to what it's not currently: false if it's true, true if it's false.
    if(modalToggle) { // In the case of modalToggl to be set to true, we want to display the modal.
      modal.style.display = "block" // Replacing the display:none of the modal to the display:block to show it.
    }
  })
})


answerButton.addEventListener("click", answerCheck) // Simply execute answerCheck() when clicking the Answer button.

function answerCheck() {
 // When the answer button is clicked, we want to put the current value of the input as the answer.
 answer = answerInput.value // .value allows us to get the value of an input;
 answerButton.disabled = true  // Once the uesr press the "Answer" button, he shall not be allowed to do it again.
 answerButton.removeEventListener("click", answerCheck) // prevent people to use a trick where they would remove the disabled in DevTools, and resend answer to get it correct while they were not.
 
 // This will need to be coded with your API logic, I will code it with the logic in mind, you'll have to adapt.
 // At this point, you'll have to call your API to get the correct answer, store it in a variable and just use it in the if statement.
 if (answer != "This will be the result of the API") {
   console.log("The answer is different from the API result, the answer is not correct!")
   isCorrect.textContent = "incorrect"
 } else {
   console.log("The answer is corresponding to the API result, the answer is correct!")
   isCorrect.textContent = "correct"
 }
 result.textContent = "Your API result."
}

Here is the HTML part of the code with the id being set.

<table>
    <tr id="tr">
        <td><button id="21" data-category="255">500</button></td>
        <td><button id="22" data-category="190">500</button></td>
        <td><button id="23" data-category="135">500</button></td>
        <td><button id="24" data-category="145">500</button></td>
        <td><button id="25" data-category="130">500</button></td>
    </tr>
</table>
</div>
<div >
    <!-- categories get injected here -->
</div>
<!-- answers container -->
<div id="modal"  style="display: none;">
    <button type="button"  data-open="modal1">...</button>
    <div class=card-modal-inner>
        <button type="button"  data-dismiss="modal">&times;</button>
        <h2 >
            <!-- clue gets added here -->
        </h2>
        <form autocomplete="off">
            <input id="answerInput" name="user-answer" type="text" />
            <button id="answerButton" type="button">Answer</button>
        </form>
        <div >
            <p >
                The correct answer is <span id="result" >
                    <!--answer gets injected here-->
                </span>. Your answer was <span id="isCorrect"></span>

            </p>
        </div>
    </div>
</div>

All you have to do is the API part on the end of the answerCheck() function. Store the result in a variable, and just replace my "string" to your variable to makes it make sense.

  • Related