Ordenación de productos para Loop Grid de elementor Pro

Ordenación de productos para Loop Grid

El Loop Grid de elementor es uno de mis widgets favoritos, nos permite crear cuadrículas donde mostrar los productos de la tienda y hacer un diseño realmente a medida.

Por supuesto, también tenemos que hacer el item de producto, es decir una plantilla que mostrará el aspecto de cada uno de los productos que aparecen listados en la tienda.

Aunque disponemos de un widget en elementor Pro (el filtro de taxonomía) para filtrar por categoría, marca u otras taxonomías, elementor Pro no dispone de un elemento para la ordenación de productos.

Me refiero al típico desplegable que nos permite ordenar los productos por precio, orden alfabético, populares, novedades…

Asi que vamos a crear un desplegable Ajax (no recarga la página) para hacer esta función, sin plugins ni complicaciones.

Como es lógico, debes tener creada tu página de la tienda con el maquetador de temas de elementor, y haber creado la cuadrícula en bucle (el Loop Grid) con su correspondiente plantilla de Loop item.

El fragmento de código

Para conseguir esta función, sólo has de añadir un fragmento de código, lo mejor es que lo hagas usando el famosísimo plugin Code Snippets del que te hablo aquí.

Si ya lo tienes instalado, te vas a Fragmentos de código / Añadir nuevo, le das un nombre como Desplegable para ordenar productos y pegas lo siguiente:

				
					/**
 * OPCIONES DE ORDENACIÓN
 */
function ayra_opciones_orden_productos() {

    return array(
        'date'       => 'Últimos productos',
        'title-asc'  => 'Orden alfabético: A–Z',
        'title-desc' => 'Orden alfabético: Z–A',
        'price'      => 'Precio: menor a mayor',
        'price-desc' => 'Precio: mayor a menor',
        'popularity' => 'Más populares',
        'rating'     => 'Mejor valorados',
    );
}


/**
 * OBTENER EL ORDEN SELECCIONADO
 */
function ayra_obtener_orden_productos() {

    $opciones = ayra_opciones_orden_productos();

    if ( isset( $_GET['orderby'] ) ) {
        $orden = sanitize_key( wp_unslash( $_GET['orderby'] ) );
    } elseif ( isset( $_COOKIE['ayra_product_order'] ) ) {
        $orden = sanitize_key(
            wp_unslash( $_COOKIE['ayra_product_order'] )
        );
    } else {
        $orden = 'date';
    }

    return isset( $opciones[ $orden ] ) ? $orden : 'date';
}


/**
 * SHORTCODE DEL DESPLEGABLE
 *
 * Uso: [ayra_ordenar_productos]
 */
add_shortcode(
    'ayra_ordenar_productos',
    'ayra_selector_orden_productos'
);

