4

I'm new to VueJS, so this is probably a very simple problem, but here goes.

I'm making a call to my API to get a set of records. I want to display those records in a simple table, but then I want to be able to click a link in the last cell of the row and be sent to a new URL -- a url for the detail of that object.

Here's what I have so far:

Vue Stuff:

var vm = new Vue({
  el: '#league-table',
  data: {
    leagues: [],
    apilink: '/api/leagues/',
  },

  mounted: function() {
    this.getLeagues();
  },
  methods: {
    getLeagues: function() {
      var self = this
      $.get('/api/leagues/', function(data){
        $.each(data, function(index, obj) {
          self.leagues.push(obj)
        });
      });
    },
    sayConsole: function() {
      console.log("OUTPUT here....")
    }
  }
});

HTML Stuff:

   <div class='card__content'>
      <div id='league-table' class='table-responsive'>
        <table class='table table--lg team-roster-table table-hover'>
          <thead>
            <th class='team-roster-table__name'>ID</th>
            <th class='team-roster-table__name'>Name</th>
            <th class='team-roster-table__name'>Characters</th>
            <th></th>
          </thead>

          <tbody>
            <tr v-for='league in leagues'>
              <td class='team-roster-table__number'>{{ league.id }}</td>
              <td class='team-roster-table__name'>{{ league.name }}</td>
              <td class='team-roster-table__name'>{{ league.max_players }}</td>
              <td class='team-roster-table__name'>
                <a v-on:click='sayConsole'>{{ league.id }}</a>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

When I open the page, the table is presented properly, and all the data is loaded correctly. However, it's the clicking of the link in the last cell that isn't working. I believe I have some sort of scope issue -- something about how the row doesn't have a method sayConsole, but I'm not too sure (that's what I can determine from the day of researching the issue).

Ideally, I want to have a URL that takes me to a detail page for that object.

Garfonzo
  • 3,876
  • 6
  • 43
  • 78
  • what happens when you use the vuejs devtools and manually add another row to the table? does the new last row remain unclickable and the 2nd to last is now clickable? – dargue3 Feb 13 '17 at 03:47
  • @dargue3 I don't know how to add a new row with the dev tools. I can see the array that I add values to, but I'm not sure how to manually add another row. – Garfonzo Feb 13 '17 at 04:08
  • maybe add a button that does `leagues.push(dummyLeague)` and see if that makes the problem any more clear – dargue3 Feb 13 '17 at 04:28
  • Hi, I want to help, but I have no issue about your code. Please review [this fiddle](https://jsfiddle.net/krisanalfa/4yge53mk/1/). – krisanalfa Feb 13 '17 at 05:28
  • Could you please provide the exact error you are getting? – Potray Feb 13 '17 at 08:21

2 Answers2

11

thanks for your tips, I was having the same problem, but a found a workaroud without having jquery.

<tbody v-for="product in products" :key="product.id" v-on:click="clickList(product)">
<tr class='clickable-row'>
    <td>  {{ product.id }}</td>
    <td style="text-align: center;">{{ product.productName }}</td>
    <td style="text-align: center;">{{ product.productDesc }}</td>
</tr>

and my vuejs :

clickList: function (product) {
    console.log("clickList fired with " + product.id);
}

I hope it helps future readers

Gregoire Mulliez
  • 1,132
  • 12
  • 20
  • 1
    This looks nice. I was initially hesitant about having multiple `` elements, but it looks fine: https://stackoverflow.com/questions/3076708/can-we-have-multiple-tbody-in-same-table – agm1984 Nov 30 '18 at 02:44
1

I think I figured out the issue -- mainly, my serious lack of experience with VueJS. Here's how I solved it:

  1. I split the table into 2 components. The league-table and the league-row components.

  2. With the separation of components, I could now create methods/data manipulation on the individual components and that data therin

  3. I also discovered that href tags in HTML are setup in VueJS with the v-bind:href(url) syntax

  4. I discovered that HTML tables (and a few other HTML elements) have difficulty being rendered with VueJS. So you'll see that in my table component below, I have to add <tr is='league-row'... to tell VueJS to use the row component.

So, with that in mind, here's how I redsigned things to make it work (though I still don't have per-row clicking, but I just put a button in the last cell).

HTML Stuff The HTML is reduced signifanctly:

 <div id='league-overview' class='table-responsive'>
    <component v-bind:is='currentView'></component>
  </div>

This could probably be even simpler, but it works for now.

VueJS Components

Vue.component('league-row', {
  template: `
    <tr>
      <td class='team-roster-table__number'>{{ league.id }}</td>
      <td class='team-roster-table__name'>{{ league.name }}</td>
      <td class='team-roster-table__name'>{{ league.max_players }}</td>
      <td><a v-bind:href=(url) class='btn btn-primary btn-xs'>View League</a></td>
    </tr>
    `,
  props: ['league'],
  data: function() {
    return {
      url: "/leagues/" + this.league.id + "/",
    }
  },
})

Vue.component('league-table', {
  template: `
    <table class='table table--lg team-roster-table table-hover'>
      <thead>
        <th class='team-roster-table__name'>ID</th>
        <th class='team-roster-table__name'>Name</th>
        <th class='team-roster-table__name'>Characters</th>
        <th></th>
      </thead>
      <tbody>
        <tr is='league-row' v-for='league in leagues' :league="league"></tr>
      </tbody>
    </table>
  `,
  data: function() {
    return {
      leagues: [],
      apilink: '/api/leagues/',
    }
  },
  mounted: function() {
    this.getLeagues();
  },
  methods: {
    getLeagues: function() {
      var self = this
      $.get('/api/leagues/', function(data){
        $.each(data, function(index, obj) {
          self.leagues.push(obj)
        });
      });
    },
  },
})


var vm = new Vue({
  el: '#league-overview',
  data: {
    currentView: 'league-table',
  },
})
Garfonzo
  • 3,876
  • 6
  • 43
  • 78