dynamic form inputs

dynamic form inputs

by Theara Yuom

HTML

<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/[email protected]/lib/index.js"></script>
<script src="https://nchutchind.github.io/vue-outside-events/dist/vue-outside-events.min.js"></script>

<div id="app">
  <div v-click-outside="onClickOutside">
    <el-form :model="form" ref="form">
      <el-table :data="form.items" ref="singleTable" border highlight-current-row @row-click="handleRowClick" style="width: 100%">
        <el-table-column label="ID">
          <template scope="scope">
            <el-select v-if="rowSelected && currentIndex == scope.$index" v-model="scope.row.id" filterable size="small" ref="product" style="width: 100%" @change="handleProductChange(scope.row.id)">
              <el-option v-for="pro in products" :key="pro.id" :label="pro.name" :value="pro.id">
              </el-option>
            </el-select>

            <span v-else>{{scope.row.id}}</span>
          </template>
        </el-table-column>
        <el-table-column label="Qty">
          <template scope="scope">
            <el-input v-if="rowSelected && currentIndex == scope.$index" v-model="scope.row.qty" size="small" ref="qty"></el-input>
            <span v-else>{{scope.row.qty}}</span>
          </template>
        </el-table-column>
        <el-table-column label="Price">
          <template scope="scope">
            <el-input v-if="rowSelected && currentIndex == scope.$index" v-model="scope.row.price" size="small"></el-input>
            <span v-else>{{scope.row.price}}</span>
          </template>
        </el-table-column>
        <el-table-column label="Amount">
          <template scope="scope">
            {{scope.row.amount}}
          </template>
        </el-table-column>
        <el-table-column label="Action">
          <template scope="scope">
            <el-button v-if="scope.$index == (form.items.length - 1)" @click="add">+</el-button>
            <el-button v-else @click="del(scope.$index)">-</el-button>
          </template>
...

CSS

@import url("//unpkg.com/[email protected]/lib/theme-default/index.css");
input {
  display: block;
}

JavaScript

new Vue({
  el: '#app',
  data: {
    rowSelected: false,
    currentIndex: null,
    currentRow: {},
    form: {
      items: [{
        id: '',
        qty: '',
        price: '',
        amount: '',
      }]
    },
    products: [{
      id: 1,
      name: 'A'
    }, {
      id: 2,
      name: 'B'
    }, {
      id: 3,
      name: 'C'
    }, {
      id: 4,
      name: 'D'
    }, {
      id: 5,
      name: 'E'
    }, ],
  },
  watch: {
    'form.items': {
      handler: function(after, before) {
        console.log(after);
        after.forEach((o, index) => {
          //console.log(o);
          let item = this.form.items[index];
          item.amount = item.qty * item.price;
        })
      },
      deep: true
    }
  },
  methods: {
    onClickOutside(e, el) {
        this.setCurrent(null);
      },
      setCurrent(row) {
        console.log('set current');
        this.$refs.singleTable.setCurrentRow(row);
        this.rowSelected = false;
        this.currentIndex = null;
      },
      handleRowClick(row, event, column) {
        console.log('row click', row);
        if (column.label !== 'Action') {
          this.rowSelected = true;
          this.currentIndex = this.form.items.indexOf(row);
          this.currentRow = row;
          setTimeout(() => {
            let el = this.$refs.product;
            if (el) {
              el.$el.querySelector("input").focus();
            }
          }, 50);
        }
      },
      //handleCurrentChange(currentRow, oldCurrentRow) {
      //console.log('current change');
      //this.rowSelected = true;
      //this.currentIndex = this.form.items.indexOf(currentRow);
      //this.currentRow = currentRow;
      //setTimeout(() => {
      //let el = this.$refs.product;
      //if (el) {
      //el.$el.querySelector("input").focus();
      //}
      //}, 50);
      //},
      add() {
        this.form.items.push({
          id: '',
          qty: '',
          price: '',
          amount: '',
        });
       ...