Sistema de Eventos

Vanilla Smart Select emite diversos eventos que permitem reagir a interações do usuário e mudanças de estado.

💡 Prefixo de Eventos: Todos os eventos são prefixados com vs: para evitar conflitos com outros plugins.

Eventos Básicos

vs:select

Disparado quando um item é selecionado.

select.on('vs:select', function(e) {
  console.log('Item selecionado:', e.detail);
  // e.detail contém: { id, text, element, ... }
});

vs:unselect

Disparado quando um item é desselecionado (apenas multi-select).

select.on('vs:unselect', function(e) {
  console.log('Item removido:', e.detail);
});

vs:change

Disparado quando o valor do select muda.

select.on('vs:change', function(e) {
  console.log('Valor mudou para:', this.val());
  console.log('Dados completos:', this.getSelected());
});

vs:clear

Disparado quando a seleção é limpa (via botão X ou clear()).

select.on('vs:clear', function(e) {
  console.log('Seleção limpa');
});

Eventos de Dropdown

vs:open

Disparado quando o dropdown é aberto.

select.on('vs:open', function(e) {
  console.log('Dropdown aberto');
});

vs:close

Disparado quando o dropdown é fechado.

select.on('vs:close', function(e) {
  console.log('Dropdown fechado');
});

Eventos de Busca

vs:query

Disparado quando o usuário digita no campo de busca.

select.on('vs:query', function(e) {
  console.log('Termo de busca:', e.detail.query);
});

vs:results

Disparado quando os resultados da busca são exibidos.

select.on('vs:results', function(e) {
  console.log('Resultados encontrados:', e.detail.results.length);
});

Eventos de Lifecycle

vs:init

Disparado quando o plugin é inicializado.

select.on('vs:init', function(e) {
  console.log('Plugin inicializado');
});

vs:destroy

Disparado quando o plugin é destruído.

select.on('vs:destroy', function(e) {
  console.log('Plugin destruído');
});

Eventos AJAX

vs:ajaxLoading

Disparado quando uma requisição AJAX é iniciada.

select.on('vs:ajaxLoading', function(e) {
  console.log('Carregando dados...');
});

vs:ajaxSuccess

Disparado quando uma requisição AJAX é bem-sucedida.

select.on('vs:ajaxSuccess', function(e) {
  console.log('Dados carregados:', e.detail.data);
});

vs:ajaxError

Disparado quando uma requisição AJAX falha.

select.on('vs:ajaxError', function(e) {
  console.error('Erro ao carregar dados:', e.detail.error);
});

vs:dataLoaded

Disparado quando dados são carregados (AJAX ou local).

select.on('vs:dataLoaded', function(e) {
  console.log('Dados disponíveis:', e.detail.data.length);
});

Eventos Especiais

vs:selectionLimitReached

Disparado quando o limite máximo de seleções é atingido.

select.on('vs:selectionLimitReached', function(e) {
  console.log('Limite atingido:', e.detail.maximum);
  alert('Você só pode selecionar ' + e.detail.maximum + ' itens');
});

Eventos Preventivos

Alguns eventos podem ser cancelados chamando e.preventDefault():

vs:selecting

Disparado antes de um item ser selecionado. Pode ser cancelado.

select.on('vs:selecting', function(e) {
  // Impedir seleção de itens com ID ímpar
  if (parseInt(e.detail.id) % 2 !== 0) {
    e.preventDefault();
    alert('Apenas IDs pares podem ser selecionados');
  }
});

vs:unselecting

Disparado antes de um item ser desselecionado. Pode ser cancelado.

select.on('vs:unselecting', function(e) {
  if (!confirm('Tem certeza que deseja remover este item?')) {
    e.preventDefault();
  }
});

vs:clearing

Disparado antes da seleção ser limpa. Pode ser cancelado.

select.on('vs:clearing', function(e) {
  if (!confirm('Limpar toda a seleção?')) {
    e.preventDefault();
  }
});

vs:opening

Disparado antes do dropdown abrir. Pode ser cancelado.

select.on('vs:opening', function(e) {
  // Carregar dados antes de abrir
  if (!dataLoaded) {
    e.preventDefault();
    loadData().then(() => select.open());
  }
});

vs:closing

Disparado antes do dropdown fechar. Pode ser cancelado.

select.on('vs:closing', function(e) {
  // Manter aberto se a busca ainda está ativa
  if (isSearching) {
    e.preventDefault();
  }
});

Ouvindo Eventos

Adicionar Listener

function myHandler(e) {
  console.log('Evento disparado:', e.type);
  console.log('Dados:', e.detail);
}

select.on('vs:select', myHandler);

Remover Listener

select.off('vs:select', myHandler);

Múltiplos Eventos

// Ouvir vários eventos
select
  .on('vs:select', handleSelect)
  .on('vs:unselect', handleUnselect)
  .on('vs:change', handleChange);

Event Delegation (DOM Nativo)

Você também pode usar eventos nativos do DOM:

document.getElementById('my-select').addEventListener('vs:select', function(e) {
  console.log('Item selecionado via DOM:', e.detail);
});

Estrutura dos Dados do Evento

A propriedade e.detail contém informações específicas de cada evento:

vs:select / vs:unselect

{
  id: "1",
  text: "Opção 1",
  element: HTMLOptionElement,
  disabled: false,
  selected: true,
  // ... outros campos customizados
}

vs:query

{
  query: "termo de busca",
  term: "termo de busca" // alias
}

vs:results

{
  results: [
    { id: "1", text: "Opção 1" },
    { id: "2", text: "Opção 2" }
  ],
  query: "termo"
}

vs:ajaxSuccess

{
  data: { ... }, // Resposta da API
  status: 200,
  xhr: XMLHttpRequest
}

vs:selectionLimitReached

{
  maximum: 5,
  current: 5
}

Exemplo Completo

const select = new VanillaSmartSelect('#my-select', {
  multiple: true,
  maximumSelectionLength: 3
});

// Eventos básicos
select.on('vs:select', function(e) {
  console.log('✅ Selecionado:', e.detail.text);
  updateUI();
});

select.on('vs:unselect', function(e) {
  console.log('❌ Removido:', e.detail.text);
  updateUI();
});

select.on('vs:change', function() {
  const values = this.val();
  console.log('📝 Valores atuais:', values);
  saveToLocalStorage(values);
});

// Eventos de dropdown
select.on('vs:open', function() {
  console.log('📂 Dropdown aberto');
  trackEvent('dropdown_opened');
});

select.on('vs:close', function() {
  console.log('📁 Dropdown fechado');
});

// Busca
select.on('vs:query', function(e) {
  console.log('🔍 Buscando:', e.detail.query);
  trackSearchQuery(e.detail.query);
});

// Limite de seleção
select.on('vs:selectionLimitReached', function(e) {
  alert(`Você só pode selecionar ${e.detail.maximum} itens!`);
});

// Eventos preventivos
select.on('vs:selecting', function(e) {
  // Validar antes de selecionar
  if (!isValidChoice(e.detail.id)) {
    e.preventDefault();
    showError('Esta opção não está disponível para você');
  }
});

// Cleanup
select.on('vs:destroy', function() {
  console.log('🗑️ Plugin destruído');
  cleanup();
});