CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-choices-js

A vanilla JS customisable text input/select box plugin with no jQuery dependency

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Choices.js

Choices.js is a lightweight (~20kb gzipped), vanilla JavaScript select box and text input plugin that serves as an alternative to jQuery-dependent libraries like Select2 and Selectize. It provides comprehensive customization options for creating enhanced select elements, multi-select interfaces, and text inputs with features including configurable sorting, flexible CSS styling, fast search and filtering capabilities, right-to-left language support, and custom templating.

Package Information

  • Package Name: choices.js
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install choices.js

Core Imports

import Choices from "choices.js";

For CommonJS:

const Choices = require("choices.js");

Basic Usage

import Choices from "choices.js";

// Basic select enhancement
const element = document.querySelector('.js-choice');
const choices = new Choices(element);

// Text input with configuration  
const textInput = new Choices('#text-input', {
  delimiter: ',',
  editItems: true,
  maxItemCount: 5,
  removeItemButton: true,
});

// Pre-configure choices for select
const selectElement = new Choices('#select-element', {
  choices: [
    { value: 'one', label: 'Option One' },
    { value: 'two', label: 'Option Two', selected: true },
    { value: 'three', label: 'Option Three', disabled: true },
  ]
});

Architecture

Choices.js is built around several key components:

  • Core Class: Choices class providing the primary API for initialization and control
  • Configuration System: Extensive options object for customizing behavior, styling, and functionality
  • Event System: Comprehensive event dispatch for lifecycle hooks and user interactions
  • Template System: Customizable HTML template functions for rendering UI components
  • Store Management: Internal state management for choices, items, and groups
  • Search Integration: Multiple search strategies including Fuse.js integration and basic filtering

Capabilities

Core Choices Class

Main plugin class providing initialization, configuration, and control methods for enhanced select and input elements.

class Choices {
  constructor(
    element?: string | Element | HTMLInputElement | HTMLSelectElement,
    userConfig?: Partial<Options>
  );
  
  // Static properties
  static version: string;
  static defaults: {
    options: Partial<Options>;
    allOptions: Options;
    templates: Templates;
  };
  
  // Instance properties
  readonly initialised: boolean;
  readonly initialisedOK?: boolean;
  readonly config: Options;
  
  // Lifecycle methods
  init(): void;
  destroy(): void;
  enable(): this;
  disable(): this;
  
  // Value management
  getValue<B extends boolean = false>(valueOnly?: B): EventChoiceValueType<B> | EventChoiceValueType<B>[];
  setValue(items: string[] | InputChoice[]): this;
  setChoiceByValue(value: string | string[]): this;
  setChoices(
    choicesArrayOrFetcher: 
      | (InputChoice | InputGroup)[]
      | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>),
    value?: string | null,
    label?: string,
    replaceChoices?: boolean,
    clearSearchFlag?: boolean
  ): this | Promise<this>;
  refresh(withEvents?: boolean, selectFirstOption?: boolean, deselectAll?: boolean): this;
  
  // Item management
  highlightItem(item: InputChoice, runEvent?: boolean): this;
  unhighlightItem(item: InputChoice, runEvent?: boolean): this;
  highlightAll(): this;
  unhighlightAll(): this;
  removeActiveItemsByValue(value: string): this;
  removeActiveItems(excludedId?: number): this;
  removeHighlightedItems(runEvent?: boolean): this;
  
  // Choice management
  removeChoice(value: string): this;
  clearChoices(): this;
  clearStore(clearOptions?: boolean): this;
  clearInput(): this;
  
  // UI control
  showDropdown(preventInputFocus?: boolean): this;
  hideDropdown(preventInputBlur?: boolean): this;
}

Core Class

Configuration Options

Comprehensive configuration system covering behavior, styling, validation, and functionality customization.

interface Options {
  // Core behavior
  silent: boolean;
  items: string[] | InputChoice[];
  choices: InputChoice[] | InputGroup[];
  maxItemCount: number;
  closeDropdownOnSelect: boolean | 'auto';
  
  // Search and filtering
  searchEnabled: boolean;
  searchChoices: boolean;
  searchFloor: number;
  searchResultLimit: number;
  
  // Styling and templates
  classNames: ClassNames;
  position: PositionOptionsType;
}

Configuration

Events System

Event system providing lifecycle hooks and user interaction callbacks for integration with external systems.

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

Events

Templates System

Customizable HTML template functions for complete control over rendered UI components and styling.

interface Templates {
  containerOuter: (classNames, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) => HTMLElement;
  containerInner: (classNames) => HTMLElement;
  itemList: (classNames, isSelectOneElement) => HTMLElement;
  placeholder: (classNames, value) => HTMLElement;
  item: (classNames, data, removeItemButton, removeItemButtonAlignLeft, removeItemText) => HTMLElement;
  choiceList: (classNames, isSelectOneElement) => HTMLElement;
  choiceGroup: (classNames, data) => HTMLElement;
  choice: (classNames, data, itemSelectText, groupName) => HTMLElement;
  input: (classNames, placeholderValue, searchEnabled) => HTMLElement;
  dropdown: (classNames) => HTMLElement;
  notice: (classNames, label, type) => HTMLElement;
}

Templates

Types

// Core data structures
interface InputChoice {
  id?: number;
  highlighted?: boolean;
  labelClass?: string | Array<string>;
  labelDescription?: string;
  customProperties?: CustomProperties;
  disabled?: boolean;
  active?: boolean;
  label: StringUntrusted | string;
  placeholder?: boolean;
  selected?: boolean;
  value: any;
}

interface InputGroup {
  id?: number;
  active?: boolean;
  disabled?: boolean;
  label?: StringUntrusted | string;
  value: string;
  choices: InputChoice[];
}

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

type EventChoiceValueType<B extends boolean> = B extends true ? string : EventChoice;

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

// Configuration types
type PositionOptionsType = 'auto' | 'top' | 'bottom';
type PassedElementType = 'text' | 'select-one' | 'select-multiple';

// String safety types
interface StringUntrusted {
  _type: 'StringUntrusted';
  value: string;
}

interface StringPreEscaped {
  _type: 'StringPreEscaped';  
  value: string;
}

// Additional utility types
type CustomProperties = Record<string, any>;
type NoticeType = 'noChoices' | 'noResults' | 'addChoice';
type FilterFunction = (value: string) => boolean;
type NoticeStringFunction = (value: string, valueRaw?: string) => string;
type NoticeLimitFunction = (maxItemCount: number) => string;
type StringFunction = () => string;
type ValueCompareFunction = (choice1: string, choice2: string) => boolean;
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/choices.js@11.0.x
Publish Source
CLI
Badge
tessl/npm-choices-js badge