or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-class.mdevents.mdindex.mdtemplates.md
tile.json

events.mddocs/

Events System

Choices.js provides a comprehensive event system that allows you to hook into various lifecycle events and user interactions. All events are dispatched on the original element that was enhanced with Choices.

Capabilities

Event Types

The available event types that can be listened for using standard DOM event listeners.

const EventType = {
  showDropdown: 'showDropdown',
  hideDropdown: 'hideDropdown', 
  change: 'change',
  choice: 'choice',
  search: 'search',
  addItem: 'addItem',
  removeItem: 'removeItem',
  highlightItem: 'highlightItem',
  highlightChoice: 'highlightChoice',
  unhighlightItem: 'unhighlightItem',
} as const;

type EventTypes = 'showDropdown' | 'hideDropdown' | 'change' | 'choice' | 'search' | 'addItem' | 'removeItem' | 'highlightItem' | 'highlightChoice' | 'unhighlightItem';

Dropdown Events

Events related to dropdown visibility and interaction.

/**
 * Fired when the dropdown is shown
 * Event detail: empty object
 */
'showDropdown': CustomEvent<{}>;

/**
 * Fired when the dropdown is hidden
 * Event detail: empty object  
 */
'hideDropdown': CustomEvent<{}>;

Usage Examples:

const element = document.querySelector('#my-select');
const choices = new Choices(element);

element.addEventListener('showDropdown', (event) => {
  console.log('Dropdown opened');
});

element.addEventListener('hideDropdown', (event) => {
  console.log('Dropdown closed');
});

Value Change Events

Events fired when the selected values change through user interaction or programmatic updates.

/**
 * Fired when the value changes (items added, removed, or modified)
 * Event detail contains the current value
 */
'change': CustomEvent<{ value: any }>;

Usage Examples:

element.addEventListener('change', (event) => {
  console.log('Value changed to:', event.detail.value);
  
  // For multi-select, value will be an array
  if (Array.isArray(event.detail.value)) {
    console.log('Selected items:', event.detail.value.length);
  }
});

Choice Selection Events

Events related to selecting and interacting with individual choices in the dropdown.

/**
 * Fired when a choice is selected from the dropdown
 * Event detail contains information about the selected choice
 */
'choice': CustomEvent<EventChoice>;

/**
 * Fired when a choice is highlighted (hover or keyboard navigation)
 * Event detail contains information about the highlighted choice
 */
'highlightChoice': CustomEvent<EventChoice>;

interface EventChoice extends InputChoice {
  element?: HTMLOptionElement | HTMLOptGroupElement;
  groupValue?: string;
  keyCode?: number;
}

Usage Examples:

element.addEventListener('choice', (event) => {
  const choice = event.detail;
  console.log('Choice selected:', choice.label, 'with value:', choice.value);
  
  // Access custom properties if available
  if (choice.customProperties) {
    console.log('Custom data:', choice.customProperties);
  }
  
  // Check if triggered by keyboard
  if (choice.keyCode) {
    console.log('Selected via keyboard, keyCode:', choice.keyCode);
  }
});

element.addEventListener('highlightChoice', (event) => {
  const choice = event.detail;
  console.log('Choice highlighted:', choice.label);
  
  // Access element if available
  if (choice.element) {
    console.log('Original element:', choice.element);
  }
});

Item Management Events

Events fired when items are added, removed, or highlighted in the selection area.

/**
 * Fired when an item is added to the selection
 * Event detail contains information about the added item
 */
'addItem': CustomEvent<{
  id: number;
  value: any;
  label: string;
  customProperties?: any;
  keyCode?: number;
}>;

/**
 * Fired when an item is removed from the selection
 * Event detail contains information about the removed item
 */
'removeItem': CustomEvent<{
  id: number;
  value: any;
  label: string;
  customProperties?: any;
}>;

/**
 * Fired when an item is highlighted (for removal or editing)
 * Event detail contains information about the highlighted item
 */
