Select2: Searchable Select Box Plugin for jQuery

File Size: 2.55 MB
Views Total: 31192
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Select2: Searchable Select Box Plugin for jQuery

Select2 is a jQuery plugin that replaces native <select> elements with searchable single- and multi-select dropdowns.

You can use it for form fields that need local search, tags, remote AJAX data, custom result templates, or paginated results.

The original <select> remains the form control, so selections follow normal form submission and jQuery change events.

Features:

  • Turns native single and multiple select fields into searchable controls.
  • Loads remote result pages through the ajax option.
  • Creates tags from typed text and token separators.
  • Renders custom result and selection templates.
  • Supports clear buttons, placeholders, result sorting, and selection limits.
  • Supports message translations and right-to-left text direction.
  • Preserves native <option> and one-level <optgroup> data for normal form submission.

Use Cases:

  • Remote product search keeps a catalog editor from loading thousands of options at page load. The endpoint returns matches for a SKU, product name, or supplier.
  • A CRM lead-assignment field lets a sales manager find contacts by name or company and store several account owners.
  • Editorial taxonomy screens accept an existing category or turn newly typed text into a tag for a post, page, or media item.
  • Bootstrap modal forms use dropdownParent to keep the result list inside the dialog and avoid focus conflicts.

How To Use It:

Install And Include The Files

Install Select2 with npm:

npm install select2

Or directly oad the Select2 plugin's files in your document:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2/dist/css/select2.min.css">

<script src="/path/to/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2/dist/js/select2.min.js"></script>

Load an i18n file after Select2 if needed:

<script src="/path/to/i18n/es.js"></script>

Add A Native Select Field

A blank first option gives a single-select control a placeholder and clear button.

<label for="project-status">Project status</label>
<select id="project-status" name="project_status">
  <option value=""></option>
  <option value="planned">Planned</option>
  <option value="active">Active</option>
  <option value="review">Ready for review</option>
  <option value="complete">Complete</option>
</select>

Initialize Select2

$(function () {
  $('#project-status').select2({
    placeholder: 'Select a project status',
    allowClear: true,
    width: '100%'
  });
});

The browser keeps the native field in the form. Read or change its value with normal jQuery methods, then trigger change when your code updates the field.

var $status = $('#project-status');

$status.val('active').trigger('change');
console.log($status.val());

Use Data Attributes For Simple Settings

Data attributes keep simple configuration next to the form field. Write camelCase options with hyphens, such as data-allow-clear. Nested settings use two hyphens between levels.

<select id="assignee"
        data-placeholder="Assign a team member"
        data-allow-clear="true"
        data-minimum-input-length="2">
  <option value=""></option>
  <option value="mira">Mira Chen</option>
  <option value="david">David Hall</option>
</select>
$('#assignee').select2({
  width: '100%'
});

Use double hyphens for nested AJAX settings. Nested data-* settings do not work in jQuery 1.x.

<select data-ajax--url="/api/team-members"
        data-ajax--cache="true"></select>

Available Plugin Options:

Data, Search, And Tags

  • ajax: Configures a remote data source. Type: Object. Default: null.
  • data: Renders options from an in-memory result array. Each result should use id and text. Type: Array of objects. Default: null.
  • dataAdapter: Replaces the built-in data adapter. Type: Adapter constructor. Default: SelectAdapter.
  • matcher: Changes the local search matching logic. Type: Function that receives search parameters and a data object. Default: Built-in matcher.
  • sorter: Sorts matched local results before Select2 displays them. Type: Function. Default: Built-in order.
  • minimumInputLength: Requires a minimum number of characters before a search starts. Type: Integer. Default: 0.
  • maximumInputLength: Limits the number of characters accepted in the search field. Type: Integer. Default: 0.
  • minimumResultsForSearch: Hides the search box until the result count reaches this value. Type: Integer. Default: 0.
  • tags: Accepts free-text values or seeds the tag list with result objects. Type: Boolean or Array of objects. Default: false.
  • tokenizer: Replaces the default tag tokenization routine. Type: Function. Default: Built-in tokenizer.
  • tokenSeparators: Splits typed text into tags when a listed character appears. Type: Array. Default: null.
  • createTag: Returns the object for a new tag or null when the typed text should not create one. Type: Function. Default: Built-in tag creator.
  • insertTag: Controls where a newly created tag appears in the result list. Type: Function. Default: Adds the tag after existing results.

