Paginação
Infinite scroll automático para carregar grandes conjuntos de dados progressivamente. Quando você rola a lista de resultados até o final, o Vanilla Smart Select detecta automaticamente e carrega a próxima página.
GitHub Repositories - Infinite Scroll
Busque repositórios do GitHub com infinite scroll automático. Role até o final para carregar mais resultados.
Ver código
HTML
<select id="github-repos"></select>
JavaScript
const reposSelect = new VanillaSmartSelect('#github-repos', {
placeholder: 'Digite para buscar repositórios...',
allowClear: true,
ajax: {
url: 'https://api.github.com/search/repositories',
delay: 400,
data: (params) => ({
q: params.term || 'javascript',
page: params.page || 1,
per_page: 10
}),
processResults: (data, params) => {
const results = data.items.map(repo => ({
id: repo.id,
text: repo.full_name,
name: repo.name,
full_name: repo.full_name,
description: repo.description || 'No description',
stars: repo.stargazers_count,
forks: repo.forks_count,
language: repo.language || 'Unknown',
url: repo.html_url
}));
return {
results: results,
pagination: {
more: data.items.length >= 10
}
};
}
},
templateResult: (item) => {
const div = document.createElement('div');
div.innerHTML = `
<div style="display: flex; gap: 12px;">
<div>📦</div>
<div>
<div style="font-weight: 500;">${item.full_name}</div>
<div style="font-size: 12px; color: #666;">${item.description}</div>
<div style="font-size: 11px; color: #888; margin-top: 4px;">
⭐ ${item.stars.toLocaleString()} | 🍴 ${item.forks.toLocaleString()} | 💻 ${item.language}
</div>
</div>
</div>
`;
return div;
},
templateSelection: (item) => {
return `📦 ${item.full_name}`;
}
});
GitHub Users - Infinite Scroll
Busque usuários do GitHub com paginação automática.
Ver código
HTML
<select id="github-users"></select>
JavaScript
const usersSelect = new VanillaSmartSelect('#github-users', {
placeholder: 'Digite para buscar usuários...',
allowClear: true,
ajax: {
url: 'https://api.github.com/search/users',
delay: 400,
data: (params) => ({
q: params.term || 'john',
page: params.page || 1,
per_page: 15
}),
processResults: (data) => {
const results = data.items.map(user => ({
id: user.id,
text: user.login,
login: user.login,
avatar: user.avatar_url,
url: user.html_url,
type: user.type
}));
return {
results: results,
pagination: {
more: data.items.length >= 15
}
};
}
},
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '10px';
div.innerHTML = `
<img src="${item.avatar}" style="width: 32px; height: 32px; border-radius: 50%;" />
<div>
<div style="font-weight: 500;">${item.login}</div>
<div style="font-size: 11px; color: #666;">${item.type}</div>
</div>
`;
return div;
},
templateSelection: (item) => {
return item.login;
}
});
Simulação de API Paginada
Exemplo simulado com dados locais para demonstrar o conceito de paginação (100 itens).
Ver código
HTML
<select id="simulated"></select>
JavaScript
// Gerar 100 itens de exemplo
const allItems = Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
text: `Item ${i + 1}`,
category: ['Electronics', 'Books', 'Clothing', 'Food'][i % 4],
price: (Math.random() * 1000).toFixed(2)
}));
const simulatedSelect = new VanillaSmartSelect('#simulated', {
placeholder: 'Buscar items (simulado)...',
allowClear: true,
ajax: {
url: '', // Não usado
delay: 300,
transport: (params) => {
// Simular delay de API
return new Promise((resolve) => {
setTimeout(() => {
const term = (params.term || '').toLowerCase();
const page = params.page || 1;
const perPage = 10;
// Filtrar por termo de busca
let filtered = allItems.filter(item =>
item.text.toLowerCase().includes(term) ||
item.category.toLowerCase().includes(term)
);
// Paginar
const start = (page - 1) * perPage;
const end = start + perPage;
const pageItems = filtered.slice(start, end);
resolve({
items: pageItems,
total: filtered.length
});
}, 500);
});
},
processResults: (data, params) => {
const page = params.page || 1;
const perPage = 10;
const hasMore = (page * perPage) < data.total;
return {
results: data.items,
pagination: { more: hasMore }
};
}
},
templateResult: (item) => {
const div = document.createElement('div');
div.innerHTML = `
<div style="display: flex; justify-content: space-between;">
<div>
<div style="font-weight: 500;">${item.text}</div>
<div style="font-size: 11px; color: #666;">${item.category}</div>
</div>
<div style="color: #007bff; font-weight: 600;">$${item.price}</div>
</div>
`;
return div;
},
templateSelection: (item) => {
return `${item.text} - $${item.price}`;
}
});
Configuração de Paginação
Estrutura do processResults
Para habilitar a paginação, o processResults deve retornar um objeto com a propriedade pagination:
processResults: (data, params) => {
return {
results: [...], // Array de resultados
pagination: {
more: true // true se há mais páginas
}
};
}
Parâmetros Automáticos
O Vanilla Smart Select passa automaticamente o número da página em params.page:
data: (params) => ({
q: params.term,
page: params.page || 1, // Página atual
per_page: 10
})
Eventos de Paginação
| Evento | Descrição |
|---|---|
vs:ajaxLoading |
Disparado quando uma página está sendo carregada |
vs:ajaxSuccess |
Disparado quando a página é carregada com sucesso |
vs:ajaxError |
Disparado se houver erro ao carregar |
select.addEventListener('vs:ajaxLoading', (e) => {
console.log('Carregando página:', e.detail.params.page);
});
select.addEventListener('vs:ajaxSuccess', (e) => {
console.log('Carregados', e.detail.results.results.length, 'itens');
console.log('Tem mais?', e.detail.results.pagination.more);
});
✅ Dicas de Uso
- Use
per_pageentre 10-20 para melhor performance - O infinite scroll é automático - não precisa de código adicional
- Os resultados são acumulados automaticamente
- Funciona perfeitamente com busca - cada termo reinicia a paginação
- Combine com templates customizados para resultados ricos