Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mvnobrega's avatar

Reverse @click action

I created a quiz that will contain 50 questions. But each question can refer to two categories or more if the answer is “YES”.

For example:

Are you shy?

YES | NOT

If so, do this: @click="relato.ck.c1 =+ 1;relato.ck.c6 =+ 1;" If you don’t do anything.

My code:

var app = new Vue({
        el: '#app',
        data: {
ck: {
    c1: '',
    c2: '',
    c3: '',
    c4: '',
    c5: '',
    c6: '',
    c7: '',
    c8: '',
    c9: '',
    c10: '',

  },
quest: {
    q1: '',
    q2: '',
    q3: '',
    q4: '',
    q5: '',
    q6: '',
}
            },

<div class="question">

        <div class="statement">
            1.  Você se sente “desligado” ou “aéreo”? | 1 e 6
        </div>

<div class="options yes-no">
   <div  class="yes" @click="relato.quest.q1 = 1;relato.ck.c1 =+ 1;relato.ck.c6 =+ 1;">Sim</div> 
   <div class="no" @click="relato.quest.q1 = 0">Não</div>
</div>

</div>

But the problem is that if a user selects “YES” and then changes his mind by placing “NO”, the values of “YES” are still stored and this cannot happen.

What is the best solution for this?

0 likes
4 replies
piljac1's avatar

Just to help me understand your code completely, what is the meaning of your ck object and its nested c1 to c10 keys ?

mvnobrega's avatar

I put it briefly to facilitate the analysis. But it's a personal test. Some questions, when answered with "YES" can add up to a point in different personalities. And the "CK" is the object that contains the 10 types of personalides (C1 to C10).

Then a "YES" answer to question 1 should add a point in C1 and C6. However, if the user changes his mind and says "NO", I need to undo the previous action on the specific question only, as the questionnaire has 50 questions.

piljac1's avatar
piljac1
Best Answer
Level 28

According to your current HTML markup, I think the most reliable way to keep track of your questions/personalities would be to add an extra key in your relato object to keep track of which question each personality points come from. From this point on, a number of different possibilities exist, but here's a component that would work :

<template>
  <div class="question">
    <div class="statement">
      1.  Você se sente “desligado” ou “aéreo”? | 1 e 6
    </div>
    <div class="options yes-no">
      <div class="yes" @click="handleYes('q1', ['c1', 'c6'])">Sim</div> 
      <div class="no" @click="handleNo('q1', ['c1', 'c6'])">Não</div>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        relato: {
          ck: {
            c1: 0,
            c2: 0,
            c3: 0,
            c4: 0,
            c5: 0,
            c6: 0,
            c7: 0,
            c8: 0,
            c9: 0,
            c10: 0,
          },
          quest: {
            q1: 0,
            q2: 0,
            q3: 0,
            q4: 0,
            q5: 0,
            q6: 0,
          },
          ckQuestAssociations: {
            c1: [],
            c2: [],
            c3: [],
            c4: [],
            c5: [],
            c6: [],
            c7: [],
            c8: [],
            c9: [],
            c10: []
          }
        }
      }
    },

    methods: {
      /**
       * Handle the "click" event for a "yes" answer
       *
       * @param {string} quest - Key to affect in the "relato.quest" object
       * @param {string[]} ck - Array of "ck" keys where to add the quest association
       */
      handleYes(quest, ck) {
        // Mark the question as answered by "yes"
        this.relato.quest[quest] = 1;
      
        // Loop each category and add the question to its association array key if it's not already present.
        // If an association is inserted, increment the category count
        ck.forEach(c => {
          if (this.relato.ckQuestAssociations[c].indexOf(quest) === -1) {
            this.relato.ckQuestAssociations[c].push(quest);
            ++this.relato.ck[c];
          }
        });
      },

      /**
       * Handle the "click" event for a "no" answer
       *
       * @param {string} quest - Key to affect in the "relato.quest" object
       * @param {string[]} ck - Array of "ck" keys where to remove the quest association
       */
      handleNo(quest, ck) {
        // Mark the question as answered by "no"
        this.relato.quest[quest] = 0;
      
        // Loop each category and remove the question from its association array key if it's present.
        // If an association is removed, decrement the category count
        ck.forEach(c => {
          let index = this.relato.ckQuestAssociations[c].indexOf(quest);
        
          if (index !== -1) {
            this.relato.ckQuestAssociations[c].splice(index, 1);
            --this.relato.ck[c];
          }
        });
      } 
    }
  }
</script>

While also solving your issue, this also offers you the possibility to display which questions attributed which personality points if you want to output that kind of information in the future.

P.S. Semantically, using radio buttons would probably be better for your use case. You can stylise them to look like button toggles if you want to go for that look.

1 like

Please or to participate in this conversation.