or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mddisplay.mdevents.mdindex.mdinitialization.mdinternationalization.mdselection.md
tile.json

internationalization.mddocs/

Internationalization

Built-in support for 41 languages with customizable text strings, formatting functions, and locale-specific behavior for global applications.

Capabilities

Language File Integration

Load and apply language-specific defaults using the provided internationalization files.

/**
 * Language files override global defaults
 * Include after bootstrap-select.js but before initialization
 */
<script src="path/to/bootstrap-select.js"></script>
<script src="path/to/i18n/defaults-[locale].js"></script>

/**
 * Global defaults object modified by language files
 */
$.fn.selectpicker.defaults: {
  noneSelectedText?: string;
  noneResultsText?: string;
  countSelectedText?: (numSelected: number, numTotal: number) => string;
  maxOptionsText?: (numAll: number, numGroup: number) => string[];
  selectAllText?: string;
  deselectAllText?: string;
  multipleSeparator?: string;
};

Usage Examples:

<!-- Include language file for German -->
<script src="bootstrap-select.js"></script>
<script src="i18n/defaults-de_DE.js"></script>

<!-- Selectpickers will now use German text by default -->
<select class="selectpicker">
  <option>Option 1</option>
  <option>Option 2</option>
</select>
// Check current defaults after language file loads
console.log($.fn.selectpicker.defaults.noneSelectedText);
// Output: "Nichts ausgewählt" (German)

// Initialize with language-specific defaults
$('.selectpicker').selectpicker();
// Will use German text automatically

Supported Locales

Complete list of available language files and their locale codes.

/**
 * Available locale files (41 languages):
 */
const SUPPORTED_LOCALES = [
  'am_ET', // Amharic (Ethiopia)
  'ar_AR', // Arabic (Arabic)  
  'bg_BG', // Bulgarian (Bulgaria)
  'cs_CZ', // Czech (Czech Republic)
  'da_DK', // Danish (Denmark)
  'de_DE', // German (Germany)
  'en_US', // English (United States)
  'es_CL', // Spanish (Chile)
  'es_ES', // Spanish (Spain)
  'et_EE', // Estonian (Estonia)
  'eu',    // Basque
  'fa_IR', // Persian (Iran)
  'fi_FI', // Finnish (Finland)
  'fr_FR', // French (France)
  'hr_HR', // Croatian (Croatia)
  'hu_HU', // Hungarian (Hungary)
  'id_ID', // Indonesian (Indonesia)
  'it_IT', // Italian (Italy)
  'ja_JP', // Japanese (Japan)
  'kh_KM', // Khmer (Cambodia)
  'ko_KR', // Korean (Korea)
  'lt_LT', // Lithuanian (Lithuania)
  'lv_LV', // Latvian (Latvia)
  'nb_NO', // Norwegian Bokmål (Norway)
  'nl_NL', // Dutch (Netherlands)
  'pl_PL', // Polish (Poland)
  'pt_BR', // Portuguese (Brazil)
  'pt_PT', // Portuguese (Portugal)
  'ro_RO', // Romanian (Romania)
  'ru_RU', // Russian (Russia)
  'sk_SK', // Slovak (Slovakia)
  'sl_SI', // Slovenian (Slovenia)
  'sr_SP', // Serbian (Serbia)
  'sv_SE', // Swedish (Sweden)
  'th_TH', // Thai (Thailand)
  'tr_TR', // Turkish (Turkey)
  'ua_UA', // Ukrainian (Ukraine)
  'vi_VN', // Vietnamese (Vietnam)
  'zh_CN', // Chinese (China)
  'zh_TW'  // Chinese (Taiwan)
];

Usage Examples:

// Dynamic locale loading
function loadLocale(locale) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = `i18n/defaults-${locale}.js`;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

// Load specific locale
loadLocale('fr_FR').then(() => {
  $('.selectpicker').selectpicker('refresh');
  console.log('French locale loaded');
});

// Locale selection interface
const localeSelect = document.getElementById('localeSelect');
SUPPORTED_LOCALES.forEach(locale => {
  const option = document.createElement('option');
  option.value = locale;
  option.textContent = locale;
  localeSelect.appendChild(option);
});

Custom Text Configuration

Override default text strings with custom translations or application-specific text.

/**
 * Override global defaults with custom text
 */
$.fn.selectpicker.defaults = {
  noneSelectedText: 'Custom no selection text',
  noneResultsText: 'Custom no results text for "{0}"',
  selectAllText: 'Custom select all text',
  deselectAllText: 'Custom deselect all text',
  multipleSeparator: ' • ',
  countSelectedText: function(numSelected, numTotal) {
    return `${numSelected}/${numTotal} selected`;
  },
  maxOptionsText: function(numAll, numGroup) {
    return [
      `Max ${numAll} selections`,
      `Group max ${numGroup} selections`
    ];
  }
};

/**
 * Override text for specific instances
 */
$('#customSelect').selectpicker({
  noneSelectedText: 'Instance-specific text',
  countSelectedText: function(numSelected, numTotal) {
    return `You have selected ${numSelected} items`;
  }
});

Usage Examples:

// Application-specific text
$.fn.selectpicker.defaults = {
  noneSelectedText: 'Choose your preferences...',
  noneResultsText: 'No matches found for "{0}"',
  selectAllText: 'Select Everything',
  deselectAllText: 'Clear Selection',
  multipleSeparator: ' | ',
  countSelectedText: function(numSelected, numTotal) {
    if (numSelected === 0) return 'None selected';
    if (numSelected === 1) return '1 item selected';
    if (numSelected === numTotal) return 'All selected';
    return `${numSelected} of ${numTotal} selected`;
  }
};

