CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-select2

Select2 is a jQuery based replacement for select boxes with searching, remote data sets, and infinite scrolling support

Pending
Overview
Eval results
Files

theming.mddocs/

Theming and Customization

Appearance customization through themes, CSS classes, template functions, and custom rendering for both dropdown options and selections.

Capabilities

Theme System

Built-in theme support with extensible theme architecture for consistent styling.

/**
 * Theme configuration
 */
theme?: string;     // Theme name (default: 'default')

// Available built-in themes
'default'           // Standard Select2 theme
'classic'           // Legacy Select2 v3.x appearance
'bootstrap4'        // Bootstrap 4 integration (requires additional CSS)

Usage Examples:

// Use default theme
$('#default-select').select2({
    theme: 'default'
});

// Use Bootstrap 4 theme (requires select2-bootstrap4-theme CSS)
$('#bootstrap-select').select2({
    theme: 'bootstrap4'
});

// Use classic theme
$('#classic-select').select2({
    theme: 'classic'
});

CSS Customization

Direct CSS styling through inline styles and CSS classes for fine-grained control.

/**
 * CSS customization options
 */
interface CssOptions {
    containerCss?: object;              // Inline CSS for main container
    containerCssClass?: string;         // CSS classes for main container
    dropdownCss?: object;              // Inline CSS for dropdown
    dropdownCssClass?: string;         // CSS classes for dropdown
    dropdownParent?: jQuery;           // Custom dropdown container element
    dropdownAutoWidth?: boolean;       // Auto-size dropdown width
}

Usage Examples:

// Inline CSS styling
$('#styled-select').select2({
    containerCss: {
        'width': '300px',
        'border-radius': '8px',
        'border': '2px solid #007bff'
    },
    dropdownCss: {
        'border-radius': '8px',
        'box-shadow': '0 4px 6px rgba(0,0,0,0.1)'
    }
});

// CSS class customization
$('#classed-select').select2({
    containerCssClass: 'my-select-container custom-border',
    dropdownCssClass: 'my-dropdown custom-shadow'
});

// Dropdown positioning
$('#modal-select').select2({
    dropdownParent: $('#myModal'),
    dropdownCssClass: 'modal-dropdown'
});

// Auto-width dropdown
$('#auto-width-select').select2({
    dropdownAutoWidth: true,
    width: 'element'
});

Template Functions

Customize the rendering of dropdown options and selected items with complete HTML control.

/**
 * Template function interfaces
 */
templateResult?: (result: DataObject) => string | jQuery | null;
templateSelection?: (selection: DataObject) => string | jQuery;
escapeMarkup?: (markup: string) => string;

/**
 * Template function receives DataObject
 */
interface DataObject {
    id: string | number;
    text: string;
    element?: HTMLOptionElement;
    loading?: boolean;      // True during AJAX loading
    disabled?: boolean;
}

Usage Examples:

// Custom dropdown option rendering
$('#template-results').select2({
    templateResult: function(result) {
        // Handle loading state
        if (result.loading) {
            return 'Loading...';
        }
        
        // Handle empty results
        if (!result.id) {
            return result.text;
        }
        
        // Custom HTML template
        return $('<span><i class="icon-' + result.id + '"></i> ' + result.text + '</span>');
    }
});

// Custom selection rendering
$('#template-selection').select2({
    templateSelection: function(selection) {
        // Simple text for placeholder
        if (!selection.id) {
            return selection.text;
        }
        
        // Custom selection display
        return selection.text + ' (ID: ' + selection.id + ')';
    }
});

// Rich HTML templates
$('#rich-templates').select2({
    templateResult: function(result) {
        if (result.loading) return 'Searching...';
        if (!result.id) return result.text;
        
        // Complex HTML with multiple elements
        var $container = $(
            '<div class="select2-result-item">' +
                '<div class="item-title"></div>' +
                '<div class="item-description"></div>' +
            '</div>'
        );
        
        $container.find('.item-title').text(result.text);
        $container.find('.item-description').text('Description for ' + result.text);
        
        return $container;
    },
    templateSelection: function(selection) {
        return selection.text || selection.id;
    }
});

// Image templates with data attributes
$('#image-select').select2({
    templateResult: function(result) {
        if (!result.id || result.loading) {
            return result.text;
        }
        
        var imageUrl = $(result.element).data('image');
        if (imageUrl) {
            return $(
                '<span>' +
                    '<img src="' + imageUrl + '" style="width:20px;height:20px;margin-right:8px;" /> ' +
                    result.text +
                '</span>'
            );
        }
        
        return result.text;
    }
});

Width and Sizing

Control the dimensions and responsive behavior of Select2 components.

/**
 * Width configuration options
 */
width?: string;

// Width values
'resolve'           // Auto-detect from element, style, or compute (default)
'style'            // Use CSS width from element
'element'          // Use element's width
'off'              // No width applied
'100%'             // Percentage width
'300px'            // Fixed pixel width

Usage Examples:

