5

If you've got a list of items with click events attached, how do you apply a specific change to a clicked child element using Vue.js (2.0)? Here's an example:

HTML:

<div id="root">

    <div class="selection">
      <div class="option" v-for="option in options" @click="processSelection(option)">
        <p class="text">{{ option.text }}</p>
        <p class="feedback"></p>
      </div>
    </div>

</div>

Javascript:

new Vue({

  el: '#root',

  data: {
    options: [
      { text: 'First option', feedback: 'First option feedback' },
      { text: 'Second option', feedback: 'Second option feedback' },
      { text: 'Third option', feedback: 'Third option feedback' },
      { text: 'Fourth option', feedback: 'Fourth option feedback' },
    ]
  },

  methods: {
    processSelection(option) {
      alert(option.text + ' was clicked');

      //Update the respective feedback div
      //...
    }
  }

});

So this will display a list of items. When you click, say, the third item, how can I update the corresponding .feedback block with the related feedback text? Here's the code in a JS Bin: https://jsbin.com/ricewuf/edit?html,js,output

2
  • What do you want to change in that div? Commented Dec 23, 2016 at 13:25
  • Add the feedback text to the related .feedback p tag. So, if they click the second option, the related feedback div would have 'Second option feedback'. Commented Dec 23, 2016 at 13:26

2 Answers 2

4

I think you can let another boolean attribute at the option object, something like showFeedback, and then just change its value to show the feedback!

It's better show in code :)

JS

https://jsbin.com/diquwemiti/edit?html,js,output

new Vue({

  el: '#root',

  data: {
    options: [
      { text: 'First option', feedback: 'First option feedback', showFeedback: false},
      { text: 'Second option', feedback: 'Second option feedback', showFeedback: false },
      { text: 'Third option', feedback: 'Third option feedback', showFeedback: false },
      { text: 'Fourth option', feedback: 'Fourth option feedback', showFeedback: false },
    ]
  },

  methods: {
    processSelection(option) {
      option.showFeedback = true
    }
  }

});

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>


  <div id="root">

    <div class="selection">
      <div class="option" v-for="option in options" @click="processSelection(option)">
        <p class="text">{{ option.text }}</p>
        <p class="feedback" v-if="option.showFeedback">{{ option.feedback }}</p>
      </div>
    </div>

  </div>

</body>
</html>
Sign up to request clarification or add additional context in comments.

2 Comments

I like this idea, however, with my actual implementation I'm fetching the feedback from the server. It's for a quiz, and I don't want to store the answer in the DOM, as people could inspect and find it out.
Hmmmmmm, can't you do options.map() when you fetch the data? This way you can set this field to the object :)
1

You can still pass the original event to your event handler and use it to find the .feedback div :

new Vue({

  el: '#root',

  data: {
    options: [{
      text: 'First option',
      feedback: 'First option feedback'
    }, {
      text: 'Second option',
      feedback: 'Second option feedback'
    }, {
      text: 'Third option',
      feedback: 'Third option feedback'
    }, {
      text: 'Fourth option',
      feedback: 'Fourth option feedback'
    }, ]
  },

  methods: {
    processSelection(option, e) {
      var target = e.currentTarget;
      var feedback = target.querySelector('.feedback');
      feedback.innerHTML = option.feedback;
    }
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js">
</script>

<div id="root">

  <div class="selection">
    <div class="option" v-for="option in options" @click="processSelection(option, $event)">
      <p class="text">{{ option.text }}</p>
      <p class="feedback"></p>
    </div>
  </div>

</div>

Here is some documentation about this : https://v2.vuejs.org/v2/guide/events.html#Methods-in-Inline-Handlers

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.