// Context-specific overrides
$('#colorSelect').selectpicker({
  noneSelectedText: 'Pick a color...',
  selectAllText: 'All Colors'
});

$('#countrySelect').selectpicker({
  noneSelectedText: 'Select country...',
  noneResultsText: 'Country "{0}" not found'
});

// Dynamic text based on context
function getLocalizedText(key, context) {
  const texts = {
    products: {
      noneSelectedText: 'Choose products...',
      selectAllText: 'All Products'
    },
    categories: {
      noneSelectedText: 'Select categories...',
      selectAllText: 'All Categories'
    }
  };
  return texts[context]?.[key] || $.fn.selectpicker.defaults[key];
}

$('.product-select').selectpicker({
  noneSelectedText: getLocalizedText('noneSelectedText', 'products'),
  selectAllText: getLocalizedText('selectAllText', 'products')
});

Runtime Locale Switching

Change language settings dynamically without page reload.

/**
 * Switch locale at runtime
 * @param locale - Target locale code
 * @returns Promise that resolves when locale is loaded
 */
function switchLocale(locale: string): Promise<void> {
  return loadLocaleFile(locale).then(() => {
    $('.selectpicker').selectpicker('refresh');
  });
}

/**
 * Get current locale information
 */
function getCurrentLocale(): {
  locale: string;
  noneSelectedText: string;
  selectAllText: string;
  deselectAllText: string;
} {
  return {
    locale: document.documentElement.lang || 'en_US',
    noneSelectedText: $.fn.selectpicker.defaults.noneSelectedText,
    selectAllText: $.fn.selectpicker.defaults.selectAllText,
    deselectAllText: $.fn.selectpicker.defaults.deselectAllText
  };
}

Usage Examples:

// Runtime locale switching
async function switchLocale(locale) {
  try {
    // Load new locale file
    await loadLocaleFile(locale);
    
    // Update all selectpickers
    $('.selectpicker').selectpicker('refresh');
    
    // Update document language
    document.documentElement.lang = locale;
    
    // Update UI feedback
    $('#currentLocale').text(locale);
    
    console.log(`Switched to locale: ${locale}`);
  } catch (error) {
    console.error(`Failed to load locale ${locale}:`, error);
  }
}

// Locale switcher interface
$('#localeSelector').on('change', function() {
  const selectedLocale = $(this).val();
  switchLocale(selectedLocale);
});

// Save user's locale preference
function saveLocalePreference(locale) {
  localStorage.setItem('preferredLocale', locale);
}

function loadSavedLocale() {
  const saved = localStorage.getItem('preferredLocale');
  if (saved && SUPPORTED_LOCALES.includes(saved)) {
    switchLocale(saved);
  }
}

// Initialize with saved preference
$(document).ready(() => {
  loadSavedLocale();
});

Custom Formatting Functions

Create advanced formatting functions for complex counting and text generation.

/**
 * Advanced count text formatting with pluralization
 */
function createCountFormatter(locale: string) {
  return function(numSelected: number, numTotal: number): string {
    // Implement locale-specific pluralization rules
    if (locale === 'ru_RU') {
      // Russian pluralization
      const cases = [2, 0, 1, 1, 1, 2];
      const index = (numSelected % 100 > 4 && numSelected % 100 < 20) 
        ? 2 : cases[Math.min(numSelected % 10, 5)];
      const forms = ['элемент выбран', 'элемента выбрано', 'элементов выбрано'];
      return `${numSelected} ${forms[index]}`;
    }
    // Default English formatting
    return numSelected === 1 ? '1 item selected' : `${numSelected} items selected`;
  };
}

/**
 * Context-aware max options text
 */
function createMaxOptionsFormatter(context: string) {
  return function(numAll: number, numGroup: number): string[] {
    const messages = {
      products: [`You can select up to ${numAll} products`, `Group limit: ${numGroup} products`],
      users: [`Maximum ${numAll} users allowed`, `User group limit: ${numGroup}`],
      default: [`Limit reached (${numAll} max)`, `Group limit reached (${numGroup} max)`]
    };
    return messages[context] || messages.default;
  };
}

Usage Examples:

// Pluralization-aware formatting
function createCountFormatter(locale) {
  const rules = {
    'en_US': (n) => n === 1 ? 'item' : 'items',
    'fr_FR': (n) => n <= 1 ? 'élément' : 'éléments',
    'de_DE': (n) => n === 1 ? 'Element' : 'Elemente',
    'ru_RU': (n) => {
      const cases = [2, 0, 1, 1, 1, 2];
      const index = (n % 100 > 4 && n % 100 < 20) ? 2 : cases[Math.min(n % 10, 5)];
      return ['элемент', 'элемента', 'элементов'][index];
    }
  };
  
  return function(numSelected, numTotal) {
    const unit = rules[locale] ? rules[locale](numSelected) : 'items';
    return `${numSelected} ${unit} selected`;
  };
}

// Apply custom formatter
$.fn.selectpicker.defaults.countSelectedText = createCountFormatter('ru_RU');

// Context-specific formatting
const productFormatter = createMaxOptionsFormatter('products');
$('#productSelect').selectpicker({
  maxOptionsText: productFormatter
});

// Conditional formatting based on selection
function smartCountFormatter(numSelected, numTotal) {
  if (numSelected === 0) return 'Make a selection';
  if (numSelected === numTotal) return 'All selected';
  if (numSelected === 1) return '1 selected';
  
  const percentage = Math.round((numSelected / numTotal) * 100);
  return `${numSelected} selected (${percentage}%)`;
}

$('#smartSelect').selectpicker({
  countSelectedText: smartCountFormatter
});