skip to Main Content

Trying to use AlpineJS in Woocommerce checkout. I have input number field with + – indicators to increase value, simplefield code:

<div x-data="{ qty: 1 }">
  <i @click="qty = qty > 2 ? qty - 1 : 1" class="icon-left-open"></i>

  <input type="number" x-model="qty">

  <i @click="qty = qty + 1" class="icon-right-open"></i>
</div>

So the problem is that when the input value changes woocommerce "update cart" button still has a disabled state. I thought this was happing because x-model and 2-way binding don’t fire native change/input events?

How to tell woocommerce that value changed?

2

Answers


  1. Chosen as BEST ANSWER

    As pointed out @Craig E we need to use x-init and $watch, but that is just half of work, we also need to notify Woocommercec about input change. One way to do this is use this one liner:

    x-init="$watch('qty', () => $refs.qty_input.dispatchEvent(new Event('change', { bubbles: true })))"
    

    We should also add $ref on target element:

    x-ref="qty_input"
    

    Complete code:

    <div 
      x-data="{ qty: 1 }" 
      x-init="$watch('qty', () => $refs.qty_input.dispatchEvent(new Event('change', { bubbles: true })))">
      <i @click="qty = qty > 2 ? qty - 1 : 1" class="icon-left-open"></i>
    
      <input type="number" x-ref="qty_input" x-model="qty">
    
      <i @click="qty = qty + 1" class="icon-right-open"></i>
    </div>
    

  2. You can "watch" an x-data variable using $watch.

    You can find out more about $watch here: https://github.com/alpinejs/alpine#watch

    For example, this watches the "qty" value and if is changed it’ll dispatch a "qty_true" event.

    x-init="$watch('qty',value => { if (value) $dispatch('qty_true'); })"
    

    Here’s a version of your code with $watch, and the "qty_true" event listener.

    <div x-data="{ qty: 1 }" x-init="$watch('qty',value => { if (value) $dispatch('qty_true'); })">
        <i @click="qty = qty > 2 ? qty - 1 : 1" class="icon-left-open"></i>
            
        <input type="number" x-model="qty">
            
        <i @click="qty = qty + 1" class="icon-right-open"></i>
    </div>
    
    <script type="text/javascript">
        window.addEventListener( 'qty_true', ( e ) => {
            console.log( 'qty now evaluates to true' );
            // enable your button here
        } );
    </script>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search