Catálogo de Produtos - Listar Produtos com AJAX

Como gerar listas de produtos diretamente da base de dados por ajax

DEMO


O carregamento por AJAX permite controlar a chamada dinâmica de listas de produtos. Pode ser usada por exemplo:


🪑 Cuidado: Como a solicitação dos produtos é via data-driven direto para o banco, não é interessante utilizá-la sem necessidade;


📦 As listas de produtos podem ser estensas, já que geram páginas estáticas, ou seja, é melhor gerenciar via script o carregamento de 250 a 1000 produtos do que chamar dinâmicamente de 10 em 10, por exemplo;


🔎 Os recursos data-driven do catálogo são esses carregamentos assíncronos e as buscas, vale lembrar que se o site tem menos de 500 ou 1000 produtos, pode ser viável fazer a busca via script na lista do total de produtos.


Veja o exemplo na página inicial do catálogo dos componentes


Os carregamentos na página de exemplo:


Parâmetros utilizados no exemplo

A solicitação é por AJAX via API. Só funciona no domínio real do site.

Veja comentários das variáveis utilizadas na URL ($mainData é variável do PHP no contexto da home.php [template]);


undefined

URLs usadas acima:


//rolagem

var scrollDeep = 1;
xmlhttp.send("&categoryId=0&siteId='.$mainData['siteId'].'&scrollDeep="+scrollDeep+"&listQtd=4&req=listProducts&filters=83,84");
scrollDeep ++;

//produtos de uma caregoria

xmlhttpAjaxProduct.send("&categoryId=241&siteId='.$mainData['siteId'].'&scrollDeep=0&listQtd=1&req=listProducts&filters=83,84");

//produtos por id

xmlhttpAjaxProductByClick.send("&categoryId=0&siteId='.$mainData['siteId'].'&scrollDeep=0&listQtd=3&req=listProducts&filters=83,84&products=108018,108021,108022");




Exemplos de chamadas do script no contexto do template em PHP


Carregamento padrão para rolagem

Carregamento de produtos ao chegar no final da página. 83 e 84 são ids específicos de filtrosdo catálogo de componentes. A variável scrollDeep controla os limites das listas para não aparecem duplicados ou chegar no final.
Como este script foi utilizado na inicial, não usa-se categoria, mas pode adicionar o id da categoria dinamicamente em lists.php para listagens de categorias e categorias adicionais específicas.




