5

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.

5
  • 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? Commented Feb 13, 2017 at 3: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. Commented Feb 13, 2017 at 4:08
  • maybe add a button that does leagues.push(dummyLeague) and see if that makes the problem any more clear Commented Feb 13, 2017 at 4:28
  • Hi, I want to help, but I have no issue about your code. Please review this fiddle. Commented Feb 13, 2017 at 5:28
  • Could you please provide the exact error you are getting? Commented Feb 13, 2017 at 8:21

2 Answers 2

12

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

Sign up to request clarification or add additional context in comments.

1 Comment

This looks nice. I was initially hesitant about having multiple <tbody> elements, but it looks fine: stackoverflow.com/questions/3076708/…
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',
  },
})

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.