Selection Behavior

  • allowClear: Adds a clear control for a selection that has a placeholder. Type: Boolean. Default: false.
  • closeOnSelect: Closes the dropdown after each selection. Type: Boolean. Default: true.
  • disabled: Disables the Select2 field. Type: Boolean. Default: false.
  • maximumSelectionLength: Caps the number of values in a multiple-select control. Values below 1 leave selection count unlimited. Type: Integer. Default: 0.
  • multiple: Activates pill-style multiple selection. The multiple HTML attribute maps to this option. Type: Boolean. Default: false.
  • placeholder: Sets the placeholder message. Type: String or Object. Default: null.
  • selectOnClose: Selects the highlighted item when the dropdown closes. Type: Boolean. Default: false.
  • scrollAfterSelect: Keeps the result list at its current position after a selection in multi-select controls that stay open. Type: Boolean. Default: false.

Dropdown, Templates, And Layout

  • dir: Sets text direction on Select2 containers. Type: String. Default: ltr.
  • dropdownAdapter: Replaces the built-in dropdown adapter. Type: Adapter constructor. Default: DropdownAdapter.
  • dropdownAutoWidth: Recalculates dropdown width when the menu opens. Type: Boolean. Default: false.
  • dropdownCssClass: Adds classes to the dropdown container. Use :all: to copy classes from the original <select>. Type: String. Default: Empty string.
  • dropdownParent: Sets the element that receives the dropdown. Use this for Bootstrap modals and scoped layouts. Type: jQuery selector or DOM node. Default: $(document.body).
  • escapeMarkup: Escapes strings returned from result and selection templates. Keep the default unless your template output handles untrusted content safely. Type: Function. Default: Utils.escapeMarkup.
  • resultsAdapter: Replaces the built-in results adapter. Type: Adapter constructor. Default: ResultsAdapter.
  • selectionAdapter: Replaces the single- or multiple-selection adapter. Type: Adapter constructor. Default: Depends on multiple.
  • selectionCssClass: Adds classes to the selection container. Use :all: to copy classes from the original <select>. Type: String. Default: Empty string.
  • templateResult: Controls each dropdown result's rendered output. Type: Function. Default: Built-in text template.
  • templateSelection: Controls the rendered selected value. Type: Function. Default: Built-in text template.
  • theme: Sets the Select2 theme name. Type: String. Default: default.
  • width: Defines the control width strategy. Type: String. Default: resolve.

Language And Diagnostic Settings

  • amdLanguageBase: Sets the language-module root for AMD or CommonJS loader configurations. Type: String. Default: ./i18n/. Note: The full current build does not dynamically load language modules.
  • debug: Sends diagnostic messages to the browser console. Type: Boolean. Default: false.
  • language: Sets message translations through a language key or translation object. Type: String or Object. Default: English translation.

AJAX Settings

  • ajax.url: Sets a fixed URL or returns a URL from the current search parameters. Type: String or Function. Default: Not specified.
  • ajax.data: Maps Select2 search parameters to request data. Type: Function. Default: Select2 passes term, q, _type, and paginated page values.
  • ajax.processResults: Converts a server response into a results array and optional pagination.more value. Type: Function. Default: Not specified.
  • ajax.delay: Waits after a keystroke before the request begins. Type: Integer in milliseconds. Default: 0.
  • ajax.transport: Replaces the default $.ajax request transport. Type: Function. Default: jQuery AJAX.
  • ajax jQuery settings: Passes standard $.ajax settings such as dataType, cache, HTTP method, and headers to the request. Type: Object properties. Default: Depends on jQuery.

Methods And Programmatic Control:

Select2 Methods

  • $(selector).select2(): Initializes Select2 on a native <select> element. Parameters: Optional configuration object. Returns: The jQuery collection.
  • $(selector).select2('open'): Opens the dropdown. Parameters: None. Returns: The jQuery collection.
  • $(selector).select2('close'): Closes the dropdown. Parameters: None. Returns: The jQuery collection.
  • $(selector).select2('destroy'): Removes the generated Select2 interface and restores the native field. Unbind application events separately with .off(). Parameters: None. Returns: The jQuery collection.
  • $(selector).select2('data'): Returns an array of objects for the current selection. The objects keep data supplied by the result source. Parameters: None. Returns: Array.

Check Initialization And Update Values

  • $(selector).hasClass('select2-hidden-accessible'): Checks whether Select2 has initialized the field. Parameters: None. Returns: Boolean.
  • $(selector).val(value).trigger('change'): Selects an existing option and updates Select2. Pass an array for a multi-select field. Parameters: String, Number, Array, or null. Returns: The jQuery collection.
  • new Option(text, value, defaultSelected, selected): Creates an option before appending it to a Select2 field. This is the safe preselection path for an AJAX result that is not yet in the DOM. Parameters: Option values. Returns: HTML option element.
  • $(selector).val(null).trigger('change'): Clears the current selection. Parameters: None. Returns: The jQuery collection.

