Передать значения из автозаполнения пользовательского интерфейса Element во входные данные таблицы, используя VueJS - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь создать форму счета, используя элемент UI . Я добавил автозаполнение, которое извлекает данные из массива loadAll . После нажатия кнопки add и выбора item_name из автозаполнения я хочу передать связанный selling_price в price , используя метод handleSelect и задайте вычисленную сумму в сумму , используя метод amountfn , который можно обновить с помощью onChange значения Кол-во input.

Также было бы неплохо предотвратить выбор дубликата item_name из раздела автозаполнения, когда item_name уже добавлено в поле ввода имени

Вот мой код

<template>
  <el-form
    ref="updateForm"
    :model="cart"
    status-icon
    label-width="100px"
    @keydown.enter.native="updateContact"
  >
    <el-table :data="cart.items" style="width: 100%">
      <el-table-column label="Name">
        <template slot-scope="scope">
          <el-autocomplete
            class="inline-input"
            v-model="scope.row.item_name"
            value-key="item_name"
            :fetch-suggestions="querySearch"
            placeholder="Please Input"
            :trigger-on-focus="false"
            @select="handleSelect"
          ></el-autocomplete>
        </template>
      </el-table-column>
      <el-table-column label="QTY">
        <template slot-scope="scope">
          <el-input v-model="scope.row.qty"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="Price">
        <template slot-scope="scope">
          <el-input v-model="scope.row.price"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="Amount">
        <template slot-scope="scope">
          <el-input v-model="scope.row.total" value="amountfn" disabled></el-input>
        </template>
      </el-table-column>
      <el-table-column>
        <template slot-scope="scope">
          <el-button type="danger" @click="removeLine(scope.$index)">Del</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-form-item>
      <el-button @click="addLine">Add</el-button>
    </el-form-item>
    <el-row>
      <el-col :span="6" :offset="14">Sub Total {{subTotal}}</el-col>
      <el-col :span="6" :offset="14">
        <el-form-item label="Discount" prop>
          <el-input placeholder v-model="cart.discount"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="6" :offset="14">Grand total {{grandTotal}}</el-col>
    </el-row>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      cart: {
        items: [],
        discount: 0
      },

      links: []
    };
  },
  methods: {
    removeLine(item) {
      if (item !== -1) {
        this.cart.items.splice(item, 1);
      }
    },
    addLine() {
      this.cart.items.push({
        item_name: "",
        qty: 1,
        price: 0,
        total: 0
      });
    },
    querySearch(queryString, cb) {
      var links = this.links;
      var results = queryString
        ? links.filter(this.createFilter(queryString))
        : links;
      // call callback function to return suggestions
      cb(results);
    },
    createFilter(queryString) {
      return link => {
        return (
          link.item_name.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        );
      };
    },
    loadAll() {
      return [
        {
          id: 2,
          upc_ean_isbn: "102",
          item_name: "Lucy Olive Oil",
          size: "150 ml",
          description: "na",
          avatar: "no-foto.png",
          cost_price: "110.00",
          selling_price: "130.00",
          quantity: 30,
          type: 1,
          created_at: "2019-07-05 21:20:10",
          updated_at: "2019-07-06 10:41:09"
        },
        {
          id: 8,
          upc_ean_isbn: "23001",
          item_name: "Pen Desk",
          size: "6 inch",
          description: "",
          avatar: "no photos",
          cost_price: "300.00",
          selling_price: "350.00",
          quantity: 5,
          type: 1,
          created_at: "2019-10-25 14:42:07",
          updated_at: "2019-10-25 14:42:07"
        },
        {
          id: 9,
          upc_ean_isbn: "789",
          item_name: "Ink",
          size: "10 mL",
          description: "NA",
          avatar: "no photos",
          cost_price: "40.00",
          selling_price: "60.00",
          quantity: 17,
          type: 1,
          created_at: "2019-10-25 18:22:23",
          updated_at: "2019-10-25 18:22:23"
        },
        {
          id: 10,
          upc_ean_isbn: "2001",
          item_name: "Phone",
          size: "na",
          description: "na",
          avatar: "no photos",
          cost_price: "12000.00",
          selling_price: "14000.00",
          quantity: 5,
          type: 1,
          created_at: "2019-10-25 18:23:31",
          updated_at: "2019-10-25 18:23:31"
        },
        {
          id: 11,
          upc_ean_isbn: "999",
          item_name: "Tasty tea",
          size: "100 g",
          description: "",
          avatar: "no photos",
          cost_price: "30.00",
          selling_price: "40.00",
          quantity: 30,
          type: 1,
          created_at: "2019-10-25 18:55:39",
          updated_at: "2019-10-25 18:55:39"
        }
      ];
    },
    handleSelect(item) {
      this.cart.items.item_name = item.item_name;
      this.cart.items.price = item.selling_price;
      console.log("this", this.cart.items);
      console.log("that", item);
    }
  },

  mounted() {
    this.links = this.loadAll();
  },

  computed: {
    subTotal: function() {
      return this.cart.items.reduce(function(carry, item) {
        return carry + parseFloat(item.qty) * parseFloat(item.price);
      }, 0);
    },
    grandTotal: function() {
      return this.subTotal - parseFloat(this.cart.discount);
    },

    amountfn: function() {
      return this.cart.items.reduce(function(item) {
        return parseFloat(item.qty) * parseFloat(item.price);
      }, 0);
    },
  }
};
</script>

Вот мой jsfiddle

https://jsfiddle.net/coolr/87a2hjv0/7/

Спасибо

1 Ответ

1 голос
/ 29 октября 2019

Ваша проблема связана с тем, что вы не знаете, какую строку обновлять в handleSelect. Поскольку вы не можете предоставить дополнительные параметры для метода handleSelect, вы можете сделать это, установив currentItem, когда auto-complete получает фокус.

Итак, сначала нужно обновить автозаполнение (Добавлено @focus, также изменено v-model на value, это лучше использовать, я думаю):

<el-autocomplete
   class="inline-input"
   :value="scope.row.item_name"
   value-key="item_name"
   :fetch-suggestions="querySearch"
   placeholder=""
   :trigger-on-focus="false"
   @focus="setCurrentItem(scope.row)"
   @select="handleSelect"
></el-autocomplete>

Обновите ваши данные / методы в JS:

 data() {
    return {
      currentItem: null,
      // other already existing data
    };
  },
  methods: {
    // other already existing methods
    setCurrentItem(item) {
        this.currentItem = item
    },
    handleSelect(item) {
      this.currentItem.item_name = item.item_name;
      this.currentItem.price = item.selling_price;
    }
  }

Для уникальных значенийвам нужно создать вычисленное значение, которое возвращает все значения, кроме уже используемых


Для обновления цены строки вы можете сделать это двумя различными способами (в любом случае, можно удалить метод amountfn). ):

  1. при изменении, но действие запускается только тогда, когда поле теряет фокус

    <el-input v-model="scope.row.price" @change="updateTotal(scope.row)"></el-input>
    
    updateTotal(item) {
       item.total = item.price * item.qty
    },
    
  2. Использование глубокого наблюдения, обновление выполняется немедленно

     watch: {
        'cart.items' : {
            deep: true,
            handler: (items) => {
               items.forEach(element => element.total = element.price * element.qty)
             }
          }
      }
    
...