6

Quick question about Vue JS. On my website, I have got a shopping cart and the user can enter any quantity. I am saving this quantity to the database table when he enters it...

issue is, the input field keeps firing save method every single digit of user types. For example, if the user types 123, the save method called 3 times. 1 and 12 and 123

I just want to call this save method when this input loses the focus, so I can save only once, not every single digit.

Component

Vue.component('product-counter', {
props: ['quantity'],
data: function () {
    return {
        count: this.quantity
    }
},
template: `
        <div class="input-group ">
          <input  v-bind:value="quantity" v-on:input.focus="$emit('input', $event.target.value)"  type="text" class="form-control col-2">
        </div>
        `
 })

Component Call

                <product-counter 
                             v-bind:productcode="item.productCode"  
                             v-bind:quantity="item.quan" 
                             v-on:input="item.quan=updateItemQuantity($event,item.productCode)" 
                             v-on:increment-quantity="item.quan=updateItemQuantity(item.quan,item.productCode)" 
                             v-on:decrement-quantity="item.quan=updateItemQuantity(item.quan,item.productCode)"></product-counter>

Vue: Method

        "updateItemQuantity": function (totalquantity, pcode) {
       if (totalquantity != '') {
           ... Update Database...              
        }
    }

3 Answers 3

14

You're listening to the input event, which is triggered every time the value of the input changes, so every time a character is typed or removed. Instead, you should listen to the blur event, which only fires when an input loses focus.

You can pass this along through your component, the same way you pass through the input event.

TLDR: Couple UpdateItemQuantity to v-on:blur instead of v-on:input, and make sure to $emit the blur event from your products-counter component.


Tip: Separate the client-side state (item.quan) and your server-side 'state' (your database) into two different methods. You want the value to reflect what the user is typing in real-time (input), which conflicts with what you want for updating the database (not real-time, only on blur). Otherwise you may get cases where users can't see what they type, as item.quan is never updated.

Sign up to request clarification or add additional context in comments.

Comments

5

I think you just need to use @change instead of @input

2 Comments

Finally, I thought no one will suggest. This is most generic solution.
Using 'change' does make more sense for this use case. 'blur' will always fire even if input field got focus, but user did not change value and klicks somewhere else. 'change' will only fire when the value has changed.
2

It could be that you should use blur event. Vue:

    new Vue({
        el: "#app",
        data: {
            quantity: ''
        },
        methods: {
            printConsole: function () {
                console.log('blured');
            }
        }
    })

html:

        <div id='app'>
            <input v-bind:value="quantity" v-on:blur="printConsole" type="text" class="form-control col-2">
        </div>

see jsfiddle for reference: https://jsfiddle.net/erezka/h8g62xfr/11/

blur will emit your change only after you focus out of the input

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.