1. Plugins
  2. Advanced Select

Plugins

Tailwind CSS Advanced Select

Advanced select solutions for massive datasets.

Advanced Select

Installation

To get started, install Advanced Select plugin via npm, else you can skip this step if you are already using Preline UI as a package.

                      
                        npm i @preline/select
                      
                    

Example

Here is a basic example of a select with advanced features.

Basic usage

Prefer to create your own style? Here is a completely unstylized example.

                      
                        <select data-hs-select='{
                            "placeholder": "Select option...",
                            "toggleTag": "<button type=\"button\"></button>",
                            "toggleClasses": "",
                            "dropdownClasses": "",
                            "optionClasses": "hs-selected:"
                          }'>
                          <option>Select option</option>
                          <option>Name</option>
                          <option>Email address</option>
                          <option>Description</option>
                          <option>User ID</option>
                        </select>
                      
                    

Data Options

Name Description Options Default value
data-hs-select Activate a Custom Select by specifying on an element. Should be added to the select.
:isOpened Opens the select if the value is true. boolean false
:placeholder Define a default placeholder when nothing is selected. string Select...
:hasSearch Define a search field inside the dropdown if the value is true. boolean false
:preventSearchFocus Sets autofocus for the search field inside a dropdown list if the value is true. boolean false
:mode Define a select mode. 'default' | 'tags' default
:toggleTag Define a markup for the select toggle. One line HTML markup
:toggleClasses Define CSS classes for the selects' toggle. CSS classes must be separated by a space. string
:toggleSeparators Define separators for the selects' toggle. object
:toggleSeparators:items Define which separator will be used for separate selected items. string ,
:toggleSeparators:betweenItemsAndCounter Define which separator will be used for separate selected items and counter text. string and
:toggleCountText This option is only available for multiple select. Determines what text will be after the counter. It also activates the counting mode. string
:toggleCountTextMinItems This option is only available for multiple select. Defines the minimum number of selected items at which the counting mode will be activated. number 1
:toggleCountTextMode This option is only available for multiple select. controls the display of the contents of the button title. 'countAfterLimit' | 'nItemsAndCount' countAfterLimit
:wrapperClasses Define CSS classes for the selects' wrapper. CSS classes must be separated by a space. string
:tagsItemTemplate This option is only available when tags mode is set up. Define template for the single tag. It could contain:
  • data-icon if target option tag has data-hs-select-option:icon, that this image will be inside the tag with this data attribute.
  • data-title the text from the target option will be inside the tag with this data attribute.
  • data-remove the target tag will be deleted when click on tag with this data attribute.
One line HTML markup
:tagsItemClasses This option is only available when tags mode is set up. Define CSS classes for the single tags. CSS classes must be separated by a space. string
:tagsInputId This option is only available when tags mode is set up. This option is useful if there is a need to associate a label outside the initialized element with the tags input. string
:tagsInputClasses This option is only available when tags mode is set up. Define CSS classes for the input. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space. string
:dropdownTag This option is only available when tags mode is set up. Define a markup for the dropdown. One line HTML markup
:dropdownClasses This option is only available when tags mode is set up. Define CSS classes for the dropdown. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space. string
:dropdownPlacement Specifies the position of the menu when opened. "top" | "top-left" | "top-right" | "bottom" | "bottom-left" | "bottom-right" | "right" | "right-top" | "right-bottom" | "left" | "left-top" | "left-bottom" bottom
:dropdownScope Determines whether the dropdown will be moved outside the parent, for correct display in elements with hidden overflow. Requires the Popper plugin. "window" | "parent" parent
:searchId This option is only available when hasSearch: true. This option is useful if there is a need to associate a label outside the initialized element with the search input. string
:searchLimit This option is only available when hasSearch: true. If this option is enabled, the search will display only the first 'n' matching items. number Infinity
:isSearchDirectMatch This option is only available when hasSearch: true. If the option is disabled, then in the search results you will be able to see non-direct matches by text. For example, if you entered england in the search field, then Eng-land, Eng.land, Eng_land will also be shown. boolean true
:searchClasses This option is only available when :hasSearch attribute is true. Define CSS classes for the search field inside the dropdown. Defines CSS classes for the search field inside a dropdown list. CSS classes must be separated by a space. string block w-[calc(100%-2rem)] text-sm border-gray-200 rounded-md focus:border-blue-500 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 py-2 px-3 my-2 mx-4
:searchPlaceholder This option is only available when :hasSearch attribute is true. Determines placeholder for the search field inside the dropdown. string Search...
:searchNoResultTemplate This option is only available when :hasSearch attribute is true. Define a markup for the "no result" text. string <span></span>
:searchNoResultText This option is only available when :hasSearch attribute is true. Defines the text that will be displayed if no results are found. string No options found...
:searchNoResultClasses This option is only available when :hasSearch attribute is true. Defines CSS classes for the "no results" wrapper. CSS classes must be separated by a space. string px-4 text-sm
:optionTemplate Define template for the single option. It could contain:
  • data-icon if target option tag has data-hs-select-option:icon, that this image will be inside the tag with this data attribute.
  • data-title the text from the target option will be inside the tag with this data attribute.
  • data-description if target option tag has data-hs-select-option:description, that this text will be inside the tag with this data attribute.