'highlightItem': CustomEvent<{
  id: number;
  value: any;
  label: string;
  customProperties?: any;
}>;

/**
 * Fired when an item highlight is removed
 * Event detail contains information about the unhighlighted item
 */
'unhighlightItem': CustomEvent<{
  id: number;
  value: any;
  label: string;
  customProperties?: any;
}>;

Usage Examples:

element.addEventListener('addItem', (event) => {
  console.log('Item added:', event.detail.label, 'with value:', event.detail.value);
  console.log('Item ID:', event.detail.id);
  
  // Track user vs programmatic additions via keyCode
  if (event.detail.keyCode) {
    console.log('Added via user input (keyCode:', event.detail.keyCode, ')');
  }
});

element.addEventListener('removeItem', (event) => {
  console.log('Item removed:', event.detail.label);
});

element.addEventListener('highlightItem', (event) => {
  console.log('Item highlighted for action:', event.detail.label);
});

element.addEventListener('unhighlightItem', (event) => {
  console.log('Item unhighlighted:', event.detail.label);
});

Search Events

Events related to search functionality and user input.

/**
 * Fired when search input changes
 * Event detail contains the search term and result count  
 */
'search': CustomEvent<{
  value: string;
  resultCount: number;
}>;

Usage Examples:

element.addEventListener('search', (event) => {
  console.log('Search term:', event.detail.value);
  console.log('Results found:', event.detail.resultCount);
  
  // Implement custom search logging or analytics
  if (event.detail.value.length > 0) {
    analytics.track('choices_search', {
      term: event.detail.value,
      results: event.detail.resultCount
    });
  }
});

Event Handling Best Practices

Event Listener Setup

Recommended patterns for setting up event listeners effectively.

const element = document.querySelector('#my-select');
const choices = new Choices(element);

// Set up multiple event listeners
const eventHandlers = {
  change: (event) => {
    console.log('Value changed:', event.detail.value);
  },
  
  addItem: (event) => {
    console.log('Item added:', event.detail);
    // Validate or process new items
  },
  
  removeItem: (event) => {
    console.log('Item removed:', event.detail);
    // Handle cleanup or confirmation
  }
};

// Attach all handlers
Object.entries(eventHandlers).forEach(([eventType, handler]) => {
  element.addEventListener(eventType, handler);
});

Event Cleanup

Proper cleanup when destroying Choices instances.

const element = document.querySelector('#my-select');
const choices = new Choices(element);

// Store handler references for cleanup
const changeHandler = (event) => {
  console.log('Value changed:', event.detail.value);
};

element.addEventListener('change', changeHandler);

// Cleanup when done
function cleanup() {
  element.removeEventListener('change', changeHandler);
  choices.destroy();
}

Integration with Frameworks

Examples of integrating Choices.js events with popular frameworks.

// React integration example
useEffect(() => {
  const element = elementRef.current;
  const choices = new Choices(element);
  
  const handleChange = (event) => {
    setValue(event.detail.value);
  };
  
  element.addEventListener('change', handleChange);
  
  return () => {
    element.removeEventListener('change', handleChange);
    choices.destroy();
  };
}, []);

// Vue.js integration example  
mounted() {
  this.choices = new Choices(this.$refs.select);
  
  this.$refs.select.addEventListener('change', (event) => {
    this.$emit('input', event.detail.value);
  });
},

beforeDestroy() {
  if (this.choices) {
    this.choices.destroy();
  }
}

Custom Event Dispatching

While Choices.js handles most event dispatching automatically, you can also dispatch custom events:

// Dispatch custom events for integration
const dispatchCustomEvent = (eventType, detail) => {
  const customEvent = new CustomEvent(`choices:${eventType}`, {
    detail,
    bubbles: true
  });
  element.dispatchEvent(customEvent);
};

// Listen for custom events
element.addEventListener('choices:customAction', (event) => {
  console.log('Custom action triggered:', event.detail);
});