Global Defaults

  • $.fn.select2.defaults.set(key, value): Sets an option default for Select2 instances created after the call. Parameters: Option name and value. Returns: Not specified.
  • $.fn.select2.defaults.reset(): Restores Select2 defaults. Parameters: None. Returns: Not specified.
$.fn.select2.defaults.set('theme', 'classic');
$.fn.select2.defaults.set('ajax--delay', 250);

Events:

Select2 relays public events through jQuery on the original <select> field.

  • change: Runs after a selection changes. Arguments: jQuery event. Trigger: An option is selected or removed.
  • change.select2: Runs only Select2-scoped change handlers. Arguments: jQuery event. Trigger: A programmatic Select2 update.
  • select2:opening: Runs before the dropdown opens. Call event.preventDefault() to stop it. Arguments: jQuery event. Trigger: Open request.
  • select2:open: Runs after the dropdown opens. Arguments: jQuery event. Trigger: Opened dropdown.
  • select2:closing: Runs before the dropdown closes. Call event.preventDefault() to stop it. Arguments: jQuery event. Trigger: Close request.
  • select2:close: Runs after the dropdown closes. Arguments: jQuery event. Trigger: Closed dropdown.
  • select2:selecting: Runs before a result is selected. Call event.preventDefault() to stop it. Arguments: jQuery event with pending data. Trigger: Selection request.
  • select2:select: Runs after a result is selected. Read the result from event.params.data. Arguments: jQuery event. Trigger: Completed selection.
  • select2:unselecting: Runs before a selection is removed. Call event.preventDefault() to stop it. Arguments: jQuery event with pending data. Trigger: Removal request.
  • select2:unselect: Runs after a selection is removed. Arguments: jQuery event. Trigger: Completed removal.
  • select2:clearing: Runs before all selections clear. Call event.preventDefault() to stop it. Arguments: jQuery event. Trigger: Clear request.
  • select2:clear: Runs after all selections clear. Arguments: jQuery event. Trigger: Completed clear action.
$('#project-status').on('select2:select', function (event) {
  var selectedStatus = event.params.data;

  console.log(selectedStatus.id, selectedStatus.text);
});

$('#project-status').val('active').trigger('change.select2');

Use change.select2 when application code must refresh Select2 without notifying unrelated change handlers. Trigger a Select2 event manually only when an integration needs to send explicit event data.

$('#project-status').trigger({
  type: 'select2:select',
  params: {
    data: {
      id: 'active',
      text: 'Active'
    }
  }
});

More Examples:

Search Customers Through AJAX

Remote endpoints should filter results on the server. Return a results array with id and text properties. Add pagination.more when the endpoint supports another page.

<label for="customer-search">Customer</label>
<select id="customer-search" name="customer_id"></select>
$('#customer-search').select2({
  placeholder: 'Search customers',
  minimumInputLength: 2,
  ajax: {
    url: '/api/customers',
    dataType: 'json',
    delay: 250,
    data: function (params) {
      return {
        query: params.term,
        page: params.page || 1
      };
    },
    processResults: function (data, params) {
      params.page = params.page || 1;

      return {
        results: data.customers.map(function (customer) {
          return {
            id: customer.id,
            text: customer.name
          };
        }),
        pagination: {
          more: (params.page * data.per_page) < data.total
        }
      };
    }
  }
});

Create Tags From Comma-Separated Labels

<label for="content-labels">Labels</label>
<select id="content-labels" name="labels[]" multiple></select>
$('#content-labels').select2({
  tags: true,
  tokenSeparators: [',', ';'],
  placeholder: 'Add labels',
  createTag: function (params) {
    var term = $.trim(params.term);

    if (!term) {
      return null;
    }

    return {
      id: term,
      text: term,
      newTag: true
    };
  }
});

Render Avatar Results

Return a jQuery object from a template function when a result needs markup. Keep untrusted text in text nodes instead of concatenating it into HTML.

<label for="reviewer">Reviewer</label>
<select id="reviewer" name="reviewer">
  <option value=""></option>
  <option value="mira" data-avatar="/images/team/mira.jpg">Mira Chen</option>
  <option value="david" data-avatar="/images/team/david.jpg">David Hall</option>
</select>
function renderReviewer(option) {
  if (!option.id) {
    return option.text;
  }

  var avatar = $(option.element).data('avatar');

  if (!avatar) {
    return option.text;
  }

  return $('', { class: 'select2-reviewer' })     .append($('', { src: avatar, alt: '' }))     .append(document.createTextNode(' ' + option.text)); }  $('#reviewer').select2({   placeholder: 'Choose a reviewer',   allowClear: true,   templateResult: renderReviewer,   templateSelection: renderReviewer,   width: '100%' });

