Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Infinite scrolling sui listati dei prodotti

PHP e e-commerce. Implementare infinite scrolling per evitare i problemi di indicizzazione dei link presenti nella paginazione tradizionale degli store.
PHP e e-commerce. Implementare infinite scrolling per evitare i problemi di indicizzazione dei link presenti nella paginazione tradizionale degli store.
Link copiato negli appunti

L'infinite scrolling è una feature AJAX che permette di evitare i problemi di indicizzazione dei link usati nella paginazione tradizionale. In questo capitolo vedremo come inserirla nel nostro e-commerce.

A ben vedere l'infinite scrolling è una forma di paginazione, con l'unica differenza che in questo caso gli elementi vengono caricati in modo asincrono mediante JavaScript.

Questa feature si basa sul concetto di offset in una query al database: se la query iniziale restituisce 10 prodotti, la prima chiamata AJAX che ha luogo quando l'utente raggiunge la fine della pagina restituirà altri 10 prodotti a partire dall'undicesimo e così via.

Classe per la gestione delle richieste

La prima cosa da fare è implementare una classe per la gestione delle richieste AJAX ed un metodo dedicato alla paginazione dell'infinite scrolling.

namespace PHPEcommerce;
class Ajax {
     public function infinite() {
        if($_SERVER['REQUEST_METHOD'] === 'GET') {
            $total_products = $db->select("SELECT count(*) AS total FROM products WHERE price > 0");
            $per_page = 10;
            $pages = floor(intval($total_products[0]['total'] ) / $per_page);
            $current_page = (isset($_GET['page']) && ctype_digit($_GET['page']) && intval($_GET['page']) <= $pages) ? intval($_GET['page']) : 1;
            $offset = $current_page * $per_page;
            $products = Templater::products($db->select("SELECT * FROM products ORDER BY price ASC LIMIT $per_page OFFSET $offset"));
            $this->json($products);
        } else {
            $this->invalidRequest();
        }
    }
     protected function invalidRequest() {
        Router::status('400', 'Bad Request');
        $this->json(['statusCode' => 400]);
    }
    protected function json($data) {
        Router::mime('application/json');
        echo json_encode($data);
        exit;
    }
}

JavaScript invia al nostro metodo un numero progressivo di pagina che servirà a calcolare l'offset nella query MySQL moltiplicando il numero di prodotti per pagina per il numero della pagina corrente.

L'endpoint

A questo punto possiamo creare un endpoint /ajax/infinite nel nostro controller principale.

public function ajax($args) {
        if(!$args) {
            Router::status('403', 'Forbidden');
            exit;
        } else {
            $endpoint = $args[0];
            $ajax = new Ajax();
            if($ajax->isEndpoint($endpoint) && method_exists($ajax, $endpoint)) {
                $ajax->$endpoint();
            } else {
                Router::status('403', 'Forbidden');
                exit;
            }
        }
    }

Codice lato client

Ora dobbiamo operare lato client intercettando lo scrolling della pagina con jQuery ed inviando il numero progressivo della paginazione nel modo corretto.

var getProducts = function( value ) {
            value = parseInt( value, 10 ) || 1;
            var perPage = 10;
            var $products = $( ".ajax-scroll .product" );
            var current = $products.length;
            var page = value + 1;
            var txt = $products.eq( 0 ).find( ".btn" ).text();
            $.get( "/ajax/infinite", { page: page }, function( response ) {
                if( Array.isArray( response ) && response.length > 0 ) {
                    var html = '';
                    for( var i = 0; i < response.length; i++ ) {
                        var product = response[i];
                        html += '<article class="col-md-6 product">';
                        html += '<header><h3>' + product.name + '</h3></header>';
                        html += '<figure><a href="' + product.link + '"><img src="' + product.image + '" class="img-fluid" alt=""></a></figure>';
                        html += ' <p class="text-muted text-truncate">' + product.description + '</p>';
                        html += '<footer class="row">';
                        html += '<div class="col-md-6">' + product.price + '</div>';
                        html += '<div class="text-right col-md-6">';
                        html += '<a href="' + product.add_to_cart_link + '" class="btn btn-success">' + txt + '</a>';
                        html += '</div>';
                        html += '</footer>';
                        html += '</article>';
                    }
                    $( ".ajax-scroll" ).data( "page", page ).append( html );
                }
            });
        };
        if( $( ".ajax-scroll" ).length && $( ".ajax-scroll .product" ).length ) {
            $( ".ajax-scroll" ).data( "page", 1 );
            $( window ).scroll(function() {
                if( $( window ).scrollTop() + $( window ).height() >= $( document ).height() ) {
                    getProducts( $( ".ajax-scroll" ).data( "page" ) );
                }
            });
}

Non facciamo altro che reperire il numero di prodotti presenti nell'elemento contenitore, calcolare con questo numero il numero di pagina, salvarlo come dato dell'elemento contenitore incrementandolo ogni volta che l'utente arriva con lo scroll in fondo alla pagina. Quindi assembliamo la struttura HTML partendo dall'array JSON restituito dal nostro endpoint.

Ti consigliamo anche