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_page entre 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