import { assertNotNull, assertNotUndefined } from './utils/assert'; import { $, $$, showEl, hideEl } from './utils/dom'; import { delegate, leftClick } from './utils/events'; import { addTag } from './tagsinput'; function focusAndSelectLast(field: HTMLInputElement, characterCount: number) { field.focus(); field.selectionStart = field.value.length - characterCount; field.selectionEnd = field.value.length; } function prependToLast(field: HTMLInputElement, value: string) { // Find the last comma in the input and advance past it const separatorIndex = field.value.lastIndexOf(','); const advanceBy = field.value[separatorIndex + 1] === ' ' ? 2 : 1; // Insert the value string at the new location field.value = [ field.value.slice(0, separatorIndex + advanceBy), value, field.value.slice(separatorIndex + advanceBy), ].join(''); } function getAssociatedData(target: HTMLElement) { const form = assertNotNull(target.closest('form')); const input = assertNotNull($('.js-search-field', form)); const helpBoxes = $$('[data-search-help]', form); return { input, helpBoxes }; } function showHelp(helpBoxes: HTMLDivElement[], typeName: string, subject: string) { for (const helpBox of helpBoxes) { // Get the subject name span const subjectName = assertNotNull($('.js-search-help-subject', helpBox)); // Take the appropriate action for this help box if (helpBox.dataset.searchHelp === typeName) { subjectName.textContent = subject; showEl(helpBox); } else { hideEl(helpBox); } } } function onSearchAdd(_event: Event, target: HTMLAnchorElement) { // Load form const { input, helpBoxes } = getAssociatedData(target); // Get data for this link const addValue = assertNotUndefined(target.dataset.searchAdd); const showHelpValue = assertNotUndefined(target.dataset.searchShowHelp); const selectLastValue = target.dataset.searchSelectLast; // Add the tag addTag(input, addValue); // Show associated help, if available showHelp(helpBoxes, showHelpValue, assertNotNull(target.textContent)); // Select last characters, if requested if (selectLastValue) { focusAndSelectLast(input, Number(selectLastValue)); } } function onSearchPrepend(_event: Event, target: HTMLAnchorElement) { // Load form const { input } = getAssociatedData(target); // Get data for this link const prependValue = assertNotUndefined(target.dataset.searchPrepend); // Prepend prependToLast(input, prependValue); } export function setupSearch() { delegate(document, 'click', { 'form.js-search-form a[data-search-add][data-search-show-help]': leftClick(onSearchAdd), 'form.js-search-form a[data-search-prepend]': leftClick(onSearchPrepend), }); }