2
\$\begingroup\$

I have the following code snippet:

<tr>
    <td @click="changeTeam('WHU')">WHU</td>
    <td>20 Oct</td>
    <td @click="changeTeam('BHA')">BHA</td>
</tr>
<tr>
    <td @click="changeTeam('CHE')">CHE</td>
    <td>21 Oct</td>
    <td>WAT</td>
</tr>

and the following VueJS method:

methods: {
            changeTeam(selection) {
                this.team = selection;
            }
         }

So as you can see, I'm calling this function and passing in the value in the table cell (i.e. <td> tag) to change a selection. This works for me, but is there a way I can capture the contents of the table cell, by means of some other method? Something a little more reusable or would this just be introducing extra overhead?

The table itself is the result of a dynamically generated page, so I'm not overly bothered about the apparent duplication.

\$\endgroup\$
  • \$\begingroup\$ If you have a couple of minutes, take the time to read how to get the best value out of Code Review on our meta site: as it stands the question seems framed for a specific issue, the code boiled down to what amounts to a MCVE, and the surrounding context is missing: IOW you don't seem to be looking for feedback on any & all aspects of the code at all. That said this one-liner method seems entirely useless to me; I'd just inline it. \$\endgroup\$ – Mathieu Guindon Nov 1 '17 at 15:15
  • \$\begingroup\$ it was my first post here - thanks for the links and the comment. of course I was asking for feedback on the code. i was asking was there a way to capture the value of the table cell and now there are some suggestions. stack to the rescue. \$\endgroup\$ – dstewart101 Nov 1 '17 at 15:44
4
\$\begingroup\$

One technique would be to apply fundamentals of event delegation by adding a method to handle all clicks. For instance, an event listener could be added to the root element (or one if child its child nodes, like a <table>)

mounted: function() {
    this.$el.addEventListener('click', this.clickHandler);
}

Then have the method accept the click event argument:

clickHandler(clickEvent){

That method could check if the target of the event was a table cell by checking the tagName attribute (for TD). To restrict to only certain table cells, add a class attribute - e.g. team. If that class is found in the target element's classList, set the team property to the innerHTML of the target.

clickHandler(clickEvent){
    const target = clickEvent.target;
    if (target.tagName == 'TD' && target.classList.contains('team')) {
        this.team = target.innerHTML;
    }
}

See a demonstration in the sample below. Notice how there is now a clean separation of the event handling logic (JS) and the markup for display (HTML).

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    team: ''
  },
  mounted: function() {
    this.$el.addEventListener('click', this.clickHandler);
  },
  methods: {
    clickHandler(clickEvent) {
      const target = clickEvent.target;
      if (target.tagName == 'TD' && target.classList.contains('team')) {
        this.team = target.innerHTML;
      }
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>Selected Team: {{ team }}</p>
  <table>
    <tr>
      <td class="team">WHU</td>
      <td>20 Oct</td>
      <td class="team">BHA</td>
    </tr>
    <tr>
      <td class="team">CHE</td>
      <td>21 Oct</td>
      <td>WAT</td>
    </tr>

  </table>
</div>

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ thanks. this is the kind of thing i was looking for. certainly takes the clutter out of my html. many thanks. \$\endgroup\$ – dstewart101 Nov 1 '17 at 15:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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