Use Select2 Inside A Bootstrap Modal

Set dropdownParent to the modal element. Select2 then places the dropdown inside the dialog instead of attaching it to the page body.

$('#modal-assignee').select2({
  dropdownParent: $('#edit-task-modal'),
  placeholder: 'Assign a team member',
  width: '100%'
});

Legacy Select2 3.4.8 Template Compatibility

Older projects that still run Select2 3.4.8 use formatter callbacks that do not apply to current Select2 builds. Keep this reference with a legacy page. Use templateResult and templateSelection when the project runs Select2 4.x.

  • formatResult(result, container, query, escapeMarkup): Renders a result row in Select2 3.4.8. Call escapeMarkup for text inserted into returned HTML. Current replacement: templateResult.
  • formatSelection(data, container, escapeMarkup): Renders the selected value in Select2 3.4.8. Call escapeMarkup for text inserted into returned HTML. Current replacement: templateSelection.
  • escapeMarkup(markup): Escapes text before Select2 inserts it as HTML. Current replacement: Keep the default escapeMarkup function unless template output handles untrusted values safely.
function formatLegacyMember(result, container, query, escapeMarkup) {
  if (!result.id) {
    return escapeMarkup(result.text);
  }

  return '<span class="member-option">' +
    escapeMarkup(result.text) +
    '</span>';
}

$('#legacy-member').select2({
  formatResult: formatLegacyMember,
  formatSelection: function (data, container, escapeMarkup) {
    return escapeMarkup(data.text);
  }
});

Themes:

Alternatives and Related Resources:

FAQs:

Q: Does Select2 require jQuery?
A: Yes. Select2 registers as the jQuery .select2() function. Load jQuery before the Select2 script.

Q: Why does the dropdown lack Select2 styles?
A: The Select2 CSS file must load before the control initializes. Confirm that the stylesheet URL returns the current select2.min.css file and that page CSS does not override its width or visibility rules.

Q: Why does a Select2 field fail inside a Bootstrap modal?
A: Set dropdownParent to the modal element. Bootstrap focus handling can block a dropdown that Select2 attaches to the document body.

Q: What response format does an AJAX endpoint need?
A: Return a results array of objects that use id and text. Paginated endpoints also return pagination: { more: true } when another result page exists.

Q: How do I destroy and reinitialize a Select2 field?
A: Call $select.select2('destroy'), remove any application handlers with $select.off(), then initialize the field again. Select2 removes only the handlers it created itself.

Q: How do formatResult and formatSelection map to current Select2?
A: Those callbacks belong to Select2 3.4.8. Replace them with templateResult and templateSelection in current Select2 code. Keep escapeMarkup in place when templates return HTML that contains data from a server or user input.

Changelog:

