Graeme Robinson
Graeme Robinson

Reputation: 71

Vue.JS table data not showing in row

I can't seem to get the data to record into a new row when typed in, and it has since stopped displaying the dummy data when it did before. I really do not understand what I've done wrong so any expert feedback would be greatly appreciated.

new Vue({

      el: '#app',
      data: {
        items: [

          {
            'id': 1,
            'product': 'Mario Kart',
            'cost': 39.99
          },
          {
            'id': 2,
            'product': 'Call of Duty',
            'cost': 129.99
          },
          {
            'id': 3,
            'product': 'PS4',
            'cost': 169.99
          }

        ],

        new_item: [

          {
            'id': '',
            'product': '',
            'cost': ''
          }

        ]

      },

      // calculate total cost of all items

      computed: {

        result: function() {

          return Object.values(this.items).reduce((t, {
            cost
          }) => t + cost, 0)

        },

      },

      // add and remove items

      methods: {

        deleteItem: function(index) {

          console.log("Removed", index);
          this.items.splice(index, 1);

        },

        addItem: function() {

          console.log("Added");
          this.items.push({
            'id': '',
            'items.product': '',
            'items.cost.toFixed(2)': ''
          });

        }
      } // close methods

    }); // close new Vue
<section class="section">
      <div id="app" class="container">
        <table class="table is-striped is-fullwidth">

          <tr class="th">
            <th>Index</th>
            <th>Products</th>
            <th>Cost</th>
            <th></th>
          </tr>

          <tr class="items" v-for="(item, index) in items" :key="'itm'+index">

            <td class="index"> {{ index+1 }} </td>
            <td class="service"> {{ items.product }} </td>
            <td class="price"> £{{ items.cost }} </td>
            <td> <button class="button is-small is-danger" @click='deleteItem(index)'>Delete</button> </td>

          </tr>

          <tr class="add_new_item" v-for="(new_items, index) in new_item" :key="'new_itm'+index">
            <th> </th>
            <th> <input class="input is-small" type="text" placeholder="Item Name" v-model="new_items.product"> </th>
            <th> <input class="input is-small" type="text" placeholder="The Price" v-model="new_items.cost"> </th>
            <th> <button class="button is-info is-small" @click='addItem()'>Add To List</button> </th>
          </tr>

          <tr class="is-selected">

            <td>Total</td>
            <td></td>
            <td>£{{ result.toFixed(2) }}</td>
            <td></td>

          </tr>
        </table>
      </div>
    </section>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

Upvotes: 3

Views: 991

Answers (2)

F.bernal
F.bernal

Reputation: 2684

I corrected several things,

Removing your new_item array it is not needed, you just need to store your input values in your data.

product: '',
cost: '',
lastIndex: 3

lastIndex is initialized to 3 due to you have already 3 items in your data items.

The object to be pushed in the items list and how to get that information.

this.items.push({
  'id': this.lastIndex,
  'product': this.product,
  'cost': parseFloat(this.cost)
});

Here a parseFloat it perform because we get a string for the input. Extra work can be performed to check it is a number, or change the input to allow only numbers.

Removed you for iteration to show the insert new item.

Now it looks:

<tr class="add_new_item">
   <th> </th>
   <th> <input class="input is-small" type="text" placeholder="Item Name" v-model="product"> </th>
   <th> <input class="input is-small" type="text" placeholder="The Price" v-model="cost"> </th>
   <th> <button class="button is-info is-small" @click='addItem()'>Add To List</button> </th>
</tr>

and last, Modified how to read the information from the items list

<tr class="items" v-for="(item, index) in items" :key="'itm'+index">
  <td class="index"> {{ item.id }} </td>
  <td class="service"> {{ item.product }} </td>
  <td class="price"> £{{ item.cost }} </td>
  <td> <button class="button is-small is-danger" @click='deleteItem(index)'>Delete</button> </td>
</tr>

