Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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

share|improve this question
    
What do you want to change in that div? – Saurabh Dec 23 '16 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'. – Dan Murfitt Dec 23 '16 at 13:26
up vote 1 down vote accepted

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://vuejs.org/v2/guide/events.html#Methods-in-Inline-Handlers

share|improve this answer

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>
share|improve this answer
    
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. – Dan Murfitt Dec 23 '16 at 13:38
    
Hmmmmmm, can't you do options.map() when you fetch the data? This way you can set this field to the object :) – Rômulo M. Farias Dec 23 '16 at 13:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.