v4.1.0 (2026-05-27)

  • The minimum jQuery version supported is the latest version in the 1.x, 2.x, 3.x, and 4.x series
  • Removed support for legacy Internet Explorer (versions older than IE 11)
  • Removed modules deprecated in 4.0.0
  • Removed undocumented CSS-related options
  • The containerCssClass option has been renamed to selectionCssClass
  • Significant changes to the HTML/CSS for the selection area impacting custom themes
  • New CSS classes for the dropdown results to better target highlighted / selected results 
  • The search box in the selection area for multiple selects has been changed from an <input /> to a <textarea> to support pasting multiple lines (#5806)
  • Change tab key to select the currently highlighted option instead of just closing
  • Tags will be highlighted first in the results even if other options have been selected
  • dropdownCssClass and selectionCssClass are now available in all builds of Select2
  • Calls to get the currently selected options are now considerably faster on large datasets
  • Selected results in the dropdown should now be properly announced to screen readers
  • Significant improvements were made to make the selection area accessible
  • Allow pasting multiple lines into the search field for tokenization
  • Add support for jQuery 4.0.0
  • Add originalEvent to close trigger arguments
  • Bugfixes
  • Add new languages

v4.0.13 (2020-01-28)

  • Trigger input event before change events
  • Feed back the keypress code that was responsible for the 'close' event
  • Only trigger selection:update once on DOM change events
  • Prevent opening of disabled elements

v4.0.12 (2019-11-06)

  • Fix incorrect offset when using the Shadow DOM and styling the <html> element
  • Fix incorrect provider for the automated NPM deployment

v4.0.11 (2019-10-14)

  • Fixes jQuery migrate error when getting offset when dropdownParent not in document

v4.0.10 (2019-08-28)

  • Support passing in a selector for dropdownParent option
  • Fix bug where dropdowns pointing upwards were incorrectly positioned

v4.0.9 (2019-08-28)

  • Mirror disabled state through aria-disabled on selection
  • Select2 now clears the internal ID when it is destroyed
  • Set the main ARIA 1.1 roles and properties for comboboxes
  • The language option now has a clearly defined fallback chain
  • Do not propagate click when search box is not empty
  • Fix maximumSelectionLength being ignored by closeOnSelect
  • Fix generated options not receiving result IDs 
  • Remove selection title attribute if text is empty 
  • Reposition dropdown whenever items are selected 
  • Fix dropdown positioning when displayed above with messages
  • Fix search box expanding width of container
  • allowClear no longer shifts selections to a new line
  • Fix error in German translations

v4.0.8 (2019-07-21)

Fix compatibility with jQuery 3.4.1

Results respect disabled state of <option>

Add computedstyle option for calculating the width

Fix tag creation being broken in 4.0.7

  • Fix infinite scroll when the scrollbar is not visible
  • Revert change to focusing behaviour
  • Fix wording in French translations
  • Update grunt-contrib-qunit to latest version
  • Removed unused .select2-selection__placeholder CSS definitions for multiple selects (#5508)
  • Remove deprecated jQuery shorthand

v4.0.7 (2019-05-08)

  • Do not close on select if Ctrl or Meta (Cmd) keys being held
  • Fixed issue where single select boxes would automatically reopen when they were closed
  • Move almond and jquery-mousewheel to devDependencies

v4.0.6 (2019-04-28)

  • Add style property to package.json
  • Implement clear and clearing events
  • Add scrollAfterSelect option
  • Add missing diacritics
  • Fix up arrow error when there are no options in dropdown
  • Add ; before beginning of factory wrapper
  • Fix IE11 issue with select losing focus after selecting an item
  • Clear tooltip from select2-selection__rendered when selection is cleared
  • Fix keyboard not closing when closing dropdown on iOS 10
  • User-defined types not normalized properly when passed in as data
  • Perform deep merge for Defaults.set()
  • Fix "the results could not be loaded" displaying during AJAX request
  • Cache objects in Utils.__cache instead of using $.data
  • Removing the double event binding registration of selection:update
  • Improve .select2-hidden-accessible
  • Add role and aria-readonly attributes to single selection dropdown value

2018-09-06

  • Add scrollAfterSelect as a configurable option for multiselect dropdowns to allow toggling of highlightFirstItem() behaviour
  • Add scrollOnSelect as a configurable option
  • Default scrollOnSelect to true to avoid modifying existing behaviour
  • Added tests and default option for scrollAfterSelect

v4.0.5 (2017-10-25)

  • Replace autocapitalize=off with autocapitalize=none
  • More translations.

v4.0.4 (2017-09-25)

  • Make tag matching case insensitive 
  • Support selecting options with blank or 0 option values 
  • Fix issue with entire form losing focus when tabbing away from a Select2 control
  • Fix UMD support for CommonJS 
  • Add more languages

v4.0.2 (2016-03-09)

  • update.

v3.5.2 (2015-01-08)

  • update.

v3.5.1 (2014-07-23)

  • update.

v3.5.0 (2014-06-17)

  • update.

v3.4.8 (2014-05-02)

  • update.

v3.4.7 (2014-05-01)

  • update.

v3.4.6 (2014-03-23)

  • update.

v3.4.5 (2013-12-08)

  • Fix for drop-auto-width collision detection and css border top.
  • better handling for ipads.

v3.4.4 (2013-10-25)

  • updated to the latest version

v3.4.3 (2013-9-17)

  • updated to the latest version

v3.4.2 (2013-8-13)

  • updated to the latest version

v3.4.1 (2013-6-28)

  • fix js error that happens when enter is pressed and there is no highlighted option.

v3.4.0 (2013-5-15)

  • Fixed MultiSelect JavaScript error - no method 'showSearch'

v3.3.1 (2013-3-26)

  • Revert "Added ajax.transport support to default options"

v3.3.1 (2013-2-21)

  • Opera implements box-shadow without a vendor prefix, so -o-box-shadow is invalid.
  • Added German translation
  • Added spanish translation
  • Added Hungarian translation

v3.3.0 (2013-2-6)

  • fix more hierarchical selection bugs.
  • pass escape markup into formatResult 

This awesome jQuery plugin is developed by select2. For more Advanced Usages, please check the demo page or visit the official website.