// Responsive width
$('#responsive-select').select2({
    width: '100%'
});

// Fixed width
$('#fixed-select').select2({
    width: '250px'
});

// Auto-detect width
$('#auto-select').select2({
    width: 'resolve'
});

// Use element's computed width
$('#element-width-select').select2({
    width: 'element'
});

// Responsive with max-width via CSS
$('#max-width-select').select2({
    width: '100%',
    containerCss: {
        'max-width': '400px'
    }
});

Custom Markup Escaping

Control HTML escaping for security and custom rendering needs.

/**
 * Markup escaping function
 */
escapeMarkup?: (markup: string) => string;

// Default escaping function
function defaultEscapeMarkup(markup) {
    var replaceMap = {
        '\\': '&#92;',
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
        "/": '&#47;'
    };
    
    return String(markup).replace(/[&<>"'\/\\]/g, function(match) {
        return replaceMap[match];
    });
}

Usage Examples:

// Disable escaping for trusted HTML content
$('#html-select').select2({
    escapeMarkup: function(markup) {
        return markup; // No escaping - USE WITH CAUTION
    },
    templateResult: function(result) {
        if (!result.id) return result.text;
        
        // Trusted HTML content
        return '<strong>' + result.text + '</strong>';
    }
});

// Custom escaping function
$('#custom-escape-select').select2({
    escapeMarkup: function(markup) {
        // Custom escaping logic
        return markup
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;');
    }
});

// Selective escaping
$('#selective-escape-select').select2({
    escapeMarkup: function(markup) {
        // Allow certain HTML tags
        var allowedTags = ['<strong>', '</strong>', '<em>', '</em>'];
        var escaped = Select2.util.escapeMarkup(markup);
        
        allowedTags.forEach(function(tag) {
            var escapedTag = Select2.util.escapeMarkup(tag);
            escaped = escaped.replace(new RegExp(escapedTag, 'g'), tag);
        });
        
        return escaped;
    }
});

Advanced Styling Techniques

Complex styling scenarios and integration patterns.

// Theme-aware styling
$('#theme-aware-select').select2({
    theme: 'bootstrap4',
    templateResult: function(result) {
        if (!result.id) return result.text;
        
        var $option = $(
            '<div class="custom-option d-flex align-items-center">' +
                '<span class="option-text flex-grow-1"></span>' +
                '<small class="text-muted option-meta"></small>' +
            '</div>'
        );
        
        $option.find('.option-text').text(result.text);
        $option.find('.option-meta').text('(' + result.id + ')');
        
        return $option;
    },
    containerCssClass: 'select2-bootstrap4-theme'
});

// Conditional styling based on data
$('#conditional-style-select').select2({
    templateResult: function(result) {
        if (!result.id || result.loading) return result.text;
        
        var $element = $(result.element);
        var priority = $element.data('priority');
        var category = $element.data('category');
        
        var $container = $('<span class="custom-result"></span>');
        $container.text(result.text);
        
        // Add classes based on data attributes
        if (priority === 'high') {
            $container.addClass('high-priority');
        }
        
        if (category) {
            $container.addClass('category-' + category);
        }
        
        return $container;
    },
    containerCssClass: function(element) {
        // Dynamic container classes
        return 'select2-' + element.attr('data-style');
    }
});

// Responsive styling
$('#responsive-styled-select').select2({
    width: '100%',
    containerCss: {
        'min-width': '200px',
        'max-width': '100%'
    },
    dropdownCss: {
        'min-width': '250px'
    },
    dropdownAutoWidth: true
});

CSS Classes Reference

Key CSS classes for styling Select2 components.

/* Main container */
.select2-container { }
.select2-container--default { }
.select2-container--bootstrap4 { }

/* Selection area */
.select2-selection { }
.select2-selection--single { }
.select2-selection--multiple { }

/* Dropdown */
.select2-dropdown { }
.select2-dropdown--below { }
.select2-dropdown--above { }

/* Results */
.select2-results { }
.select2-results__options { }
.select2-results__option { }
.select2-results__option--highlighted { }
.select2-results__option--selected { }

/* Search */
.select2-search { }
.select2-search__field { }

/* Multiple selection */
.select2-selection__choice { }
.select2-selection__choice__remove { }

/* States */
.select2-container--disabled { }
.select2-container--open { }
.select2-container--focus { }

Usage Examples:

/* Custom theme styling */
.my-custom-theme .select2-container {
    border-radius: 8px;
}

.my-custom-theme .select2-selection {
    border: 2px solid #007bff;
    border-radius: 8px;
}

.my-custom-theme .select2-dropdown {
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.my-custom-theme .select2-results__option--highlighted {
    background-color: #007bff;
    color: white;
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .select2-container {
        width: 100% !important;
    }
    
    .select2-dropdown {
        width: 100% !important;
    }
}

Install with Tessl CLI

npx tessl i tessl/npm-select2

docs

ajax.md

configuration.md

data-management.md

events.md

index.md

initialization.md

theming.md

tile.json