Home > Blockchain >  add trash can or delte icon in each table row in vuejs
add trash can or delte icon in each table row in vuejs

Time:12-26

I am new in vue.js and I am trying to add trash icon in each row inside table and activate it to delete row but it does not work , also how can I make the input of one cell as drop down menu or list inside the table rows. the below script is copied from tutorial https://smarttutorials.net/dynamically-add-or-remove-table-row-using-vuejs/ your help is highly appreciated

<!DOCTYPE html>
<html>
    <head>
    <title>Report Generation</title>
        <meta charset = "UTF-8" />
    </head>
    <body> 
        <div id="app">
            <table>
                <thead>
                    <tr>
                        <th scope ="col">#</th>
                        <th scope ="col">Item No</th>
                        <th scope ="col text-right">Item Name</th>
                        <th scope ="col text-right">Price</th>
                        <th scope ="col text-right">Quntatiy</th>
                        <th scope ="col text-right">Total</th>              
                    </tr>
                </thead>
            <tr v-for="(invoice_product, index) in invoice_products" :key="index">
                <td scope="row" >
                    <i  @click="deleteRow(index, invoice_product)"></i>
                </td>
               
                <td>
                    <input  type="text" v-model="invoice_product.product_no" />
                </td>
                <td>
                    <input  type="text" v-model= "invoice_product.product_no" />
      </v-col>
                </td>
                <td>
                    <input  type="number" min="0" step=".01" v-model="invoice_product.product_price" @change="calculateLineTotal(invoice_product)"
                    />
                </td>
                <td>
                    <input  type="number" min="0" step=".01" v-model="invoice_product.product_qty" @change="calculateLineTotal(invoice_product)"
                    />
                </td>
                <td>
                    <input readonly  type="number" min="0" step=".01" v-model="invoice_product.line_total" />
                </td>
            </tr>
        </table>
            <button type='button'  @click="addNewRow">
                <i ></i>
                Add
            </button>
            <button    @click="deleteRow">
            <i ></i>
                Delete
        </button>
    </template>
        </div>
        <script src= "js/vue.js"> </script>
        <script>
            var app = new Vue({
                el: "#app",
                data: {
                    invoice_products: [{
                        product_no: '',
                        product_name: '',
                        product_price: '',
                        product_qty: '',
                        line_total: 0
                    }]
                },methods: {
                
                    deleteRow(index, invoice_product) {
                        var idx = this.invoice_products.indexOf(invoice_product);
                        console.log(idx, index);
                        
                            this.invoice_products.splice(idx, 2);          
            
                    },
                    addNewRow() {
                        this.invoice_products.push({
                            product_no: '',
                            product_name: '',
                            product_price: '',
                            product_qty: '',
                            line_total: 0
                        });
                    }
                }
            });
        </script>
    </body>
</html> ```

CodePudding user response:

Probably you should move your button inside v-for and don't forget about tbody tag

<table>
    <thead>
    <tr>
      <th scope ="col">#</th>
      <th scope ="col">Item No</th>
      <th scope ="col text-right">Item Name</th>
      <th scope ="col text-right">Price</th>
      <th scope ="col text-right">Quntatiy</th>
      <th scope ="col text-right">Total</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="(invoice_product, index) in invoice_products" :key="index">
      <td scope="row" >
        <i  @click="deleteRow(index, invoice_product)"></i>
      </td>

      <td>
        <input  type="text" v-model="invoice_product.product_no" />
      </td>
      <td>
        <input  type="text" v-model= "invoice_product.product_no" />
      </td>
      <td>
        <input  type="number" min="0" step=".01" v-model="invoice_product.product_price" @change="calculateLineTotal(invoice_product)"
        />
      </td>
      <td>
        <input  type="number" min="0" step=".01" v-model="invoice_product.product_qty" @change="calculateLineTotal(invoice_product)"
        />
      </td>
      <td>
        <input readonly  type="number" min="0" step=".01" v-model="invoice_product.line_total" />
      </td>
      <td>
        <button type='button'  @click="addNewRow">
          <i ></i>
          Add
        </button>
      </td>
      <td>
        <button    @click="deleteRow">
          <i ></i>
          Delete
        </button>
      </td>
    </tr>
    </tbody>
  </table>

CodePudding user response:

Try like following snippet:

var app = new Vue({
  el: "#app",
  data() {
    return {
      invoice_products: [{
          id: this.uniqueId(),
          product_no: '',
          product_name: '',
          product_price: '',
          product_qty: '',
          line_total: 0
      }]
    }
  },
  methods: {
    deleteRow(product) {
      this.invoice_products = this.invoice_products.filter(p => p.id !== product.id)       
    },
    addNewRow() {
      const id = this.uniqueId()
      this.invoice_products.push({
          id,
          product_no: '',
          product_name: '',
          product_price: '',
          product_qty: '',
          line_total: 0
      });
    },
    calculateLineTotal(product) {
      if (product.product_price && product.product_qty) {
        product.line_total = product.product_price * product.product_qty
      }
      this.invoice_products = [
        ...this.invoice_products.map((item) =>
          item.id !== product.id
            ? item
            : {
              ...item,
              ...product,
            }
        ),
      ];
    },
    uniqueId(length=16) {
      return parseInt(Math.ceil(Math.random() * Date.now()).toPrecision(length).toString().replace(".", ""))
    }

  }
})
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg p" crossorigin="anonymous"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button type='button'  @click="addNewRow">
    <i ></i>
    Add
  </button>
  <table>
    <thead>
      <tr>
        <th scope ="col">#</th>
        <th scope ="col">Item No</th>
        <th scope ="col text-right">Item Name</th>
        <th scope ="col text-right">Price</th>
        <th scope ="col text-right">Quntatiy</th>
        <th scope ="col text-right">Total</th>              
      </tr>
    </thead>
    <tr v-for="(invoice_product, index) in invoice_products" :key="index">
      <td scope="row" >
        <i  @click="deleteRow(invoice_product)"></i>
      </td>
      <td>
        <input  type="text" v-model="invoice_product.product_no" />
      </td>
      <td>
        <input  type="text" v-model= "invoice_product.product_name" />
      </td>
      <td>
        <input  type="number" min="0" step=".01" v-model="invoice_product.product_price" @change="calculateLineTotal(invoice_product)"
          />
      </td>
      <td>
        <input  type="number" min="0" step=".01" v-model="invoice_product.product_qty" @change="calculateLineTotal(invoice_product)"
          />
      </td>
      <td>
        <input readonly  type="number" min="0" step=".01" v-model="invoice_product.line_total" />
      </td>
    </tr>
  </table>
</div>

  • Related