function ayra_selector_orden_productos() {

    if ( ! function_exists( 'wc_query_string_form_fields' ) ) {
        return '';
    }

    $opciones     = ayra_opciones_orden_productos();
    $orden_actual = ayra_obtener_orden_productos();
    $select_id    = wp_unique_id( 'ayra-orderby-' );

    ob_start();
    ?>

    <form
        class="ayra-ordenar-productos"
        method="get"
        data-ayra-ordering-form
        data-target="ayra-productos-grid"
    >

        <label
            class="screen-reader-text"
            for="<?php echo esc_attr( $select_id ); ?>"
        >
            Ordenar productos
        </label>

        <select
            id="<?php echo esc_attr( $select_id ); ?>"
            name="orderby"
            class="orderby"
            data-ayra-ordering
        >
            <?php foreach ( $opciones as $valor => $texto ) : ?>

                <option
                    value="<?php echo esc_attr( $valor ); ?>"
                    <?php selected( $orden_actual, $valor ); ?>
                >
                    <?php echo esc_html( $texto ); ?>
                </option>

            <?php endforeach; ?>
        </select>

        <?php
        /*
         * Conserva los filtros de colecciones y categorías
         * presentes en la URL.
         */
        wc_query_string_form_fields(
            null,
            array(
                'orderby',
                'submit',
                'paged',
                'product-page',
            )
        );
        ?>

        <span
            class="screen-reader-text"
            aria-live="polite"
            data-ayra-ordering-status
        ></span>

        <noscript>
            <button type="submit">Ordenar</button>
        </noscript>

    </form>

    <?php
    static $recursos_cargados = false;

    if ( ! $recursos_cargados ) :
        $recursos_cargados = true;
        ?>

        <style>
            #ayra-productos-grid {
                transition: opacity 0.2s ease;
            }

            #ayra-productos-grid.ayra-cargando {
                opacity: 0.35;
                pointer-events: none;
            }
        </style>

        <script>window.addEventListener('DOMContentLoaded', function() {
        (function () {

            if (window.ayraOrdenacionProductosIniciada) {
                return;
            }

            window.ayraOrdenacionProductosIniciada = true;

            async function ayraOrdenarProductos(select) {

                const form = select.closest('[data-ayra-ordering-form]');

                if (!form) {
                    return;
                }

                const targetId = form.dataset.target;
                const grid = document.getElementById(targetId);
                const status = form.querySelector(
                    '[data-ayra-ordering-status]'
                );

                if (!grid) {
                    form.submit();
                    return;
                }

                const url = new URL(window.location.href);

                url.searchParams.set('orderby', select.value);
                url.searchParams.delete('paged');
                url.searchParams.delete('product-page');

                /*
                 * Regresar a la primera página del Loop Grid
                 * cuando se cambia la ordenación.
                 */
                Array.from(url.searchParams.keys()).forEach(function (key) {
                    if (key.indexOf('e-page-') === 0) {
                        url.searchParams.delete(key);
                    }
                });

                let cookie = 'ayra_product_order=' +
                    encodeURIComponent(select.value) +
                    '; path=/; max-age=31536000; SameSite=Lax';

                if (window.location.protocol === 'https:') {
                    cookie += '; Secure';
                }

                document.cookie = cookie;

                select.disabled = true;
                grid.classList.add('ayra-cargando');
                grid.setAttribute('aria-busy', 'true');

                if (status) {
                    status.textContent = 'Ordenando productos…';
                }

                try {

                    const response = await fetch(url.toString(), {
                        method: 'GET',
                        credentials: 'same-origin',
                        cache: 'no-store',
                        headers: {
                            'X-Requested-With': 'XMLHttpRequest'
                        }
                    });

                    if (!response.ok) {
                        throw new Error('No se pudo cargar la ordenación.');
                    }

                    const html = await response.text();

                    const documento = new DOMParser().parseFromString(
                        html,
                        'text/html'
                    );

                    const nuevoGrid = documento.getElementById(targetId);

                    if (!nuevoGrid) {
                        throw new Error('No se encontró el Loop Grid.');
                    }

                    /*
                     * Sustituimos únicamente el contenido del Loop Grid.
                     * La página no se recarga y no cambia de posición.
                     */
                    grid.innerHTML = nuevoGrid.innerHTML;

                    window.history.pushState(
                        {},
                        '',
                        url.toString()
                    );

                    /*
                     * Reactivar los widgets que contiene el Loop Grid.
                     */
                    if (
                        window.elementorFrontend &&
                        window.jQuery &&
                        window.elementorFrontend.elementsHandler
                    ) {
                        window.elementorFrontend.elementsHandler
                            .runReadyTrigger(window.jQuery(grid));
                    }

                    document.dispatchEvent(
                        new CustomEvent('ayra:productos-ordenados', {
                            detail: {
                                orderby: select.value,
                                grid: grid
                            }
                        })
                    );

                    if (status) {
                        status.textContent = 'Productos ordenados.';
                    }

                } catch (error) {

                    /*
                     * Si el AJAX falla, se utiliza la recarga tradicional
                     * como método de respaldo.
                     */
                    window.location.href = url.toString();

                } finally {

                    select.disabled = false;
                    grid.classList.remove('ayra-cargando');
                    grid.removeAttribute('aria-busy');
                }
            }

            document.addEventListener('change', function (event) {

                const select = event.target.closest(
                    '[data-ayra-ordering]'
                );

                if (select) {
                    ayraOrdenarProductos(select);
                }
            });

            document.addEventListener('submit', function (event) {

                const form = event.target.closest(
                    '[data-ayra-ordering-form]'
                );

                if (!form) {
                    return;
                }

                event.preventDefault();

                const select = form.querySelector(
                    '[data-ayra-ordering]'
                );

                if (select) {
                    ayraOrdenarProductos(select);
                }
            });

        })();
        });</script>

        <?php
    endif;

    return ob_get_clean();
}


