Tags

O recurso de Tags permite que os usuários criem novas opções dinamicamente enquanto digitam. Ideal para campos de email, categorias, etiquetas e menções de usuários.

Email Tags com Validação

Tags com validação de formato de email e múltipla seleção:

Ver código

HTML

<select id="emails" multiple></select>

JavaScript

const emailsData = [
  { id: '1', text: 'joao@exemplo.com' },
  { id: '2', text: 'maria@exemplo.com' },
  { id: '3', text: 'pedro@exemplo.com' }
];

const emailsSelect = new VanillaSmartSelect('#emails', {
  data: emailsData,
  multiple: true,
  placeholder: 'Digite emails...',
  tags: true,
  createTag: (params) => {
    const term = params.term?.trim();
    if (!term) return null;

    // Validação de email
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(term)) {
      return null; // Email inválido
    }

    return {
      id: term,
      text: term
    };
  },
  insertTag: (data, tag) => {
    // Inserir no início
    data.unshift(tag);
  },
  templateResult: (item) => {
    if (item._isTag) {
      return `<div style="font-weight: 500;">➕ Adicionar email: <strong>${item.text}</strong></div>`;
    }
    return `<div>📧 ${item.text}</div>`;
  }
});

Categorias Personalizadas

Criação dinâmica de categorias com formatação automática:

Ver código

HTML

<select id="categories" multiple></select>

JavaScript

const categoriesData = [
  { id: 'javascript', text: 'JavaScript' },
  { id: 'python', text: 'Python' },
  { id: 'css', text: 'CSS' },
  { id: 'html', text: 'HTML' }
];

const categoriesSelect = new VanillaSmartSelect('#categories', {
  data: categoriesData,
  multiple: true,
  placeholder: 'Selecione ou crie categorias...',
  tags: true,
  createTag: (params) => {
    const term = params.term?.trim();
    if (!term) return null;

    // Converter para lowercase e substituir espaços por hífens
    const id = term.toLowerCase().replace(/\s+/g, '-');

    return {
      id: id,
      text: term
    };
  },
  templateResult: (item) => {
    if (item._isTag) {
      return `<div style="font-weight: 500;">✨ Criar nova categoria: "${item.text}"</div>`;
    }
    return `<div>🏷️ ${item.text}</div>`;
  },
  templateSelection: (item) => {
    return item.text;
  }
});

Tags com Validação Customizada

Tags com limite de seleção, validação alfanumérica e cores personalizadas:

Ver código

HTML

<select id="custom-tags" multiple></select>

JavaScript

const customTagsData = [
  { id: 'important', text: 'important', color: '#dc3545' },
  { id: 'urgent', text: 'urgent', color: '#ffc107' },
  { id: 'bug', text: 'bug', color: '#6f42c1' },
  { id: 'feature', text: 'feature', color: '#28a745' }
];

const customTagsSelect = new VanillaSmartSelect('#custom-tags', {
  data: customTagsData,
  multiple: true,
  placeholder: 'Digite tags (alfanuméricas)...',
  tags: true,
  maximumSelectionLength: 5,
  createTag: (params) => {
    const term = params.term?.trim();
    if (!term) return null;

    // Apenas caracteres alfanuméricos e hífens
    const validTag = /^[a-zA-Z0-9-]+$/;
    if (!validTag.test(term)) {
      return null; // Formato inválido
    }

    // Gerar cor aleatória
    const colors = ['#007bff', '#28a745', '#dc3545', '#ffc107', '#17a2b8', '#6f42c1'];
    const randomColor = colors[Math.floor(Math.random() * colors.length)];

    return {
      id: term.toLowerCase(),
      text: term.toLowerCase(),
      color: randomColor
    };
  },
  templateResult: (item) => {
    if (item._isTag) {
      return `<div style="font-weight: 500;">
        <span style="font-size: 18px;">+</span> Criar tag: <strong>${item.text}</strong>
        <div style="font-size: 11px; margin-top: 4px; color: #999;">Apenas letras, números e hífens</div>
      </div>`;
    }
    return `<div>
      <span style="display: inline-block; width: 12px; height: 12px; border-radius: 50%; background: ${item.color}; margin-right: 8px;"></span>
      ${item.text}
    </div>`;
  },
  templateSelection: (item) => {
    return `<span style="color: ${item.color}">🏷️ ${item.text}</span>`;
  }
});

Menções de Usuários (Single Select)

Sistema de menções com @ para seleção única:

Ver código

HTML

<select id="mentions"></select>

JavaScript

const mentionsData = [
  { id: 'john', text: '@john', name: 'John Doe' },
  { id: 'jane', text: '@jane', name: 'Jane Smith' },
  { id: 'bob', text: '@bob', name: 'Bob Johnson' }
];

const mentionsSelect = new VanillaSmartSelect('#mentions', {
  data: mentionsData,
  placeholder: 'Digite @usuario...',
  allowClear: true,
  tags: true,
  createTag: (params) => {
    let term = params.term?.trim();
    if (!term) return null;

    // Garantir que comece com @
    if (!term.startsWith('@')) {
      term = '@' + term;
    }

    // Remover @ para o ID
    const username = term.substring(1);

    // Apenas alfanuméricos e underscores
    if (!/^[a-zA-Z0-9_]+$/.test(username)) {
      return null;
    }

    return {
      id: username,
      text: term,
      name: term // Sem nome real para novos usuários
    };
  },
  templateResult: (item) => {
    if (item._isTag) {
      return `<div style="font-weight: 500;">
        ➕ Mencionar novo usuário: <strong>${item.text}</strong>
      </div>`;
    }
    return `<div>
      <div style="font-weight: 500;">${item.text}</div>
      <div style="font-size: 12px; color: #666;">${item.name}</div>
    </div>`;
  },
  templateSelection: (item) => {
    return item.text;
  }
});

Configuração de Tags

Opções Principais

Opção Tipo Descrição
tags Boolean Habilita a criação de tags dinâmicas
createTag Function Função que valida e cria novos objetos de tag
insertTag Function Função que define onde inserir a nova tag no array de dados

Propriedade _isTag

Quando uma tag é criada dinamicamente, o objeto tem a propriedade _isTag: true. Use isso no templateResult para exibir uma mensagem diferente durante a criação.

Parâmetros de createTag

createTag: (params) => {
  // params.term: texto digitado pelo usuário
  
  // Retorne null para rejeitar a tag
  if (/* validação falhou */) {
    return null;
  }
  
  // Retorne objeto com id e text para criar a tag
  return {
    id: '...',
    text: '...',
    // ... outros campos customizados
  };
}
✅ Dicas de Uso
  • Use createTag para validar o formato antes de criar a tag
  • Combine tags com maximumSelectionLength para limitar seleções
  • Use insertTag para controlar a posição das novas tags
  • Adicione campos customizados (como cores) nos objetos de tag
  • Tags podem ser usadas em modo single ou multiple