search form

A Search form is a search field, wrapped in a form, with possible auto-suggestions. For the form to work, you will need to set up either a name attribute on the search input and an action on the form, or implement your logic in a submit event handler on the form.

Attaching autosuggestions heavily depends on your setup and is therefore not part of this component.

The autosuggestion list is a markup demonstrator; do not use this implementation in production! We recommend to use the `autocomplete="off"` setting showcased here to prevent the browser's native suggestions to overlay the custom suggestions.
According to the Web Content Accessibility Guidelines (WCAG), it is highly reccomended to use a label together with the search form.

component variations

Default

<form class="m-search-form" autocomplete="off">
  <div class="a-search-input">
    <input
      type="search"
      id="search-input-1"
      name="Default"
      placeholder="Search"
    />
    <button type="button" class="a-search-input__icon-close">
      <i class="a-icon ui-ic-close-small"></i>
    </button>
    <button
      type="submit"
      class="a-search-input__icon-search"
      aria-label="Search"
    >
      <i class="a-icon ui-ic-search"></i>
    </button>
  </div>
</form>

With suggestions

<form class="m-search-form" autocomplete="off">
  <div class="a-search-input">
    <input
      type="search"
      id="search-input-2"
      name="With suggestions"
      placeholder="Search"
    />
    <button type="button" class="a-search-input__icon-close">
      <i class="a-icon ui-ic-close-small"></i>
    </button>
    <button
      type="submit"
      class="a-search-input__icon-search"
      aria-label="Search"
    >
      <i class="a-icon ui-ic-search"></i>
    </button>
  </div>
  <ul class="a-search-suggestions">
    <li class="a-search-suggestions__item">
      <a href="#" class="a-search-suggestions__result-link">
        <em>Product XYZ</em>
        Lorem ipsum dolor
      </a>
    </li>
    <li class="a-search-suggestions__item">
      <a href="#" class="a-search-suggestions__result-link">
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr Product XYZ
        another line can be very long or very short, however when text breaks
        and the Product XYZ is mentioned again,
        <em>we should highlight this</em>
      </a>
    </li>
    <li class="a-search-suggestions__item">
      <a href="#" class="a-search-suggestions__result-link">
        Lorem ipsum
        <em>Product XYZ</em>
      </a>
    </li>
    <li class="a-search-suggestions__item">
      <a href="#" class="a-search-suggestions__result-link">
        <em>Product XYZ</em>
        Lorem ipsum dolor
      </a>
    </li>
    <li class="a-search-suggestions__item a-search-suggestions__results-link">
      <div class="a-link -icon">
        <a href="/" target="_self">
          <span>All</span>
          <span>
            Results
            <i class="a-icon ui-ic-nosafe-lr-right-small"></i>
          </span>
        </a>
      </div>
    </li>
  </ul>
</form>

Auto suggestion demonstrator

<div class="frontend-kit-example_m-search-form">
  <form class="m-search-form" autocomplete="off">
    <div class="a-search-input">
      <input type="search" id="search-input-3" />
      <button type="button" class="a-search-input__icon-close">
        <i class="a-icon ui-ic-close-small"></i>
      </button>
      <button
        type="submit"
        class="a-search-input__icon-search"
        aria-label="Search"
      >
        <i class="a-icon ui-ic-search"></i>
      </button>
    </div>
  </form>
</div>

additional content

Instance API

The instance API can be accessed by the component property of the searchForm element.

Attribute description
searchInput access the underlying inputSearch component to subscribe to custom events

demo

import { dataMock } from './demonstrators/dataMock';

export default (): void => {
  const searchFields = document.querySelectorAll(
    '.a-text-field.a-text-field--search',
  );

  [...searchFields].forEach((searchField) => {
    const searchInput: HTMLInputElement = searchField.querySelector(
      '[type="search"]',
    );
    const resetIcon: HTMLElement = searchField.querySelector(
      '.a-text-field__icon-close',
    );

    // register the reset of the text field input
    if (resetIcon instanceof HTMLElement) {
      resetIcon.addEventListener('click', () => {
        if (searchInput.getAttribute('type') === 'search') {
          searchInput.value = '';
        }
      });
    }
  });

  const exampleContainers = document.querySelectorAll(
    '.frontend-kit-example_m-search-form',
  );

  [...exampleContainers].forEach((container) => {
    const searchField = container.querySelector('.m-search-form');

    searchField.addEventListener('input', (e) => {
      const pastSuggestions = container.querySelector('.a-search-suggestions');
      if (pastSuggestions) {
        pastSuggestions.remove();
      }
      const term = e.target.value;

      const suggestions = [];
      for (let i = 0; suggestions.length < 4 && dataMock.length > i; i += 1) {
        if (dataMock[i].toLowerCase().indexOf(term.toLowerCase()) !== -1) {
          suggestions.push({
            text: dataMock[i],
            highlight: term,
            href: '#',
          });
        }
      }

      const renderSuggestionLinkText = (
        text: string,
        highlight: string,
      ): string => {
        if (!highlight) {
          return text;
        }
        const searchPattern = new RegExp(highlight, 'ig');
        return text.replace(searchPattern, '<em>$&</em>');
      };

      if (suggestions.length) {
        const suggestionItems = suggestions.map((suggestion) => {
          return `
          <li class="a-search-suggestions__item">
            <a href="#" class="a-search-suggestions__result-link">${renderSuggestionLinkText(
              suggestion.text,
              suggestion.highlight,
            )}</a>
          </li>`;
        });
        const suggestionList = `
        <ul class="a-search-suggestions">
          ${suggestionItems.join('')}
          <li class="a-search-suggestions__item a-search-suggestions__results-link">
            <div class="a-link a-link--primary">
              <a href="/" target="_self">All Results</a>
            </div>
          </li>
        </ul>`;
        searchField.insertAdjacentHTML('beforeend', suggestionList);
      }
    });
  });
};

styles SCSS

// no styles needed here, yay!```