<!-- load more products on scrolling -->
<script>
 //scroll button to show more stuff
 var scrollDeep = 1;
 window.addEventListener("scroll", scrollF);
 
 function scrollF(evt) {
 
 //console.log("SCROLL:"+(window.innerHeight + window.scrollY+1));
 //console.log("DOC:"+document.body.offsetHeight);
 if ((window.innerHeight + window.scrollY + 1) >= document.body.offsetHeight) {
 
 console.log("load more: "+scrollDeep);
 
 if (navigator.onLine) {
 var xmlhttp;
 if (window.XMLHttpRequest) {
 xmlhttp = new XMLHttpRequest();
 } 
 else {
 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange = function() { 
 if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
 if(xmlhttp.status == 200){
 let data = xmlhttp.responseText;
 
 console.log(data);
 
 if(data == 0) {
 window.removeEventListener("scroll", scrollF);
 }
 else { //load additional list
 
 let obj = JSON.parse(data);
 console.log(obj);
 
 var render = "";
 
 for(var i = 0; i < obj.length; ++i) {
 
 let product = JSON.parse(obj[i]);
 console.log(product);
 let productImg = "";
 let productPrice = "";
 
 if(product.img == "") {
 productImg = "https://cdn.interago.com.br/img/png/w_0_q_8/1/mc/cdn//productGeneric";
 }
 else {
 productImg = product.img;
 }
 
 productImg = productImg.replace("w_0_", "w_400_");
 
 if(product.price != "0.00") {
 productPrice = "<small>R$ </small>"+product.price;
 productPrice = productPrice.replace(".", ",");
 }

 console.log(product[\'83\'][\'filterValue\']);
 
 render += "<div class=\'col-6 col-sm-6 col-md-6 productItem\'>\
 <a href=\'item/"+product.url+"\'>\
 <div class=\'productImg\'>\
 <img src=\'"+productImg+"\' alt=\'Imagem do produto "+product.title+"\' title=\'"+product.title+"\'/>\
 </div>\
 \
 <h2 class=\'productTitle\' title=\'"+product.title+"\'>"+product.title+"</h2>\
 <p class=\'productPrice\'>"+productPrice+"</p>\
 \<p>"+product[\'83\'][\'filterKey\']+": "+product[\'83\'][\'filterValue\']+"</p>\
 <p>"+product[\'84\'][\'filterKey\']+": "+product[\'84\'][\'filterValue\']+"</p>\
 </a>\
 </div>";
 
 
 }
 
 }
 if(render != undefined) {
 console.log(render); document.getElementById("listProductsContainer").insertAdjacentHTML("beforeend", render);
 }
 scrollDeep++;
 }
 }
 }
 let url = "https://www.interago.com.br/App/Extensions/5/compile/assets/loadProductList.php";
 xmlhttp.open("POST", url, true);
 xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 xmlhttp.setTimeout = 6000; //6s
 xmlhttp.ontimeout = function() {
 console.log("🚨 tempo esgotado - impossível enviar");
 }
 xmlhttp.send("&categoryId=0&siteId='.$mainData['siteId'].'&scrollDeep="+scrollDeep+"&listQtd=4&req=listProducts&filters=83,84"); 
 } else {
 console.log("🚨 navegador offline");
 }
 
 }
 
 
 }

</script>




Carregamento padrão de produtos por categoria

Neste exemplo os filtros 83 e 84 são exclusivos do exemplo. O carregamento no id específicos  também.



<!-- load first product of a category -->
<script>
 
 if(navigator.onLine) {

 var xmlhttpAjaxProduct;
 if (window.XMLHttpRequest) {
 xmlhttpAjaxProduct = new XMLHttpRequest();
 } 
 else {
 xmlhttpAjaxProduct = new ActiveXObject("Microsoft.XMLHTTP");
 }


 xmlhttpAjaxProduct.onreadystatechange = function() { 
 
 if (xmlhttpAjaxProduct.readyState == XMLHttpRequest.DONE ) {
 
 if(xmlhttpAjaxProduct.status == 200){
 
 let data = xmlhttpAjaxProduct.responseText;
 
 console.log(data);
 
 if(data == 0) {
 window.removeEventListener("scroll", scrollF);
 }
 else { //load additional list
 
 let obj = JSON.parse(data);
 console.log(obj);
 
 var render = "";
 
 for(var i = 0; i < obj.length; ++i) {
 
 let product = JSON.parse(obj[i]);
 console.log(product);
 let productImg = "";
 let productPrice = "";
 
 if(product.img == "") {
 productImg = "https://cdn.interago.com.br/img/png/w_0_q_8/1/mc/cdn//productGeneric";
 }
 else {
 productImg = product.img;
 }
 
 productImg = productImg.replace("w_0_", "w_400_");
 
 if(product.price != "0.00") {
 productPrice = "<small>R$ </small>"+product.price;
 productPrice = productPrice.replace(".", ",");
 }

 render += "\
 <div class=\'col-6 col-sm-6 col-md-6 productItem\'>\
 <a href=\'item/"+product.url+"\'>\
 <div class=\'productImg\'>\
 <img src=\'"+productImg+"\' alt=\'Imagem do produto "+product.title+"\' title=\'"+product.title+"\'/>\
 </div>\
 \
 <h2 class=\'productTitle\' title=\'"+product.title+"\'>"+product.title+"</h2>\
 <p class=\'productPrice\'>"+productPrice+"</p>\
 \<p>"+product[\'83\'][\'filterKey\']+": "+product[\'83\'][\'filterValue\']+"</p>\
 <p>"+product[\'84\'][\'filterKey\']+": "+product[\'84\'][\'filterValue\']+"</p>\
 </a>\
 </div>";
 
 
 }
 
 }
 if(render != undefined) {
 console.log(render); document.getElementById("loadOneProductFromCategory").insertAdjacentHTML("afterbegin", render);
 }
 
 }
 }
 }
 
 let url = "https://www.interago.com.br/App/Extensions/5/compile/assets/loadProductList.php";
 xmlhttpAjaxProduct.open("POST", url, true);
 xmlhttpAjaxProduct.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 xmlhttpAjaxProduct.setTimeout = 6000; //6s
 xmlhttpAjaxProduct.ontimeout = function() {
 console.log("🚨 tempo esgotado - impossível enviar");
 }
 
 xmlhttpAjaxProduct.send("&categoryId=241&siteId='.$mainData['siteId'].'&scrollDeep=0&listQtd=1&req=listProducts&filters=83,84"); 
 } 
 else {
 console.log("🚨 navegador offline");
 }
 console.log("ending script..."); 
 </script>




Carregamento de produtos por id

O id utilizado para imprimir e os filtros 83 e 84 só funcionam neste exemplo. Lembre-se que o total de produtos precisa estar na URL além dos ids separados por vírgula.





<!-- load one or any products by id on click a element -->
<script>
 

 document.getElementById("loadProductsByDemandButton").addEventListener("click", loadProductsFunction, false);

 function loadProductsFunction() {

 if(navigator.onLine) {

 var xmlhttpAjaxProductByClick;
 if (window.XMLHttpRequest) {
 xmlhttpAjaxProductByClick = new XMLHttpRequest();
 } 
 else {
 xmlhttpAjaxProductByClick = new ActiveXObject("Microsoft.XMLHTTP");
 }


 xmlhttpAjaxProductByClick.onreadystatechange = function() { 
 
 if (xmlhttpAjaxProductByClick.readyState == XMLHttpRequest.DONE ) {
 
 if(xmlhttpAjaxProductByClick.status == 200){
 
 let data = xmlhttpAjaxProductByClick.responseText;
 
 console.log(data);
 
 if(data == 0) {
 window.removeEventListener("scroll", scrollF);
 }
 else { //load additional list
 
 let obj = JSON.parse(data);
 console.log(obj);
 
 var render = "";
 
 for(var i = 0; i < obj.length; ++i) {
 
 let product = JSON.parse(obj[i]);
 console.log(product);
 let productImg = "";
 let productPrice = "";
 
 if(product.img == "") {
 productImg = "https://cdn.interago.com.br/img/png/w_0_q_8/1/mc/cdn//productGeneric";
 }
 else {
 productImg = product.img;
 }
 
 productImg = productImg.replace("w_0_", "w_400_");
 
 if(product.price != "0.00") {
 productPrice = "<small>R$ </small>"+product.price;
 productPrice = productPrice.replace(".", ",");
 }

 render += "\
 <div class=\'col-6 col-sm-6 col-md-6 productItem\'>\
 <a href=\'item/"+product.url+"\'>\
 <div class=\'productImg\'>\
 <img src=\'"+productImg+"\' alt=\'Imagem do produto "+product.title+"\' title=\'"+product.title+"\'/>\
 </div>\
 \
 <h2 class=\'productTitle\' title=\'"+product.title+"\'>"+product.title+"</h2>\
 <p class=\'productPrice\'>"+productPrice+"</p>\
 \<p>"+product[\'83\'][\'filterKey\']+": "+product[\'83\'][\'filterValue\']+"</p>\
 <p>"+product[\'84\'][\'filterKey\']+": "+product[\'84\'][\'filterValue\']+"</p>\
 </a>\
 </div>";
 
 
 }
 
 }
 if(render != undefined) {
 console.log(render); document.getElementById("loadProductsByDemand").insertAdjacentHTML("afterbegin", render);
 }
 
 }
 }
 }
 
 let url = "https://www.interago.com.br/App/Extensions/5/compile/assets/loadProductList.php";
 xmlhttpAjaxProductByClick.open("POST", url, true);
 xmlhttpAjaxProductByClick.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 xmlhttpAjaxProductByClick.setTimeout = 6000; //6s
 xmlhttpAjaxProductByClick.ontimeout = function() {
 console.log("🚨 tempo esgotado - impossível enviar");
 }
 
 xmlhttpAjaxProductByClick.send("&categoryId=0&siteId='.$mainData['siteId'].'&scrollDeep=0&listQtd=3&req=listProducts&filters=83,84&products=108018,108021,108022"); 
 } 
 else {
 console.log("🚨 navegador offline");
 }
 console.log("ending script..."); 
 }
 </script>


Você também pode gostar de ler

Guia completo para o catálogo de produtos (Extensão)

Em 14/06/2022 às 13h38 - Atualizado em 11/04/2025 às 13h17

Guia da Extensão #11 Promoções

Em 04/09/2023 às 10h41 - Atualizado em 12/02/2025 às 09h16

Carrinho de compras cart2.js

Em 29/11/2022 às 12h54 - Atualizado em 03/02/2025 às 11h54

Buscas e Pesquisas no Catálogo de produtos

Em 01/03/2023 às 09h23 - Atualizado em 16/12/2024 às 11h48

Extensão #9 Envios e cálculos de frete

Em 23/03/2023 às 20h22 - Atualizado em 15/09/2023 às 09h49

Checkout e Pedidos - Extensão #10

Em 01/06/2023 às 14h35 - Atualizado em 18/08/2023 às 08h36

Estoque do Catálogo de Produtos - Layout, Uso e Consultas

Em 13/02/2023 às 14h40 - Atualizado em 07/08/2023 às 22h28

001. Catálogo em Lista - Formato Imobiliária

Em 29/06/2022 às 11h22 - Atualizado em 16/08/2022 às 09h09