javascripthtmlvue.jsdata-entry

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>


Solution

  • 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>