Tags

The Tags feature allows users to create new options dynamically as they type. Ideal for email fields, categories, tags, and user mentions.

Email Tags with Validation

Tags with email format validation and multiple selection:

View code

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;

    // Email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(term)) {
      return null; // Invalid email
    }

    return {
      id: term,
      text: term
    };
  },
  insertTag: (data, tag) => {
    // Insert at the beginning
    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>`;
  }
});

Custom Categories

Dynamic creation of categories with automatic formatting:

View code

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: 'Select or create categories...',
  tags: true,
  createTag: (params) => {
    const term = params.term?.trim();
    if (!term) return null;

    // Convert to lowercase and replace spaces with hyphens
    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 with Custom Validation

Tags with selection limit, alphanumeric validation and custom colors:

View code

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: 'Type tags (alphanumeric)...',
  tags: true,
  maximumSelectionLength: 5,
  createTag: (params) => {
    const term = params.term?.trim();
    if (!term) return null;

    // Only alphanumeric characters and hyphens
    const validTag = /^[a-zA-Z0-9-]+$/;
    if (!validTag.test(term)) {
      return null; // Invalid format
    }

    // Generate random color
    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>`;
  }
});

User Mentions (Single Select)

Mention system with @ for single selection:

View code

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: 'Type @username...',
  allowClear: true,
  tags: true,
  createTag: (params) => {
    let term = params.term?.trim();
    if (!term) return null;

    // Ensure it starts with @
    if (!term.startsWith('@')) {
      term = '@' + term;
    }

    // Remove @ for the ID
    const username = term.substring(1);

    // Only alphanumeric and underscores
    if (!/^[a-zA-Z0-9_]+$/.test(username)) {
      return null;
    }

    return {
      id: username,
      text: term,
      name: term // No real name for new users
    };
  },
  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;
  }
});

Tags Configuration

Main Options

Option Type Description
tags Boolean Enables dynamic tag creation
createTag Function Function that validates and creates new tag objects
insertTag Function Function that defines where to insert the new tag in the data array

_isTag Property

When a tag is created dynamically, the object has the _isTag: true property. Use this in templateResult to display a different message during creation.

createTag Parameters

createTag: (params) => {
  // params.term: text typed by the user
  
  // Return null to reject the tag
  if (/* validation failed */) {
    return null;
  }
  
  // Return object with id and text to create the tag
  return {
    id: '...',
    text: '...',
    // ... other custom fields
  };
}
✅ Usage Tips
  • Use createTag to validate format before creating the tag
  • Combine tags with maximumSelectionLength to limit selections
  • Use insertTag to control the position of new tags
  • Add custom fields (like colors) to tag objects
  • Tags can be used in single or multiple mode