new Vue({

      el: '#app',
      data: {
        items: [

          {
            'id': 1,
            'product': 'Mario Kart',
            'cost': 39.99
          },
          {
            'id': 2,
            'product': 'Call of Duty',
            'cost': 129.99
          },
          {
            'id': 3,
            'product': 'PS4',
            'cost': 169.99
          }

        ],
        product: '',
        cost: '',
        lastIndex: 3

      },

      // calculate total cost of all items

      computed: {

        result: function() {

          return Object.values(this.items).reduce((t, {cost}) => t + cost, 0);

        },

      },

      // add and remove items

      methods: {

        deleteItem: function(index) {

          console.log("Removed", index);
          this.items.splice(index, 1);

        },

        addItem: function() {

          console.log("Added");
          this.lastIndex += 1;
          
          this.items.push({
            'id': this.lastIndex,
            'product': this.product,
            'cost': parseFloat(this.cost)
          });
          
          this.product = '';
          this.cost = '';

        }
      } // close methods

    }); // close new Vue
<section class="section">
      <div id="app" class="container">
        <table class="table is-striped is-fullwidth">

          <tr class="th">
            <th>Index</th>
            <th>Products</th>
            <th>Cost</th>
            <th></th>
          </tr>

          <tr class="items" v-for="(item, index) in items" :key="'itm'+index">

            <td class="index"> {{ item.id }} </td>
            <td class="service"> {{ item.product }} </td>
            <td class="price"> £{{ item.cost }} </td>
            <td> <button class="button is-small is-danger" @click='deleteItem(index)'>Delete</button> </td>

          </tr>

          <tr class="add_new_item">
            <th> </th>
            <th> <input class="input is-small" type="text" placeholder="Item Name" v-model="product"> </th>
            <th> <input class="input is-small" type="text" placeholder="The Price" v-model="cost"> </th>
            <th> <button class="button is-info is-small" @click='addItem()'>Add To List</button> </th>
          </tr>

          <tr class="is-selected">

            <td>Total</td>
            <td></td>
            <td>£{{ result }}</td>
            <td></td>

          </tr>
        </table>
      </div>
    </section>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

Upvotes: 2

Sowmyadhar Gourishetty
Sowmyadhar Gourishetty

Reputation: 1878

No need to create a new object for the New items and loop through it. I have modified your code. please refer below

new Vue({

      el: '#app',
      data: {
        items: [

          {
            'id': 1,
            'product': 'Mario Kart',
            'cost': 39.99
          },
          {
            'id': 2,
            'product': 'Call of Duty',
            'cost': 129.99
          },
          {
            'id': 3,
            'product': 'PS4',
            'cost': 169.99
          }

        ],
        currentItemId: 0,
        product: '',
        cost: ''
      },

      // calculate total cost of all items

      computed: {

        result: function() {

          return Object.values(this.items).reduce((t, {
            cost
          }) => t + cost, 0)

        },

      },
      created: function() {
         this.currentItemId = this.items.length + 1;
      },
      // add and remove items

      methods: {

        deleteItem: function(index) {

          console.log("Removed", index);
          this.items.splice(index, 1);

        },

        addItem: function() {

          console.log("Added");
          this.items.push({
            'id': this.currentItemId++,
            'product': this.product,
            'cost': this.cost
          });

          this.product = '';
          this.cost = '';

        }
      } // close methods

    }); // close new Vue
<section class="section">
      <div id="app" class="container">
        <table class="table is-striped is-fullwidth">

          <tr class="th">
            <th>Index</th>
            <th>Products</th>
            <th>Cost</th>
            <th></th>
          </tr>

          <tr class="items" v-for="(item, index) in items" :key="index">

            <td class="index"> {{ index+1 }} </td>
            <td class="service"> {{ item.product }} </td>
            <td class="price"> £{{ item.cost }} </td>
            <td> <button class="button is-small is-danger" @click='deleteItem(index)'>Delete</button> </td>

          </tr>

          <tr class="add_new_item">
            <th> </th>
            <th> <input class="input is-small" type="text" placeholder="Item Name" v-model="product"> </th>
            <th> <input class="input is-small" type="text" placeholder="The Price" v-model="cost"> </th>
            <th> <button class="button is-info is-small" @click='addItem()'>Add To List</button> </th>
          </tr>

          <tr class="is-selected">

            <td>Total</td>
            <td></td>
            <td>£{{ result }}</td>
            <td></td>

          </tr>
        </table>
      </div>
    </section>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

Upvotes: 1

Related Questions