.itemPage {
min-width: 30px;
min-height: 30px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.itemPage.ativo {
font-weight: 700;
}
document.addEventListener("DOMContentLoaded", function () {
/***********************
* Funções Utilitárias *
***********************/
function getVeiculosData() {
const data = sessionStorage.getItem("veiculosList");
if (!data) {
console.warn("Nenhum dado encontrado na sessionStorage para 'veiculosList'");
return [];
}
try {
return JSON.parse(data);
} catch (e) {
console.error("Erro ao parsear os dados da sessionStorage:", e);
return [];
}
}
function updateURLParam(param, value, useReplaceState = true) {
const url = new URL(window.location.href);
if (value) {
url.searchParams.set(param, value);
} else {
url.searchParams.delete(param);
}
if (useReplaceState) {
window.history.replaceState({}, "", url);
} else {
window.history.pushState({}, "", url);
}
}
function getURLParam(name) {
const params = new URLSearchParams(window.location.search);
return params.get(name);
}
function getURLParams() {
return new URLSearchParams(window.location.search);
}
function preserveParamsOnClear() {
const params = new URLSearchParams(window.location.search);
const newParams = new URLSearchParams();
params.forEach((value, key) => {
if (key === "orderby" || key === "paginacao") {
newParams.set(key, value);
}
});
const newUrl = window.location.pathname + (newParams.toString() ? `?${newParams.toString()}` : "");
window.history.replaceState({}, "", newUrl);
}
function formatCurrency(value) {
return new Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL",
}).format(value);
}
function getCookie(name) {
let match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
return match ? decodeURIComponent(match[2]) : null;
}
/***********************************
* Funções de Paginação e Filtros *
***********************************/
function renderPagination(total, perPage, currentPage) {
const printPages = document.getElementById("printPages");
if (!printPages) return;
const totalPages = Math.ceil(total / perPage);
printPages.innerHTML = "";
if (totalPages <= 1) {
updateURLParam("paginacao", "");
return;
}
let start = Math.max(1, currentPage - 2);
let end = Math.min(totalPages, currentPage + 2);
if (currentPage <= 2) {
start = 1;
end = Math.min(5, totalPages);
}
if (currentPage >= totalPages - 1) {
start = Math.max(1, totalPages - 4);
end = totalPages;
}
if (currentPage > 1) {
if (currentPage > 2) {
const first = document.createElement("div");
first.className = "itemPage";
first.setAttribute("data-page", "1");
first.textContent = "<<";
printPages.appendChild(first);
}
const prev = document.createElement("div");
prev.className = "itemPage";
prev.setAttribute("data-page", currentPage - 1);
prev.textContent = "<";
printPages.appendChild(prev);
}
for (let i = start; i <= end; i++) {
const pageItem = document.createElement("div");
pageItem.className = "itemPage" + (i === currentPage ? " ativo" : "");
pageItem.setAttribute("data-page", i);
pageItem.textContent = i;
printPages.appendChild(pageItem);
}
if (currentPage < totalPages) {
const next = document.createElement("div");
next.className = "itemPage";
next.setAttribute("data-page", currentPage + 1);
next.textContent = ">";
printPages.appendChild(next);
if (currentPage < totalPages - 1) {
const last = document.createElement("div");
last.className = "itemPage";
last.setAttribute("data-page", totalPages);
last.textContent = ">>";
printPages.appendChild(last);
}
}
document.querySelectorAll(".itemPage").forEach((el) => {
el.addEventListener("click", () => {
const page = parseInt(el.getAttribute("data-page"));
updateURLParam("paginacao", page);
renderVeiculosList(page);
});
});
}
function applyFilters(veiculos) {
let filtered = veiculos.slice();
const buscar = getURLParam("buscar");
const orderby = getURLParam("orderby");
const locID = getCookie("locID");
if (buscar) {
const lowerBuscar = buscar.toLowerCase();
filtered = filtered.filter((v) =>
v.titulo.toLowerCase().includes(lowerBuscar) ||
JSON.stringify(v.meta).toLowerCase().includes(lowerBuscar) ||
JSON.stringify(v.terms).toLowerCase().includes(lowerBuscar)
);
}
if (locID) {
filtered = filtered.filter((v) => v.meta.unidade_id && v.meta.unidade_id.includes(locID));
}
const urlParams = new URLSearchParams(window.location.search);
urlParams.forEach((value, key) => {
if (key.startsWith("meta-")) {
const metaKey = key.replace("meta-", "");
if (value.includes("-")) {
const [min, max] = value.split("-").map(Number);
filtered = filtered.filter((v) => v.meta[metaKey] >= min && v.meta[metaKey] <= max);
} else {
filtered = filtered.filter((v) => v.meta[metaKey] && v.meta[metaKey].toString().includes(value));
}
} else if (key.startsWith("terms-")) {
const termKey = key.replace("terms-", "");
const values = value.split(",").map(Number);
filtered = filtered.filter((v) => v.terms[termKey] && values.includes(v.terms[termKey].term_id));
}
});
if (orderby) {
if (orderby === "menorpreco") {
filtered.sort((a, b) => a.meta.valorcar - b.meta.valorcar);
} else if (orderby === "maiorpreco") {
filtered.sort((a, b) => b.meta.valorcar - a.meta.valorcar);
} else if (orderby === "baixakm") {
filtered.sort((a, b) => (a.meta.kmcar || 0) - (b.meta.kmcar || 0));
} else if (orderby === "maisnovo") {
filtered.sort((a, b) => b.ID - a.ID);
} else if (orderby === "maisantigo") {
filtered.sort((a, b) => a.ID - b.ID);
}
}
return filtered;
}
/*****************************************
* População dos Selects de Filtros Base *
*****************************************/
function populateSelect(selectId, defaultOptionText, dataObj, urlParam) {
const selectEl = document.getElementById(selectId);
if (!selectEl) {
console.error(`Elemento <select id='${selectId}'> não encontrado no DOM.`);
return;
}
selectEl.innerHTML = "";
const defaultOption = document.createElement("option");
defaultOption.value = "";
defaultOption.textContent = defaultOptionText;
selectEl.appendChild(defaultOption);
Object.keys(dataObj).forEach((term_id) => {
const option = document.createElement("option");
option.value = term_id;
option.textContent = dataObj[term_id]; // O contador será acrescentado posteriormente
selectEl.appendChild(option);
});
selectEl.addEventListener("change", function () {
const selectedValue = this.value;
updateURLParam(urlParam, selectedValue, false);
renderVeiculosList();
});
}
function populateCategorias() {
const veiculos = getVeiculosData();
const categorias = {};
veiculos.forEach((v) => {
if (v.terms && v.terms.categoria) {
if (Array.isArray(v.terms.categoria)) {
v.terms.categoria.forEach((cat) => {
categorias[cat.term_id] = cat.term_name;
});
} else {
categorias[v.terms.categoria.term_id] = v.terms.categoria.term_name;
}
}
});
populateSelect("carrocerias", "Selecione Carroceria", categorias, "terms-categoria");
}
function populateMarcas() {
const veiculos = getVeiculosData();
const marcas = {};
veiculos.forEach((v) => {
if (v.terms && v.terms.marca) {
marcas[v.terms.marca.term_id] = v.terms.marca.term_name;
}
});
populateSelect("marcas", "Selecione a Marca", marcas, "terms-marca");
}
function populateOtherSelects() {
const veiculos = getVeiculosData();
const cores = {};
const transmissao = {};
const combustivel = {};
const anos = {};
veiculos.forEach((v) => {
if (v.terms) {
if (v.terms.cor) {
cores[v.terms.cor.term_id] = v.terms.cor.term_name;
}
if (v.terms.transmissao) {
transmissao[v.terms.transmissao.term_id] = v.terms.transmissao.term_name;
}
if (v.terms.combustivel) {
combustivel[v.terms.combustivel.term_id] = v.terms.combustivel.term_name;
}
if (v.terms.ano) {
anos[v.terms.ano.term_id] = v.terms.ano.term_name;
}
}
});
populateSelect("cores", "Selecione a Cor", cores, "terms-cor");
populateSelect("transmissao", "Selecione a Transmissão", transmissao, "terms-transmissao");
populateSelect("combustivel", "Selecione o Combustível", combustivel, "terms-combustivel");
populateSelect("anos", "Selecione o Ano", anos, "terms-ano");
}
function initOrderingSelects() {
const orderingSelects = document.querySelectorAll(".filtro.select.orderby");
const orderbyValue = getURLParam("orderby");
orderingSelects.forEach((select) => {
if (orderbyValue) {
select.value = orderbyValue;
}
select.addEventListener("change", function () {
const newValue = this.value;
updateURLParam("orderby", newValue, false);
orderingSelects.forEach((s) => (s.value = newValue));
renderVeiculosList();
});
});
}
function updateFiltersVisibility() {
const params = getURLParams();
const removeEls = document.querySelectorAll(".removeFilters");
if (params.toString().length > 0) {
removeEls.forEach((el) => el.classList.remove("hidden"));
} else {
removeEls.forEach((el) => el.classList.add("hidden"));
}
}
function clearFilters() {
preserveParamsOnClear();
document.querySelectorAll(".removeFilters").forEach((el) => el.classList.add("hidden"));
renderVeiculosList();
}
/************************************************************
* Atualiza os selects (exceto ordenação) com os totais e *
* reordena as opções: opções com total > 0 para o topo e *
* as com total 0 ao final. *
************************************************************/
function updateSelectOptionsValidity(filteredVehicles) {
const filtersMapping = [
{ selectId: "carrocerias", termKey: "categoria" },
{ selectId: "marcas", termKey: "marca" },
{ selectId: "cores", termKey: "cor" },
{ selectId: "transmissao", termKey: "transmissao" },
{ selectId: "combustivel", termKey: "combustivel" },
{ selectId: "anos", termKey: "ano" },
];
filtersMapping.forEach((filter) => {
const selectEl = document.getElementById(filter.selectId);
if (!selectEl) return;
// Obtenha a opção padrão (valor vazio)
const defaultOption = Array.from(selectEl.options).find((opt) => opt.value === "");
// Obtenha as demais opções
let otherOptions = Array.from(selectEl.options).filter((opt) => opt.value !== "");
otherOptions.forEach((opt) => {
// Guarde o texto original se ainda não estiver salvo
if (!opt.dataset.originalText) {
opt.dataset.originalText = opt.textContent;
}
// Conta quantos veículos do filtro possuem este term_id
const count = filteredVehicles.filter((v) => {
if (v.terms && v.terms[filter.termKey]) {
if (Array.isArray(v.terms[filter.termKey])) {
return v.terms[filter.termKey].some((t) => t.term_id.toString() === opt.value);
} else {
return v.terms[filter.termKey].term_id.toString() === opt.value;
}
}
return false;
}).length;
opt.dataset.count = count;
// Atualiza o texto da opção com o contador
opt.textContent = `${opt.dataset.originalText} (${count})`;
});
// Reordena as opções: as com count > 0 ficam primeiro
otherOptions.sort((a, b) => {
const countA = parseInt(a.dataset.count);
const countB = parseInt(b.dataset.count);
if (countA > 0 && countB === 0) return -1;
if (countA === 0 && countB > 0) return 1;
return 0;
});
// Limpa e reanexa: mantém a opção padrão no início
selectEl.innerHTML = "";
if (defaultOption) {
selectEl.appendChild(defaultOption);
}
otherOptions.forEach((opt) => selectEl.appendChild(opt));
});
}
/******************************
* Renderização da Lista de Veículos *
******************************/
function renderVeiculosList(page = null) {
const veiculosList = getVeiculosData();
if (!veiculosList.length) return;
const filteredVehicles = applyFilters(veiculosList);
const areaLoop = document.getElementById("areaLoop");
const notFoundBlock = document.getElementById("block-not-found");
if (!areaLoop) return;
const postPerPage = parseInt(areaLoop.getAttribute("post-per-page")) || 10;
const totalEncontrado = filteredVehicles.length;
let urlPage = parseInt(getURLParam("paginacao")) || 1;
let currentPage = page ? page : urlPage;
const totalPages = Math.ceil(totalEncontrado / postPerPage);
if (currentPage > totalPages) {
updateURLParam("paginacao", "");
currentPage = 1;
}
const start = (currentPage - 1) * postPerPage;
const paginatedItems = filteredVehicles.slice(start, start + postPerPage);
const totalEncontradoDiv = document.querySelector(".totalEncontrado");
const totalImpressoDiv = document.querySelector(".totalImpresso");
if (totalEncontradoDiv) totalEncontradoDiv.textContent = totalEncontrado;
if (totalImpressoDiv) totalImpressoDiv.textContent = paginatedItems.length;
if (totalEncontrado === 0) {
areaLoop.classList.add("hidden");
if (notFoundBlock) notFoundBlock.classList.remove("hidden");
updateURLParam("paginacao", "");
return;
} else {
areaLoop.classList.remove("hidden");
if (notFoundBlock) notFoundBlock.classList.add("hidden");
}
areaLoop.innerHTML = "";
const template = document.querySelector(".designOculto .veiculoList");
if (!template) return;
paginatedItems.forEach((veiculo) => {
const clone = template.cloneNode(true);
clone.setAttribute("href", veiculo.permalink);
const imgBg = clone.querySelector(".img-bg");
if (imgBg) imgBg.style.backgroundImage = `url('${veiculo.imagem_large}')`;
clone.querySelectorAll("span, div").forEach((element) => {
element.classList.forEach((className) => {
if (className.startsWith("meta-")) {
const key = className.replace("meta-", "");
if (veiculo.meta.hasOwnProperty(key)) {
let valorMeta = veiculo.meta[key];
// MELHORIA: Limpa meta-anomodcar, deixando só o ano (número)
if (className === "meta-anomodcar") {
const matchAno = String(valorMeta).match(/\\d{4}/);
valorMeta = matchAno ? matchAno[0] : "";
}
element.textContent = key === "valorcar" ? formatCurrency(valorMeta) : valorMeta;
}
} else if (className.startsWith("terms-")) {
const key = className.replace("terms-", "");
if (veiculo.terms.hasOwnProperty(key)) {
element.textContent = veiculo.terms[key]?.term_name || "";
}
}
});
});
areaLoop.appendChild(clone);
});
renderPagination(totalEncontrado, postPerPage, currentPage);
updateFiltersVisibility();
updateSelectOptionsValidity(filteredVehicles);
}
/*********************************
* Busca dos Veículos via Fetch *
*********************************/
function fetchVeiculosList() {
fetch(window.location.href, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ acao: "get_veiculos_list" }),
})
.then((response) => {
if (!response.ok) {
throw new Error("Erro na requisição");
}
return response.json();
})
.then((data) => {
try {
sessionStorage.setItem("veiculosList", JSON.stringify(data));
} catch (e) {
console.error("Erro ao armazenar dados na sessionStorage:", e);
}
triggerFunctionsJs();
})
.catch((error) => {
console.error("Erro ao buscar veículos:", error);
});
}
/*******************************
* Inicialização Geral *
*******************************/
function triggerFunctionsJs() {
populateCategorias();
populateMarcas();
populateOtherSelects();
renderVeiculosList();
}
const inputBuscar = document.getElementById("filtro-buscar");
if (inputBuscar) {
const initialBuscar = getURLParam("buscar");
if (initialBuscar) {
inputBuscar.value = initialBuscar;
}
inputBuscar.addEventListener("keyup", function () {
const valor = this.value.trim();
updateURLParam("buscar", valor);
renderVeiculosList();
});
}
initOrderingSelects();
document.querySelectorAll(".removeFilters").forEach((el) => {
el.addEventListener("click", clearFilters);
});
fetchVeiculosList();
});