AJAX Básico
Integre com APIs externas usando AJAX/Fetch para carregar dados remotos dinamicamente. Suporte completo a debounce, cache, templates customizados e tratamento de erros.
REST Countries API
Busca de países em tempo real usando a API pública REST Countries.
Ver código
HTML
<select id="countries"></select>
JavaScript
const countriesSelect = new VanillaSmartSelect('#countries', {
placeholder: 'Digite para buscar países...',
allowClear: true,
ajax: {
url: 'https://restcountries.com/v3.1/name',
delay: 300,
transport: (params, config) => {
const searchTerm = params.term || 'brazil';
const url = `${config.url}/${encodeURIComponent(searchTerm)}`;
const abortController = new AbortController();
const fetchPromise = fetch(url, {
signal: abortController.signal
}).then(response => response.json());
fetchPromise.abort = () => abortController.abort();
return fetchPromise;
},
processResults: (data) => {
const results = data.map(country => ({
id: country.cca3,
text: country.name.common,
flag: country.flag,
capital: country.capital?.[0],
population: country.population
}));
return { results };
}
},
templateResult: (item) => {
return `
<div style="display: flex; gap: 10px;">
<span>${item.flag}</span>
<div>
<div>${item.text}</div>
<small>Capital: ${item.capital}</small>
</div>
</div>
`;
}
});
ViaCEP - Busca de CEP
Busca de endereços brasileiros por CEP usando a API ViaCEP.
Ver código
HTML
<select id="cep"></select>
JavaScript
const cepSelect = new VanillaSmartSelect('#cep', {
placeholder: 'Digite um CEP para buscar...',
allowClear: true,
ajax: {
url: 'https://viacep.com.br/ws',
delay: 400,
transport: (params, config) => {
const cep = (params.term || '').replace(/\D/g, '');
if (cep.length < 8) return Promise.resolve([]);
const url = `${config.url}/${cep}/json/`;
return fetch(url)
.then(response => response.json())
.then(data => data.erro ? [] : [data]);
},
processResults: (data) => {
const results = data.map(address => ({
id: address.cep,
text: `${address.cep} - ${address.logradouro}`,
logradouro: address.logradouro,
bairro: address.bairro,
localidade: address.localidade,
uf: address.uf
}));
return { results };
}
}
});
Busca de Filmes (Simulado)
Exemplo de busca com dados locais simulando uma API de filmes.
Ver código
HTML
<select id="movies"></select>
JavaScript
const moviesSelect = new VanillaSmartSelect('#movies', {
placeholder: 'Digite para buscar filmes...',
allowClear: true,
ajax: {
delay: 300,
transport: (params) => {
return new Promise((resolve) => {
setTimeout(() => {
const term = (params.term || '').toLowerCase();
const filtered = moviesDatabase.filter(movie =>
movie.title.toLowerCase().includes(term)
);
resolve(filtered);
}, 500);
});
},
processResults: (data) => {
return {
results: data.map(movie => ({
id: movie.id,
text: movie.title,
year: movie.year,
genre: movie.genre,
rating: movie.rating
}))
};
}
},
templateResult: (item) => {
return `
<div style="display: flex; justify-content: space-between;">
<div>
<div>🎬 ${item.text}</div>
<small>${item.year} • ${item.genre}</small>
</div>
<span style="background: #ffc107; padding: 4px 8px; border-radius: 4px;">
⭐ ${item.rating}
</span>
</div>
`;
}
});
Headers Customizados
Configure headers HTTP customizados, incluindo autenticação Bearer e Content-Type.
Ver código
HTML
<select id="auth-api"></select>
JavaScript
const authSelect = new VanillaSmartSelect('#auth-api', {
placeholder: 'Buscar dados autenticados...',
ajax: {
url: 'https://api.example.com/data',
delay: 300,
transport: (params, config) => {
const abortController = new AbortController();
const fetchPromise = fetch(config.url, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN_HERE',
'Content-Type': 'application/json',
'X-Custom-Header': 'CustomValue'
},
body: JSON.stringify({
query: params.term,
limit: 20
}),
signal: abortController.signal
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
});
fetchPromise.abort = () => abortController.abort();
return fetchPromise;
},
processResults: (data) => {
return {
results: data.results.map(item => ({
id: item.id,
text: item.name
}))
};
}
}
});
Tratamento de Erros
Monitore e trate erros de requisições AJAX usando eventos customizados.
Ver código
HTML
<select id="error-demo"></select>
JavaScript
const errorSelect = new VanillaSmartSelect('#error-demo', {
placeholder: 'Digite para testar...',
ajax: {
url: 'https://api.invalid-domain-example-12345.com/search',
delay: 300,
transport: (params, config) => {
const abortController = new AbortController();
const fetchPromise = fetch(config.url, {
signal: abortController.signal
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
});
fetchPromise.abort = () => abortController.abort();
return fetchPromise;
}
}
});
// Monitorar eventos
const selectElement = document.getElementById('error-demo');
selectElement.addEventListener('vs:ajaxLoading', (e) => {
console.log('🔄 Carregando...', e.detail);
});
selectElement.addEventListener('vs:ajaxSuccess', (e) => {
console.log('✅ Sucesso!', e.detail.data);
alert('Dados carregados com sucesso!');
});
selectElement.addEventListener('vs:ajaxError', (e) => {
console.error('❌ Erro ao carregar:', e.detail.error);
alert(`Erro: ${e.detail.error.message}`);
});
Eventos AJAX
Monitore o estado das requisições usando eventos:
JavaScript
// Eventos disponíveis
selectElement.addEventListener('vs:ajaxLoading', (e) => {
console.log('Carregando...', e.detail);
});
selectElement.addEventListener('vs:ajaxSuccess', (e) => {
console.log('Sucesso!', e.detail);
});
selectElement.addEventListener('vs:ajaxError', (e) => {
console.error('Erro:', e.detail);
});
Recursos Implementados
- ✅ Carregamento assíncrono via fetch API
- ✅ Debounce automático para evitar requisições excessivas
- ✅ Transport customizado para controle total das requisições
- ✅ Busca remota com parâmetros dinâmicos
- ✅ Indicador de carregamento
- ✅ Tratamento de erros com mensagens customizadas
- ✅ Templates customizados para resultados
- ✅ Suporte a AbortController para cancelar requisições
- ✅ Headers HTTP customizados (Authorization, Content-Type)
- ✅ Eventos de sucesso e erro para monitoramento