Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

158
Vistas
x-show elements based on parent element class in Alpine.js

In my WooCommerce theme, I'm want to show the spinner icon when WooCommerce dynamically adds the "loading" class to the element using AJAX.

I tried to use Alpine.js's $el property to retrieve the current DOM node, but this isn't working. It's also not 'watching' the classList of .

How can I accomplish this using Alpine.js?

<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">

    <!-- Spinner Icon -->
    <svg x-show="$el.parentElement.classList.contains('loading')" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
        ...
    </svg>

    <!-- Toevoegen aan winkelmand -->
    <span x-show="$el.parentElement.classList.contains('!loading')">
        <?php echo esc_html( $product->single_add_to_cart_text() ); ?>
    </span>
    
</button>
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Digging into WooCommerce source code revealed that it uses jQuery event system so we have to create a little event bus between jQuery and Alpine.js. The two respective events are adding_to_cart that called before the AJAX call and the added_to_cart event that triggered after the successful AJAX call (i.e. the product has been added to the cart).

Let's call our event bus catchWooEvents:

<script>
document.addEventListener('alpine:init', () => {
    Alpine.data('catchWooEvents', () => ({
        loading: false,

        init() {
            $(document.body).on('adding_to_cart', (event, button, data) => {
                this.loading = true
            })
            $(document.body).on('added_to_cart', (fragments, cart_hash, button) => {
                this.loading = false
            })
        }
    }))
})
</script>

We have a new variable loading that is active between the two events. You see that we used the jQuery's $.on() function inside the init() to catch the jQuery events, but then we manipulate an Alpine.js variable.

The modified button example:

<div x-data="catchWooEvents">
    <button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">

        <!-- Spinner Icon -->
        <svg x-show="loading" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            ...
        </svg>

        <!-- Toevoegen aan winkelmand -->
        <span x-show="!loading">
            <?php echo esc_html( $product->single_add_to_cart_text() ); ?>
        </span>
        
    </button>
</div>

We have a new parent div element where we applied the catchWooEvents component, so multiple child buttons can share the loading state. In the x-show attribute the loading variable is now reactive.

Note: the definition of catchWooEvents must be placed after the jQuery script line.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda