Custom Search / Поиск

ver.3.2.0
от 29.07.2025 10:20

Особенности

  1. Два вида отображения поиска: "статичный" и "скользящий"
    Очищает введенное содержимое в текстовом поле.
  2. Кнопка "очистить поле"
    Очищает введенное содержимое в текстовом поле.
  3. Изменение плейсхолдера
    Можно указывать как для всех разрешений, так и для каждого отдельного разрешения.
  4. Результаты поиска
    Получение и отображение выпадающих результатов поиска. Моковые данные или данные по api.
  5. Переключение результатов поиска при помощи стрелок на клавиатуре
    Переключение выделения найденых результатов при помощи клавишных стрелок на клавиатуре.

Codes

Jade/Pug
HTML
JS
Форма
от 28.07.2025 14:52
Код
      form.form.form_type_default.form-search(data-form-id="search")
    .form__fields
        .form__field.form__field-query
            label.form__label(for="form-search-field-query") Поиск
            input.form__input(id="form-search-field-query", type="text", name="query", data-type="query", value="")
        .form__field.form__field-result
            .search-result-popover
                .search-result-popover__content Содержимое поповера
    .form__actions
        button.form__submit.button.button-primary.button-m(type="submit")
            .button__icon
                <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15Z" stroke="#151515" stroke-width="1.5" stroke-linejoin="round" />
                <path d="M13 13L16.5 16.5" stroke="#151515" stroke-width="1.5" stroke-linejoin="round" />
                </svg>
            .button__name Найти
    
Статичный вид
от 15.07.2025 14:43
Описание

Статичный поиск - это классический вид поиска с полем для ввода и кнопкой.

Описание классов:
.search_type_full - поле для ввода и кнопка отдельно от поля.
.search_type_compact - поле для ввода и кнопка поверх поля.
Код
      .search.search_view_static[.search_type_full|.search_type_compact]
    .search__form
        include ../../components/forms/custom/search/search
    
Cкользящий вид
от 15.07.2025 14:43
Описание

Скользящий поиск - это вид поиска который отображает только иконку поиска, а поле для ввода и кнопка выезжают при наведении.

Описание классов:
.search_type_full - поле для ввода и кнопка отдельно от поля.
.search_type_compact - поле для ввода и кнопка поверх поля.
.search_direction_left - Направление формы в какую сторону будет выезжать.
.search_direction_right - Направление формы в какую сторону будет выезжать.
Код
      .search.search_view_sliding[.search_type_full|.search_type_compact][.search_direction_left|.search_direction_right]
    .search__icon
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15Z" stroke="#151515" stroke-width="1.5" stroke-linejoin="round" />
        <path d="M13 13L16.5 16.5" stroke="#151515" stroke-width="1.5" stroke-linejoin="round" />
        </svg>
    .search__form
        include ../../components/forms/custom/search/search
    

Changelogs

v3.2.0
latest
от 29 Июля 2025
  • Переключение выделения найденых результатов при помощи клавишных стрелок на клавиатуре.
v3.1.0
от 28 Июля 2025
  • Получение и отображение выпадающих результатов поиска. Моковые данные или данные по api.
v3.0.0
от 03 Июля 2025
  • Добавлена кнопка "очистить поле"
  • Добавлена возможность проставлять свой плейсхолдер
v2.0.0
  • Информация отсутствует
v1.0.0
  • Init

Архив

ver.3.1.0
JS
от 28.07.2025 14:52
Параметры
PARAMTYPEDEFAULTDESCRIPTION
mocksbooleantrueОтображение моковых данных. При выключении опции данные будут браться из api
clearbooleantrueКнопка очистить введеное значение в поле.
placeholderstring|object'Поиск'

Текст плейхолдера.

Один плейхолдер для всех разрешений.

placeholder: 'Поиск'

Разные плейхолдеры для определенных разрешений.

{
    desktop: 'Поиск на ПК',
    tablet: 'Поиск на планшете',
    mobile: 'Поиск на телефоне',
    'mobile-sm': 'Поиск на маленьком телефоне',
}

Примечание:

Для указания разрешений потребуется наличие скрипта "CustomDevices"

Как юзать
      new CustomSearch();
    
      new CustomSearch({
    clear: false,
    placeholder: 'Поиск'
});
    
Код
      /**
 *
 * Custom Search 3.1.0
 * Поиск
 *
 * Copyright 2025 Mihail Pridannikov
 *
 * Released on: July 28, 2025
 *
 */

window.CustomSearch = function(customSettings) {
    this.deepMergeObjects = function (obj1, obj2) {
        const result = {};
        for (const key in obj2) {
            if (obj2.hasOwnProperty(key)) {
                if (typeof obj2[key] === "object" && obj1.hasOwnProperty(key) && typeof obj1[key] === "object") {
                    result[key] = this.deepMergeObjects(obj1[key], obj2[key]);
                } else {
                    result[key] = obj2[key];
                }
            }
        }
        for (const key in obj1) {
            if (obj1.hasOwnProperty(key) && !result.hasOwnProperty(key)) {
                if (typeof obj1[key] === "object") {
                    result[key] = this.deepMergeObjects(obj1[key], {});
                } else {
                    result[key] = obj1[key];
                }
            }
        }
        return result;
    }

    const FORM = document.querySelectorAll('.form-search');
    const DEFAULT_SETTINGS = {
        mocks: true,
        clear: true,
        placeholder: 'Поиск',
    }
    let settings = this.deepMergeObjects(DEFAULT_SETTINGS, customSettings);

    this.init = function () {

        // console.log('default', DEFAULT_SETTINGS)
        // console.log('custom', customSettings)
        // console.log('merge', settings)

        if (FORM.length) {
            FORM.forEach(form => {
                if (form) {

                    // добавляем кнопку очистить поле
                    if (form.querySelector('.form__input').value !== '') {
                        this.addButtonClear(form);
                        this.addClassFilled(form);
                    }

                    // событие при изменении поля
                    form.querySelector('.form__input').addEventListener('input', e => this.handlerChangeOnTextField(e, form));

                    this.setPlaceholder(form);
                    // this.setSettingsSearchInHeader(form);

                }
            });
            window.addEventListener('resize', e => {
                this.handlerResizeWindow();
            }, true);
        }
    }
    this.handlerResizeWindow = function () {
        FORM.forEach(form => {
            if (form) {
                this.setPlaceholder(form);
                // this.setSettingsSearchInHeader(form);
            }
        });
    }
    this.setPlaceholder = function (search) {
        switch (typeof settings.placeholder) {
            case 'string':
                search.querySelector('.form__input').setAttribute('placeholder', settings.placeholder);
                break;
            case 'object':
                let checkRange = Object.entries(settings.placeholder).find(item => document.body.classList.contains(`js-device-${item[0]}`));
                search.querySelector('.form__input').setAttribute('placeholder', checkRange ? checkRange[1] : 'Поиск');
                break;
            default:
                break;
        }
    }
    this.handlerChangeOnTextField = function (e, form) {
        // добавляем кнопку очистить поле
        if (e.currentTarget.value !== '') {
            this.addButtonClear(form);
            this.addClassFilled(form);
            this.initSearchResult(form, e.currentTarget.value.toLowerCase());
        } else {
            this.removeButtonClear(form);
            this.removeClasses(form);
            settings.mocks ? this.closePopover(form) : this.removeResults(form);
        }

    }
    this.initSearchResult = function (form, query) {
        if (settings.mocks) {
            this.openPopover(form);
        } else {
            let words = query.split(' ');
            words.filter(word => {
                this.getData(form, word);
            });
        }
    }
    this.addButtonClear = function (form) {
        if (settings.clear) {
            if (!form.querySelector('.form__button-clear')) {
                form.querySelector('.form__field-query').insertAdjacentHTML('beforeend',
                    `<button class="form__button-clear">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
                        <path fill="gray" d="M1.793 1.796a1 1 0 000 1.414l4.793 4.793-4.793 4.793a1 1 0 001.414 1.414L8 9.417l4.793 4.793a1 1 0 001.414-1.414L9.414 8.003l4.793-4.793a1 1 0 00-1.414-1.414L8 6.589 3.207 1.796a1 1 0 00-1.414 0z" />
                    </svg>
                </button>`);
                form.classList.add('is-button-clear');
                form.querySelector('.form__button-clear').addEventListener('click', e => this.handlerClickOnButtonClear(e, form));
            }
        }
    }
    this.removeButtonClear = function (search) {
        if (search.querySelector('.form__button-clear')) {
            search.querySelector('.form__button-clear').remove();
            search.classList.remove('is-button-clear');
        }
    }
    this.handlerClickOnButtonClear = function (e, form) {
        e.preventDefault();
        form.querySelector('.form__input').value = '';
        this.removeClasses(form);
        settings.mocks ? this.closePopover(form) : this.removeResults(form);
        this.removeButtonClear(form);
    }
    this.removeClasses = function (search) {
        search.classList.remove('is-focus');
        search.classList.remove('is-open');
        search.classList.remove('is-filled');
    }
    this.addClassFilled = function (form) {
        form.classList.add('is-filled');
    }
    this.createPopover = function (form, data) {
        if (!form.querySelector('.form__field-result')) {
            form.querySelector('.form__fields').insertAdjacentHTML('beforeend', `
                <div class="form__field form__field-result">
                    <div class="search-result-popover">
                        <div class="search-result-popover__content"></div>
                    </div>
                </div>
            `);
        }
        const field = form.querySelector('.form__field-result');
        this.clearResults(field);
        this.insertResults(form, data);
    }
    this.openPopover = function (form) {
        form.classList.add('is-popover-opened');
    }
    this.closePopover = function (form) {
        form.classList.remove('is-popover-opened');
    }
    this.insertResults = function (form, data) {
        if (data) {
            data.map(item => {
                form.querySelector('.search-result-popover__content').insertAdjacentHTML('beforeend',
            `
                    <div class="search-result-mini__item">
                        <div class="teaser-product-search">
                            <div class="teaser-product-search__image">
                                <img src="" alt="" width="32" height="32" loading="lazy">
                            </div>
                            <div class="teaser-product-search__name">Тестовое название товара</div>
                            <div class="teaser-product-search__price">1 000р.</div>
                        </div>
                    </div>
                `);
            });
        } else {
            form.querySelector('.search-result-popover__content').textContent = 'Результаты не найдены';
        }
        this.openPopover(form);
    }
    this.clearResults = function (field) {
        field.querySelector('.search-result-popover__content').innerHTML = '';
    }
    this.removeResults = function (form) {
        if (form.querySelector('.form__field-result')) {
            form.querySelector('.form__field-result').remove();
        }
    }
    this.getData = function (form, query) {
        fetch('/rest/search?key=' + query, {method: 'GET'})
        .then((response) => {
            if (response.ok) {
                return response.json()
            }
            throw new Error('Network response was not ok')
        })
        .then((data) => {
            // console.log('DATA:', data);
            this.createPopover(form, data);
        })
        .catch((error) => {
            console.log('ERROR:', error);
        })
    }

    if (FORM) {
        this.init();
    }
}
    
ver.3.0.0
JS
от 03.07.2025 21:29
Параметры
PARAMTYPEDEFAULTDESCRIPTION
clearbooleantrueКнопка очистить введеное значение в поле.
placeholderstring|object'Поиск'

Текст плейхолдера.

Один плейхолдер для всех разрешений.

placeholder: 'Поиск'

Разные плейхолдеры для определенных разрешений.

{
    desktop: 'Поиск на ПК',
    tablet: 'Поиск на планшете',
    mobile: 'Поиск на телефоне',
    'mobile-sm': 'Поиск на маленьком телефоне',
}

Примечание:

Для указания разрешений потребуется наличие скрипта "CustomDevices"

Как юзать
      new CustomSearch();
    
      new CustomSearch({
    clear: false,
    placeholder: 'Поиск'
});
    
Код
      /**
 *
 * Custom Search 3.0.0
 * Поиск
 *
 * Copyright 2025 Mihail Pridannikov
 *
 * Released on: July 3, 2025
 *
 */

window.CustomSearch = function(customSettings) {
    this.deepMergeObjects = function (obj1, obj2) {
        const result = {};
        for (const key in obj2) {
            if (obj2.hasOwnProperty(key)) {
                if (typeof obj2[key] === "object" && obj1.hasOwnProperty(key) && typeof obj1[key] === "object") {
                    result[key] = this.deepMergeObjects(obj1[key], obj2[key]);
                } else {
                    result[key] = obj2[key];
                }
            }
        }
        for (const key in obj1) {
            if (obj1.hasOwnProperty(key) && !result.hasOwnProperty(key)) {
                if (typeof obj1[key] === "object") {
                    result[key] = this.deepMergeObjects(obj1[key], {});
                } else {
                    result[key] = obj1[key];
                }
            }
        }
        return result;
    }

    const FORM = document.querySelectorAll('.form-search');
    const DEFAULT_SETTINGS = {
        clear: true,
        placeholder: 'Поиск',
        // placeholder: {
        //     desktop: 'Поиск на ПК',
        //     tablet: 'Поиск на планшете',
        //     mobile: 'Поиск на телефоне',
        //     'mobile-sm': 'Поиск на маленьком телефоне',
        // },
        // headerType: 'full',
        // headerSlideDirection: null,
        // headerBreakpoint: {
        //     breakpoint: [767, 1023],
        //     type: 'short',
        //     slideDirection: 'left'
        // }
    }
    let settings = this.deepMergeObjects(DEFAULT_SETTINGS, customSettings);

    this.init = function () {

        console.log('default', DEFAULT_SETTINGS)
        console.log('custom', customSettings)
        console.log('merge', settings)

        if (FORM.length) {
            FORM.forEach(form => {
                if (form) {

                    // добавляем кнопку очистить поле
                    if (form.querySelector('.form__input').value !== '') {
                        this.addButtonClear(form);
                        this.addClassFilled(form);
                    }

                    // событие при изменении поля
                    form.querySelector('.form__input').addEventListener('input', e => this.handlerChangeOnTextField(e, form));

                    this.setPlaceholder(form);
                    // this.setSettingsSearchInHeader(form);

                }
            });
            window.addEventListener('resize', e => {
                this.handlerResizeWindow();
            }, true);
        }
    }

    // событие на изменение разрешения браузера
    this.handlerResizeWindow = function () {
        FORM.forEach(form => {
            if (form) {
                this.setPlaceholder(form);
                // this.setSettingsSearchInHeader(form);
            }
        });
    }

    // задаем настройки поиску находящийся в шапке
    // this.setSettingsSearchInHeader = function (form) {
    //     if (this.getParameter('headerType') && !this.getParameter('headerBreakpoint')) {
    //         this.setTypeSearch(form);
    //         this.setSlideDirection(form);
    //     } else {
    //         let widthWindow = document.body.getBoundingClientRect().width;
    //         this.removeClassTypeSearch(form);
    //         this.removeClassSlideDirection(form);
    //         this.getParameter('headerBreakpoint').map(item => {
    //             let min = typeof item.breakpoint[0] === 'number' ? item.breakpoint[0] : rangeDevices[item.breakpoint[0]].value;
    //             let max = typeof item.breakpoint[1] === 'number' ? item.breakpoint[1] : rangeDevices[item.breakpoint[1]].value;
    //             if (min === 0 && widthWindow <= max) {
    //                 this.setTypeSearch(form, item);
    //                 item.type === 'short' && this.setSlideDirection(form, item);
    //             } else if (max === 0 && widthWindow > min) {
    //                 this.setTypeSearch(form, item);
    //                 item.type === 'short' && this.setSlideDirection(form, item);
    //             } else if (widthWindow > min && widthWindow <= max) {
    //                 this.setTypeSearch(form, item);
    //                 item.type === 'short' && this.setSlideDirection(form, item);
    //             }
    //         })
    //     }
    // }

    // устанавливаем тип поиска
    // this.setTypeSearch = function (form, item) {
    //     if (this.getParameter('headerType') && !this.getParameter('headerBreakpoint')) {
    //         form.classList.add(`form-search_type_${this.getParameter('headerType')}`)
    //     } else {
    //         form.classList.add(`form-search_type_${item.type}`)
    //     }
    // }

    // устанавливаем направление поиска если он "short"
    // this.setSlideDirection = function (form, item) {
    //     if (this.getParameter('headerType') && !this.getParameter('headerBreakpoint')) {
    //         this.getParameter('headerType') === 'short' ? form.classList.add(`form-search_slide-direction_${this.getParameter('headerSlideDirection')}`) : null;
    //     } else {
    //         form.classList.add(`form-search_slide-direction_${item.slideDirection}`)
    //     }
    // }

    // this.removeClassTypeSearch = function (form) {
    //     form.classList.remove(...[...form.classList].filter(n => n.startsWith('form-search_type_')));
    // }
    // this.removeClassSlideDirection = function (form) {
    //     form.classList.remove(...[...form.classList].filter(n => n.startsWith('form-search_slide-direction_')));
    // }

    // проверка на наличие кастомных настроек
    // this.checkingSettings = function () {
    //     // return typeof customSettings !== 'undefined' || (typeof customSettings === 'object' && Object.keys(customSettings).length > 0);
    //     return (typeof customSettings === 'object' && Object.keys(customSettings).length > 0);
    // }

    // проверка на наличе параметра в кастомных настройках
    // this.checkingParameter = function (value) {
    //     return typeof customSettings[value] !== 'undefined'
    // }
    // // получаем параметр из кастомных настроек, если там нету, то из значений по умолчанию
    // this.getParameter = function (value) {
    //     // console.log(value, this.checkingSettings() && this.checkingParameter(value) ? customSettings[value] : DEFAULT_SETTINGS[value])
    //     return this.checkingSettings() && this.checkingParameter(value) ? customSettings[value] : DEFAULT_SETTINGS[value];
    // }

    // задаем плейсхолдер
    this.setPlaceholder = function (search) {
        switch (typeof settings.placeholder) {
            case 'string':
                search.querySelector('.form__input').setAttribute('placeholder', settings.placeholder);
                break;
            case 'object':
                let checkRange = Object.entries(settings.placeholder).find(item => document.body.classList.contains(`js-device-${item[0]}`));
                search.querySelector('.form__input').setAttribute('placeholder', checkRange ? checkRange[1] : 'Поиск');
                break;
            default:
                break;
        }
    }

    // событие при изменении поля
    this.handlerChangeOnTextField = function (e, form) {
        // добавляем кнопку очистить поле
        if (e.currentTarget.value !== '') {
            this.addButtonClear(form);
            this.addClassFilled(form);
        } else {
            this.removeButtonClear(form);
            this.removeClasses(form);
        }
    }

    // добавляем кнопку очистить поле
    this.addButtonClear = function (form) {
        if (settings.clear) {
            if (!form.querySelector('.form__button-clear')) {
                form.querySelector('.form__field-query').insertAdjacentHTML('beforeend',
                    `<button class="form__button-clear">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
                        <path fill="gray" d="M1.793 1.796a1 1 0 000 1.414l4.793 4.793-4.793 4.793a1 1 0 001.414 1.414L8 9.417l4.793 4.793a1 1 0 001.414-1.414L9.414 8.003l4.793-4.793a1 1 0 00-1.414-1.414L8 6.589 3.207 1.796a1 1 0 00-1.414 0z" />
                    </svg>
                </button>`);
                form.classList.add('is-button-clear');
                form.querySelector('.form__button-clear').addEventListener('click', e => this.handlerClickOnButtonClear(e, form));
            }
        }
    }

    // удаляем кнопку очистить поле
    this.removeButtonClear = function (search) {
        if (search.querySelector('.form__button-clear')) {
            search.querySelector('.form__button-clear').remove();
            search.classList.remove('is-button-clear');
        }
    }

    // событие клика по кнопке очистить поле
    this.handlerClickOnButtonClear = function (e, form) {
        e.preventDefault();
        form.querySelector('.form__input').value = '';
        this.removeClasses(form);
        this.removeResult(form);
        this.removeButtonClear(form);
    }

    // удаление классов
    this.removeClasses = function (search) {
        search.classList.remove('is-results');
        search.classList.remove('is-focus');
        search.classList.remove('is-open');
        search.classList.remove('is-filled');
    }

    // добавляем класс что поле заполнено
    this.addClassFilled = function (form) {
        form.classList.add('is-filled');
    }

    // удаляем результаты поиска
    this.removeResult = function (search) {
        search.querySelector('.search-result') ? search.querySelector('.search-result').remove() : null;
    }

    if (FORM) {
        this.init();
    }
}
    
ver.2.0.0
HTML
Jade/Pug
JS
Код
      <div class="search">
    <form class="form form-full form-search search__form">
        <div class="form__field form__field-query search__item">
            <input class="form__input" type="text" placeholder="">
        </div>
        <div class="form__action search__actions">
            <button class="form__submit search__submit button button-primary button_size_norma">Поиск</button>
        </div>
    </form>
</div>

    
ver.1.0.0
JS
Как юзать
      new Search({
    clear: true, // true or false
    placeholder: {
        desktop: 'Введите артикул или наименование',
        mobile: 'Поиск',
    },
    inHeader: {
        type: 'short', // 'short' or 'full'
        direction: 'left', // 'left' or 'right
    }
});
    
Код
      window.Search = function(settings) {
    const FORM = document.querySelectorAll('.form-search');
    const SETTINGS = {
      clear: true,
      placeholder: {
        desktop: 'Введите артикул или наименование',
        mobile: 'Поиск',
      },
      inHeader: {
        type: 'full',
        direction: 'right',
      }
    }

    // начало
    this.init = function () {
      if (FORM.length) {
        FORM.forEach(form => {
          if (form) {

            // если поиск находится в шапке сайта
            // if ((typeof settings.inHeader === 'undefined' && SETTINGS.inHeader) || settings.inHeader) {
            //   if (form.closest('.header-desktop, .header-tablet')) {
            //     if ((settings.inHeader && settings.inHeader.type) || SETTINGS.inHeader.type) {
            //       form.classList.add(`search_type_${(settings.inHeader && settings.inHeader.type) || SETTINGS.inHeader.type}`);
            //     }
            //     if ((settings.inHeader && settings.inHeader.direction) || SETTINGS.inHeader.direction) {
            //       form.classList.add(`search_direction_${(settings.inHeader && settings.inHeader.direction) || SETTINGS.inHeader.direction}`);
            //     }
            //   }
            // }

            if ((typeof settings.clear === 'undefined' && SETTINGS.clear) || settings.clear) {
              this.clickOnChangeText(form);
              if (form.querySelector('.form__input').value !== '') {
                this.addButtonClear(form);
              }
            }
            this.setPlaceholder(form);
          }
        });
        window.addEventListener('resize', e => {
          this.handlerResizeWindow();
        }, true);
      }
    }

    // событие на изменение разрешения браузера
    this.handlerResizeWindow = function () {
      FORM.forEach(search => {
        if (search.querySelector('form')) {
          this.setPlaceholder(search);
        }
      });
    }

    // задаем плейсхолдер
    this.setPlaceholder = function (search) {
      let text = search.querySelector('.form__input');
      if (document.body.getBoundingClientRect().width <= 767) {
        if (text.getAttribute('placeholder') !== ((settings.placeholder && settings.placeholder.mobile) || SETTINGS.placeholder.mobile)) {
          text.setAttribute('placeholder', (settings.placeholder && settings.placeholder.mobile) || SETTINGS.placeholder.mobile);
        }
      } else {
        if (text.getAttribute('placeholder') !== ((settings.placeholder && settings.placeholder.desktop) || SETTINGS.placeholder.desktop)) {
          text.setAttribute('placeholder', (settings.placeholder && settings.placeholder.desktop) || SETTINGS.placeholder.desktop);
        }
      }
    }

    // событие при изменении поля
    this.clickOnChangeText = function (form) {
      form.querySelector('.form__input').addEventListener('input', e => {
        if (e.currentTarget.value !== '') {
          this.addButtonClear(form);
        } else {
          this.removeButtonClear(form);
        }
      });
    }

    // добавляем кнопку очистить поле
    this.addButtonClear = function (form) {
      if (!form.querySelector('.form__button-clear')) {
        form.querySelector('.form__field-query').insertAdjacentHTML('beforeend', '<button class="form__button-clear">Очистить</button>');
        form.classList.add('is-button-clear');
        this.clickOnButtonClear(form);
      }
    }

    // удаляем кнопку очистить поле
    this.removeButtonClear = function (search) {
      search.querySelector('.form__button-clear').remove();
      search.classList.remove('is-button-clear');
    }

    // событие клика по кнопке очистить поле
    this.clickOnButtonClear = function (search) {
      search.querySelector('.form__button-clear').addEventListener('click', e => {
        e.preventDefault();
        search.querySelector('.form__input').value = '';
        this.removeClasses(search);
        this.removeResult(search);
        this.removeButtonClear(search);
      });
    }

    // удаление классов
    this.removeClasses = function (search) {
      search.classList.remove('is-results');
      search.classList.remove('is-focus');
      search.classList.remove('is-open');
    }

    // удаляем результаты поиска
    this.removeResult = function (search) {
      search.querySelector('.search-result') ? search.querySelector('.search-result').remove() : null;
    }

    if (FORM) {
      this.init();
    }
}