/**
 * MODIFICAR LA CONSULTA DEL LOOP GRID DE PRODUCTOS
 *
 * Se identifica mediante el ID CSS "ayra-productos-grid".
 */
add_filter(
    'elementor/query/query_args',
    'ayra_aplicar_orden_loop_productos',
    50,
    2
);

function ayra_aplicar_orden_loop_productos( $query_args, $widget ) {

    if (
        ! is_object( $widget ) ||
        ! method_exists( $widget, 'get_name' ) ||
        ! method_exists( $widget, 'get_settings_for_display' ) ||
        'loop-grid' !== $widget->get_name()
    ) {
        return $query_args;
    }

    $css_id = $widget->get_settings_for_display( '_element_id' );

    if ( 'ayra-productos-grid' !== $css_id ) {
        return $query_args;
    }

    $orden = ayra_obtener_orden_productos();

    switch ( $orden ) {

        case 'title-asc':
            $query_args['orderby'] = 'title';
            $query_args['order']   = 'ASC';
            break;

        case 'title-desc':
            $query_args['orderby'] = 'title';
            $query_args['order']   = 'DESC';
            break;

        case 'price':
            $query_args['meta_key'] = '_price';
            $query_args['orderby']  = 'meta_value_num';
            $query_args['order']    = 'ASC';
            break;

        case 'price-desc':
            $query_args['meta_key'] = '_price';
            $query_args['orderby']  = 'meta_value_num';
            $query_args['order']    = 'DESC';
            break;

        case 'popularity':
            $query_args['meta_key'] = 'total_sales';
            $query_args['orderby']  = 'meta_value_num';
            $query_args['order']    = 'DESC';
            break;

        case 'rating':
            $query_args['meta_key'] = '_wc_average_rating';
            $query_args['orderby']  = 'meta_value_num';
            $query_args['order']    = 'DESC';
            break;

        case 'date':
        default:
            $query_args['orderby'] = 'date';
            $query_args['order']   = 'DESC';
            break;
    }

    return $query_args;
}
				
			

Hacer que reconozca el Loop Grid

Para que el snippet pueda identificar que Loop Grid es el que debe ordenar, has de seleccionar tu Loop Grid, ir a Avanzado y en ID de CSS escribir la clase ayra-productos-grid

Mostrar el desplegable de ordenación

Simplemente arrastra donde quieras (normalmente sobre los productos) un widget de Shortcode y escribe [ayra_ordenar_productos]

No hace falta darle CSS, con el propio elementor puedes alinearlo a la derecha o a la izquierda y darle un ancho personalizado, por ejemplo 220px

Con estos sencillos pasos ya tienes hecha la ordenación de productos para loop Grid.

Ordenación de productos para Loop Grid

Ya no tienes excusa para que tu tienda online Woocommerce tenga todas las funciones necesarias diseñando a medida con elementor Pro.

¿Aún no tienes elementor Pro?

Comparte en tus Redes Sociales

Facebook
Twitter
LinkedIn
Pinterest
WhatsApp

Suscríbete a nuestra Newsletter y consigue un descuento en tu primera compra

Sólo por registrarte, te regalamos un cupón para que consigas elementor Pro aún mas barato.

Suscríbete a nuestra Newsletter para estar informado de todas las novedades y descuentos