0

I'm trying to update a list of products with an editable quantity, which updates and changes a row-wise total of product prices. Please see my code below -

<template>
    <div>
        <product-search-bar :product_search_route="product_search_route" />

        <table class="table table-hover table-responsive table-striped">
            <thead>
            <tr>
                <th>#</th>
                <th>Name</th>
                <th>Qty.</th>
                <th>Price</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(product, index) in product_list">
                <td>
                    {{ index + 1 }}
                    <input type="hidden" :name="'order_items[' + index + '][id]'" :value="product.id" />
                </td>
                <td>{{ product.name }}</td>
                <td>
                    <input type="number" :name="'order_items[' + index + '][qty]'" @change="product_quantity_changed($event, product)" />
                </td>
                <td>{{ product.purchase_currency }} {{ product.total_price }}</td>
            </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default {
        name: 'form-purchase-order-items',
        props: [
            'product_search_route',
        ],
        data() {
            return {
                product_list: []
            };
        },
        mounted() {
        },
        methods: {
            /**
             *
             * @param product
             */
            product_added(product)
            {
                product.quantity = 1;
                product.total_price = product.supplier.purchase_price;

                if (!this.product_list.find((v) => { return v.id == product.id }))
                    this.product_list.push(product);
            },

            /**
             *
             * @param product
             */
            product_quantity_changed(e, product)
            {
                var quantity = Number(e.target.value);
                this.$set(product, 'quantity', quantity);
                this.$set(product, 'total_price', (quantity * product.supplier.purchase_price));
            }
        },
        watch: {
        }
    }
</script>

The price total does update correctly, seen through Vue DevTools, however, the column <td>{{ product.purchase_currency }} {{ product.total_price }}</td> doesn't reflect the changes made. I've read the documentation and I think this is something that isn't mentioned there.

Edit:

The two members quantity and total_price are being created after the object is received in the product_added(product) callback. This probably makes them non-reactive members of the object.

5
  • Try not passing product into @change, instead just pass the index then in method use $set on this.product_list[index] and see if this works? Commented Jul 24, 2018 at 9:05
  • @Zlatev I've tried this too, the result is identical to the current code. Commented Jul 24, 2018 at 9:06
  • Setting a v-for :key (vuejs.org/v2/guide/list.html#key) is also worth a try Commented Jul 24, 2018 at 9:09
  • 1
    I prepared jsfiddle jsfiddle.net/eywraw8t/201784 the value changed but you need to remove focus from input to fire change handler, I suggest to use input event it will be more informative. Commented Jul 24, 2018 at 9:11
  • 1
    $set only work on vue data ! Your product is not vue data ! It is temp array data @SagunKho Commented Jul 24, 2018 at 9:29

2 Answers 2

2

try @input instead of @change in following html code:

<input type="number" :name="'order_items[' + index + '][qty]'" @change="product_quantity_changed($event, product)" />
Sign up to request clarification or add additional context in comments.

Comments

0

I was able to fix this by making quantity and total_price reactive members.

        product_added(product)
        {
            this.$set(product, 'quantity', 1);
            this.$set(product, 'total_purchase_price', product.supplier.purchase_price);

            if (!this.product_list.find((v) => { return v.id == product.id }))
                this.product_list.push(product);
        },

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.