An Angular select2 component.
npm install ng-select2-component  
This Angular CLI module it's a fork of select2-component without Vue & React. For Vue or React, please use the original component.
```
npm i ng-select2-component --save
- peerDependencies:
- angular ^18.1.0 to ^21.0.0angular/cdk
- ^18.1.0 to ^21.0.0
- dependencies (include):
- ngx-infinite-scroll ^19.0.0 to ^21.0.0
| Version | For Angular | Notes |
| --------- | ---------------- | ----------------- |
| 17.2.x | 18.1, 19, 20, 21 | Ivy / Stand-alone |17.1.0
| | 19 | Ivy / Stand-alone |16.0.0
| | 19 | Ivy / Module |15.4.0
| | 18 | Ivy |14.0.1
| | 17 | Ivy |13.0.12
| | 16.1 | Ivy |12.1.0
| | 16 | Ivy |11.1.0
| | 15 | Ivy |10.0.0
| | 14 | Ivy |9.0.0
| | 13 | Ivy |8.1.0
| | 10, 11 and 12 | View Engine |7.3.1
| | 7, 8 and 9 | View Engine |
See a demo and code generator.
- select one
- options or groups (list or grid)
- scroll
- local search
- select by keyboard
- disabled option
- disabled component
- hide search box
- placeholder
- multiple selection
- add items not found in multiple
- material style
- form binding
- templating
- drag'n drop
- WAI (accessibility)
- etc.
`ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Select2, Select2Hint, Select2Label } from 'ng-select2-component';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.scss'],
imports: [FormsModule, ReactiveFormsModule, Select2, Select2Hint, Select2Label],
})
class MyComponent {}
`
`html`
| name | type | default | description | required |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| data (required) | Select2Data | | the data of the select2 | |value
| | Select2Value | | initial value | |minCharForSearch
| | number | 0 | start the search when the number of characters is reached (0 = unlimited) | |minCountForSearch
| | number | 6 | hide search box if options.length < minCountForSearch | |displaySearchStatus
| | 'default''hidden''always' | 'default' | display the search box (default : is based on minCountForSearch) | |placeholder
| | string | | the placeholder string if nothing selected | |noResultMessage
| | string | | the message string if no results when using the search field | |customSearchEnabled
| | boolean | false | will trigger search event, and disable inside filter | |multiple
| | boolean | false | select multiple options | |multipleDrag
| | boolean | false | drag'n drop list of items in selection | with multiple |resettable
| | boolean | false | add a button to reset value | |resetSelectedValue
| | any | undefined | selected option when × is clicked | |autoCreate
| | boolean | false | gives the possibility to add elements not present in the list. | |limitSelection
| | number | 0 | to limit multiple selection (0 = unlimited) | |hideSelectedItems
| | boolean | false | remove selected values | with multiple |resultMaxHeight
| | string | '200px' | change the height size of results | |maxResults
| | number | 0 | maximum results limit (0 = unlimited) | |maxResultsMessage
| | string | 'Too much result…' | message when maximum result | |grid
| | number or string | | option by line in grid layout (empty or 0 = no grid layout)number: item by linestring: minimal item width | |listPosition
| | 'below''above''auto' ¹ | 'below' | the position for the dropdown list | ¹ 'auto': only with overlay |infiniteScroll
| | boolean | false | active infiniteScroll on dropdown list | with ngx-infinite-scroll |infiniteScrollDistance
| | number | 1.5 | infiniteScroll distance | with ngx-infinite-scroll |infiniteScrollThrottle
| | number | 150 | infiniteScroll throttle | |overlay
| | boolean | false | active an overlay mode for dropdown list (with angular cdk). (See Overlay) | |styleMode
| | 'default''material''noStyle''borderless' | 'default' | change style for material style or remove border and background color | |templates
| | Select2TemplatetemplateSelection
(see ”possible object” in Templating) | | use templates for formatting content (see Templating) | |
| | TemplateRef | | use templates for formatting content (see Templating) | |noLabelTemplate
| | boolean | false | do not use the template in the selection, stay in text mode | |selectionOverride
| | Select2SelectionOverride | | Replace selection by a textstring: %size% = total selected optionsfunction: juste show the string | |selectionNoWrap
| | boolean | false | Force selection on one line | |showSelectAll
| | boolean | false | Add an option to select all options | with multiple |selectAllText
| | string | 'Select all' | Text when all options as not selected | with multiple |removeAllText
| | string | 'Remove all' | Text when all options as selected | with multiple |editPattern
| | (str: string) => string | | use it for change the pattern of the filter search | |nativeKeyboard
| | boolean | false | Use the keyboard navigation like native HTML select component | not with multiple |ngModel
| idrequireddisabledreadonlytabIndex | | | just like a select control | |(update)
| | (event: Select2UpdateEvent) => void | | triggered when user select an option | |(open)
| | (event: Select2) => void | | triggered when user open the options | |(close)
| | (event: Select2) => void | | triggered when user close the options | |(focus)
| | (event: Select2) => void | | triggered when user enters the component | |(blur)
| | (event: Select2) => void | | triggered when user leaves the component | |(search)
| | (event: Select2SearchEvent) => void | | triggered when search text changed | with customSearchEnabled |(scroll)
| | (event: Select2ScrollEvent) => void | | triggered when infiniteScroll is on up or down position | with ngx-infinite-scroll |(removeOption)
| | (event: Select2RemoveEvent) => void | | triggered when an option is removed from the list of selected options options list | with multiple |(autoCreateItem)
| | (event: Select2AutoCreateEvent) => void | | triggered when a new item has been added | with autoCreate |
`ts
export interface Select2Group {
/* label of group /
label: string;
/* options list /
options: Select2Option[];
/* add classes /
classes?: string;
/* template id dropdown & selection if no templateSelectionId /
templateId?: string;
/* template data /
data?: any;
}
export interface Select2Option {
/* value /
value: Select2Value;
/* label of option /
label: string;
/* no selectable is disabled /
disabled?: boolean;
/* for identification /
id?: string;
/* add classes /
classes?: string;
/* template id dropdown & selection if no templateSelectionId /
templateId?: string;
/* template id for selection /
templateSelectionId?: string;
/* template data /
data?: any;
/* hide this option /
hide?: boolean;
}
export type Select2Value = string | number | boolean | object | null | undefined;
export type Select2UpdateValue = Select2Value | Select2Value[] | undefined | null;
export type Select2Data = (Select2Group | Select2Option)[];
export interface Select2UpdateEvent {
/* component /
readonly component: Select2;
/* current selected value /
readonly value: U | null;
/* selected option /
readonly options: Select2Option[] | null;
}
export interface Select2AutoCreateEvent {
/* component /
readonly component: Select2;
/* current selected value /
readonly value: U;
/* selected option /
readonly options: Select2Option[] | null;
}
export interface Select2SearchEvent {
/* component /
readonly component: Select2;
/* current selected value /
readonly value: U | null;
/* search text /
readonly search: string;
/* current data source /
readonly data: Select2Data;
/* method to call to update the data /
readonly filteredData: (data: Select2Data) => void;
}
export interface Select2RemoveEvent {
/* component /
readonly component: Select2;
/* current selected value /
readonly value: U;
/* remove /
readonly removedOption: Select2Option;
}
export interface Select2ScrollEvent {
/* component /
readonly component: Select2;
/* scroll way /
readonly way: 'up' | 'down';
/* search text /
readonly search: string;
/* current data /
readonly data: Select2Data;
}
export type Select2SelectionOverride = string | ((params: { size: number; options: Select2Option[] | null }) => string);
export type Select2Template = TemplateRef
`
#### Unique template
`html`
`ts`
const data: Select2Data = [
{
value: 'heliotrope',
label: 'Heliotrope',
data: { color: 'white', name: 'Heliotrope' },
},
{
value: 'hibiscus',
label: 'Hibiscus',
data: { color: 'red', name: 'Hibiscus' },
},
];
#### Template group & option
`html`
No difference in data structure.
The template is defined by its type, option or group, automatically.
#### Template by templateId
`html`
`ts`
const data: Select2Data = [
{
value: 'heliotrope',
label: 'Heliotrope',
data: { color: 'white', name: 'Heliotrope' },
templateId: 'template1',
},
{
value: 'hibiscus',
label: 'Hibiscus',
data: { color: 'red', name: 'Hibiscus' },
templateId: 'template2',
},
];
#### Template for change the selection
`html`
#### Possible object
- TemplateRef{template: TemplateRef}
- {option?: TemplateRef, group?: TemplateRef}
- {templateId1: TemplateRef, ...}
-
In addition to the rendering templates of options and groups, in addition to going through the templateSelection attribute, it is possible to define that of the selection :
- {templateSelection: TemplateRef}{optionSelection: TemplateRef}
-
#### Priority order
For group or option:
- 'id' (from item data templateId)'group'
- or 'option''template'
- TemplateRef
- (from html attribute templates)
- Default render
For the selection:
- 'id' (from item data templateSelectionId)'optionSelection'
- 'templateSelection'
- TemplateRef
- (from html attribute templateSelection)'id'
- (from item data templateId)'option'
- 'template'
- TemplateRef
- (from html attribute templates)
- Default render
If the overlay mode is used / activated, add to the project root in CSS (with ViewEncapsulation.None)
`css`
@import '~@angular/cdk/overlay-prebuilt.css';
It's possible to change different colors (and more) with CSS variables without having to modify them with ::ng-deep or other CSS rules :
`css
:root {
/ size /
--select2-single-height: 28px;
--select2-multiple-height: 28px;
/ label /
--select2-label-text-color: #000;
--select2-required-color: red;
/ selection /
--select2-selection-border-radius: 4px;
--select2-selection-background: #fff;
--select2-selection-disabled-background: #eee;
--select2-selection-border-color: #aaa;
--select2-selection-focus-border-color: #000;
--select2-selection-text-color: #111;
--select2-selection-line-height: 28px;
--select2-selection-padding: 0 0 0 8px;
/ selection (multiple) /
--select2-selection-multiple-gap: 2px 5px;
--select2-selection-multiple-padding: 2px 5px;
/ selection: choice item (multiple) /
--select2-selection-choice-background: #e4e4e4;
--select2-selection-choice-text-color: #000;
--select2-selection-choice-border-color: #aaa;
--select2-selection-choice-close-color: #999;
--select2-selection-choice-hover-close-color: #333;
/ placeholder /
--select2-placeholder-color: #999;
--select2-placeholder-overflow: ellipsis;
/ no result message /
--select2-no-result-color: #888;
--select2-no-result-font-style: italic;
/ no result message /
--select2-too-much-result-color: #888;
--select2-too-much-result-style: italic;
/ reset /
--select2-reset-color: #999;
/ arrow /
--select2-arrow-color: #888;
/ dropdown panel /
--select2-dropdown-background: #fff;
--select2-dropdown-border-color: #aaa;
--select2-dropdown-above-border-bottom: none;
--select2-dropdown-above-border-bottom-left-radius: 0;
--select2-dropdown-above-border-bottom-right-radius: 0;
--select2-dropdown-below-border-top: none;
--select2-dropdown-below-border-top-left-radius: 0;
--select2-dropdown-below-border-top-right-radius: 0;
/ overlay /
--select2-overlay-backdrop: transparent;
/ search field /
--select2-search-border-color: #aaa;
--select2-search-background: #fff;
--select2-search-border-radius: 0px;
/ dropdown option /
--select2-option-text-color: #000;
--select2-option-disabled-text-color: #999;
--select2-option-disabled-background: transparent;
--select2-option-selected-text-color: #000;
--select2-option-selected-background: #ddd;
--select2-option-highlighted-text-color: #fff;
--select2-option-highlighted-background: #5897fb;
--select2-option-group-text-color: gray;
--select2-option-group-background: transparent;
--select2-option-padding: 6px;
/ hint /
--select2-hint-text-color: #888;
/ for Material ------------------------------------------/
--select2-material-underline: #ddd;
--select2-material-underline-active: #5a419e;
--select2-material-underline-disabled: linear-gradient(
to right,
rgba(0, 0, 0, 0.26) 0,
rgba(0, 0, 0, 0.26) 33%,
transparent 0
);
--select2-material-underline-invalid: red;
--select2-material-placeholder-color: rgba(0, 0, 0, 0.38);
--select2-material-selection-background: #ddd;
--select2-material-option-selected-background: rgba(0, 0, 0, 0.04);
--select2-material-option-highlighted-text-color: #000;
--select2-material-option-selected-text-color: #ff5722;
}
`
``
npm run build:lib
npm run publish:lib
```
npm run build:demo
Like Angular, this module is released under the permissive MIT license. Your contributions are always welcome.