One line HTML markup
:optionTag Define a markup for the single option. One line HTML markup
:optionClasses Define CSS classes for the single option. CSS classes must be separated by a space. string
:extraMarkup Define a markup that could be extra added to the wrapper of the select for the decoration reasons. If it contains the --prevent-click class, clicking on this element will not trigger the open function. One line HTML markup || Array of one line HTML markup
:descriptionClasses Define CSS classes for the description inside the single option. CSS classes must be separated by a space. string
:iconClasses Define CSS classes for the icon inside the single option. CSS classes must be separated by a space. string
:isAddTagOnEnter Determines whether a tag will be added when the enter key is pressed. boolean true
:apiUrl Defines the address where the API is located. string | null null
:apiQuery Defines query parameters that are separated by ?. string | null null
:apiOptions Defines options for the fetch function. RequestInit | null null
:apiDataPart If data is in some first level parameter, then it allows you to specify the name of this parameter to extract the data. string | null null
:apiSearchQueryKey Defines the key for the query search parameter. string | null null
:apiFieldsMap Allows you to convert fields from the API to the fields required for the plugin to work.
{
  id: string;
  title: string;
  icon?: string | null;
  description?: string | null;
} | null
null
:apiIconTag Allows to define an img tag that will be used when rendering options and in the trigger button. string | null null

Tailwind Modifiers

Name Description
hs-select-opened:* A modifier that allows you to set Tailwind classes when select has been opened.
hs-select-disabled:* A modifier that allows you to set Tailwind classes when select has "disabled" attribute.

Methods

The HSSelect object is contained within the global window object

Method Description
Public methods
destroy() Destroys select.
open() Open dropdown list.
close() Close dropdown list.
setValue() Set the select value. This should be a string for a simple select and an array if it's a multiple select.
addOption(items) Adds an option (several possible) to the select. The single option should follow this interface
{
  title: string;
  val: string;
  options?: {
    description: string;
    icon: string;
  };
}
removeOption(val) Removes an option by value (several possible).
recalculateDirection() Force recalculation for dropdown list.
Static methods
HSSelect.getInstance(target, isInstance) Returns the element associated to the target.
  • target should be a Node or string (valid selector)
  • isInstance boolean. Returns the instance instead of Node if true
HSSelect.close(target) Closes the element associated to the target.
  • target should be a Node or string (valid selector)
HSSelect.closeCurrentlyOpened(evtTarget) Closes the opened element associated to the target.
  • target should be a Node

Set value.

                      
                        const select = HSSelect.getInstance('#select');
                        const setValueBtn = document.querySelector('#set-value-btn');

                        setValueBtn.addEventListener('click', () => {
                          select.setValue('address');
                          // if select is multiple
                          // select.setValue(['address', 'email']);
                        });
                      
                    

Open item (public method).

                      
                        const select = new HSSelect(document.querySelector('#select'));
                        const openBtn = document.querySelector('#open-btn');

                        openBtn.addEventListener('click', () => {
                          select.open();
                        });
                      
                    

Open item (static method).

                      
                        const openBtn = document.querySelector('#open-btn');

                        openBtn.addEventListener('click', () => {
                          HSSelect.open('#select');
                        });
                      
                    

Open item (mixed).

                      
                        const { element } = HSSelect.getInstance('#select', true);
                        const openBtn = document.querySelector('#open-btn');

                        openBtn.addEventListener('click', () => {
                          element.open();
                        });
                      
                    

Add options (public method).

                      
                        const select = window.HSSelect.getInstance('#select');
                        const addOptionsBtn = document.querySelector('#add-options');

                        addOptionsBtn.addEventListener('click', () => {
                          select.addOption([
                            {
                              title: "James Collins",
                              val: "1",
                              options: {
                                icon: `<img class="inline-block size-6 rounded-full" src="https://images.unsplash.com/photo-1659482633369-9fe69af50bfb?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=3&w=320&h=320&q=80" alt="James Collins 2" />`
                              }
                            },
                            {
                              title: "Amanda Harvey",
                              val: "2",
                              options: {
                                icon: `<img class="inline-block size-6 rounded-full" src="https://images.unsplash.com/photo-1541101767792-f9b2b1c4f127?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=3&w=320&h=320&q=80" alt="Amanda Harvey" />`
                              }
                            }
                          ]);
                        });
                      
                    

Remove options (public method).

                      
                        const select = window.HSSelect.getInstance('#select');
                        const removeOptionsBtn = document.querySelector('#remove-options');

                        removeOptionsBtn.addEventListener('click', () => {
                          select.removeOption(["1", "2"]);
                        });
                      
                    

Destroy select (public method).

                      
                        const select = window.HSSelect.getInstance('#select');
                        const destroySelectBtn = document.querySelector('#destroy-select');

                        destroySelectBtn.addEventListener('click', () => {
                          select.destroy();
                        });
                      
                    

Events

Method Description Returning value
on:change Called when any select was changed. Current value

When select changes event example.

                      
                        const el = HSSelect.getInstance('#select');

                        el.on('change', (val) => {...});
                      
                    

Demo examples

Looking for prebuilt UI components based on the Tailwind CSS? Preline UI packs hundreds of component examples for all your website needs.

Plugins UI Mockups
Check out Preline UI Components