# Documentation v8.0.38

Preview Downloads Purchase

# Overview

Quick Search is an exclusive advanced component of Metronic that provides a flexible and powerful UI component to manage and handle layouts related to search. Quick Search also comes with multiple custom hook points to allow advanced users to bind custom JS or search logic to control and manipulate our Quick Search component.
The Quick Search component is a frontend only solution that manages element display orders and event triggers to show/hide certain layers. However, the search logic backend functionality is not included.

# Usage

Quick Search hooks are globally included in our scripts bundle, however, initialization is manually controlled and is required to be included.

    <link href="assets/css/style.bundle.css" rel="stylesheet" type="text/css"/>
    <script src="assets/js/scripts.bundle.js"></script>

# Initialization

- The Quick Search component is a highly robust and flexible frontend solution that comes with number of HTML elements to provide a rapid search layout. Quick Search starts with a simple `div`element that houses a number of HTML attributes to control and configure the Quick Search component. See below for more info.
- Quick Search structure comes in a few layers.
  - Main Wrapper
  - Toggle Button
  - Main Content Element
  - Main Content Inner Wrapper
  - Input Form
  - Search Suggestion
  - Search Preference
  - Search Advanced Options
  - Search Results
  - Empty Search
- Each search UI HTML element within the main wrapper can be identified by the `data-kt-search-element`HTML attribute with a specific value. For example, `data-kt-search-element="toggle"`indicates that the current HTML element is a Toggle Button. See below for more info.
- Quick Search uses our extended Bootstrap's utility classes for styling.
- Quick Search instances can also be controlled programmatically. See below for more info.

# Basic Layout

Here's a basic example of our Quick Search.
In this demo, we're simulating the search results by randomly showing and hiding the search results layer on keypress within the input field.
Emma Smith Art Director
M
Melody Macy Marketing Analytic
Max Smith Software Enginer
Sean Bean Web Developer
Brian Cox UI/UX Designer
C
Mikaela Collins Head Of Marketing
Francis Mitcham Software Arcitect
O
Olivia Wild System Admin
N
Neil Owen Account Manager
Dan Wilson Web Desinger
No users found
Try to search by username, full name or email...

    var processs = function(search) {
        var timeout = setTimeout(function() {
            var number = KTUtil.getRandomInt(1, 6);

            // Hide recently viewed
            suggestionsElement.classList.add("d-none");

            if (number === 3) {
                // Hide results
                resultsElement.classList.add("d-none");
                // Show empty message
                emptyElement.classList.remove("d-none");
            } else {
                // Show results
                resultsElement.classList.remove("d-none");
                // Hide empty message
                emptyElement.classList.add("d-none");
            }

            // Complete search
            search.complete();
        }, 1500);
    }

    var clear = function(search) {
        // Show recently viewed
        suggestionsElement.classList.remove("d-none");
        // Hide results
        resultsElement.classList.add("d-none");
        // Hide empty message
        emptyElement.classList.add("d-none");
    }

    // Input handler
    const handleInput = () => {
        // Select input field
        const inputField = element.querySelector("[data-kt-search-element="input"]");

        // Handle keyboard press event
        inputField.addEventListener("keydown", e => {
            // Only apply action to Enter key press
            if(e.key === "Enter"){
                e.preventDefault(); // Stop form from submitting
            }
        });
    }

    // Elements
    element = document.querySelector('#kt_docs_search_handler_basic');

    if (!element) {
        return;
    }

    wrapperElement = element.querySelector("[data-kt-search-element="wrapper"]");
    suggestionsElement = element.querySelector("[data-kt-search-element="suggestions"]");
    resultsElement = element.querySelector("[data-kt-search-element="results"]");
    emptyElement = element.querySelector("[data-kt-search-element="empty"]");

    // Initialize search handler
    searchObject = new KTSearch(element);

    // Search handler
    searchObject.on("kt.search.process", processs);

    // Clear handler
    searchObject.on("kt.search.clear", clear);

    // Handle select
    KTUtil.on(element, "[data-kt-search-element="customer"]", "click", function() {
        //modal.hide();
    });

    // Handle input enter keypress
    handleInput();

    <!--begin::Main wrapper-->
    <div
        id="kt_docs_search_handler_basic"

        data-kt-search-keypress="true"
        data-kt-search-min-length="2"
        data-kt-search-enter="true"
        data-kt-search-layout="inline">

        <!--begin::Input Form-->
        <form data-kt-search-element="form" class="w-100 position-relative mb-5" autocomplete="off">
            <!--begin::Hidden input(Added to disable form autocomplete)-->
            <input type="hidden"/>
            <!--end::Hidden input-->

            <!--begin::Icon-->
                <!--begin::Svg Icon | path: icons/duotune/general/gen021.svg-->
            <!--end::Icon-->

            <!--begin::Input-->
            <input type="text" class="form-control form-control-lg form-control-solid px-15"
                name="search"
                value=""
                placeholder="Search by username, full name or email..."
                data-kt-search-element="input"/>
            <!--end::Input-->

            <!--begin::Spinner-->
            <span class="position-absolute top-50 end-0 translate-middle-y lh-0 d-none me-5" data-kt-search-element="spinner">
                <span class="spinner-border h-15px w-15px align-middle text-gray-400"></span>
            </span>
            <!--end::Spinner-->

            <!--begin::Reset-->
            <span class="btn btn-flush btn-active-color-primary position-absolute top-50 end-0 translate-middle-y lh-0 me-5 d-none"
                data-kt-search-element="clear">

                <!--begin::Svg Icon | path: icons/duotune/arrows/arr061.svg-->
            </span>
            <!--end::Reset-->
        </form>
        <!--end::Form-->

        <!--begin::Wrapper-->
        <div class="py-5">
            <!--being::Search suggestion-->
            <div data-kt-search-element="suggestions">
                ...
            </div>
            <!--end::Suggestion wrapper-->

            <!--begin::Search results-->
            <div data-kt-search-element="results" class="d-none">
                ...
            </div>
            <!--end::Search results-->

            <!--begin::Empty search-->
            <div data-kt-search-element="empty" class="text-center d-none">
                ...
            </div>
            <!--end::Empty search-->
        </div>
        <!--end::Wrapper-->
    </div>
    <!--end::Main wrapper-->

# Menu Layout

This demo combines the Quick Search component with our menu component for unique interactive dropdown search UI component.
In this demo, we're simulating the search results by randomly showing and hiding the search results layer on keypress within the input field.

    var processs = function(search) {
        var timeout = setTimeout(function() {
            var number = KTUtil.getRandomInt(1, 3);

            // Hide recently viewed
            mainElement.classList.add("d-none");

            if (number === 3) {
                // Hide results
                resultsElement.classList.add("d-none");
                // Show empty message
                emptyElement.classList.remove("d-none");
            } else {
                // Show results
                resultsElement.classList.remove("d-none");
                // Hide empty message
                emptyElement.classList.add("d-none");
            }

            // Complete search
            search.complete();
        }, 1500);
    }

    var clear = function(search) {
        // Show recently viewed
        mainElement.classList.remove("d-none");
        // Hide results
        resultsElement.classList.add("d-none");
        // Hide empty message
        emptyElement.classList.add("d-none");
    }

    var handlePreferences = function() {
        // Preference show handler
        preferencesShowElement.addEventListener("click", function() {
            wrapperElement.classList.add("d-none");
            preferencesElement.classList.remove("d-none");
        });

        // Preference dismiss handler
        preferencesDismissElement.addEventListener("click", function() {
            wrapperElement.classList.remove("d-none");
            preferencesElement.classList.add("d-none");
        });
    }

    var handleAdvancedOptionsForm = function() {
        // Show
        advancedOptionsFormShowElement.addEventListener("click", function() {
            wrapperElement.classList.add("d-none");
            advancedOptionsFormElement.classList.remove("d-none");
        });

        // Cancel
        advancedOptionsFormCancelElement.addEventListener("click", function() {
            wrapperElement.classList.remove("d-none");
            advancedOptionsFormElement.classList.add("d-none");
        });

        // Search
        advancedOptionsFormSearchElement.addEventListener("click", function() {

        });
    }

    // Elements
    element = document.querySelector("#kt_docs_search_handler_menu");

    if (!element) {
        return;
    }

    wrapperElement = element.querySelector("[data-kt-search-element="wrapper"]");
    formElement = element.querySelector("[data-kt-search-element="form"]");
    mainElement = element.querySelector("[data-kt-search-element="main"]");
    resultsElement = element.querySelector("[data-kt-search-element="results"]");
    emptyElement = element.querySelector("[data-kt-search-element="empty"]");

    preferencesElement = element.querySelector("[data-kt-search-element="preferences"]");
    preferencesShowElement = element.querySelector("[data-kt-search-element="preferences-show"]");
    preferencesDismissElement = element.querySelector("[data-kt-search-element="preferences-dismiss"]");

    advancedOptionsFormElement = element.querySelector("[data-kt-search-element="advanced-options-form"]");
    advancedOptionsFormShowElement = element.querySelector("[data-kt-search-element="advanced-options-form-show"]");
    advancedOptionsFormCancelElement = element.querySelector("[data-kt-search-element="advanced-options-form-cancel"]");
    advancedOptionsFormSearchElement = element.querySelector("[data-kt-search-element="advanced-options-form-search"]");

    // Initialize search handler
    searchObject = new KTSearch(element);

    // Search handler
    searchObject.on("kt.search.process", processs);

    // Clear handler
    searchObject.on("kt.search.clear", clear);

    // Custom handlers
    handlePreferences();
    handleAdvancedOptionsForm();

    <!--begin::Main wrapper-->
    <div id="kt_docs_search_handler_menu"
        class="d-flex align-items-stretch"

        data-kt-search-keypress="true"
        data-kt-search-min-length="2"
        data-kt-search-enter="true"
        data-kt-search-layout="menu"

        data-kt-menu-trigger="auto"
        data-kt-menu-overflow="false"
        data-kt-menu-permanent="true"
        data-kt-menu-placement="bottom-start">

        <!--begin::Search toggle-->
        <div class="d-flex align-items-center" data-kt-search-element="toggle" id="kt_header_search_toggle">
            <div class="btn btn-primary">
                Toggle Quick Search
            </div>
        </div>
        <!--end::Search toggle-->

        <!--begin::Menu-->
        <div data-kt-search-element="content" class="menu menu-sub menu-sub-dropdown p-7 w-325px w-md-375px">
            <!--begin::Wrapper-->
            <div data-kt-search-element="wrapper">
            <!--begin::Form-->
                <form data-kt-search-element="form" class="w-100 position-relative mb-3" autocomplete="off">
                    <!--begin::Icon-->
                        <!--begin::Svg Icon | path: icons/duotune/general/gen021.svg-->
                    <!--end::Icon-->

                    <!--begin::Input-->
                    <input type="text"
                        class="form-control form-control-flush ps-10"
                        name="search"
                        value=""
                        placeholder="Search..."
                        data-kt-search-element="input"/>
                    <!--end::Input-->

                    <!--begin::Spinner-->
                    <span class="position-absolute top-50 end-0 translate-middle-y lh-0 d-none me-1"
                        data-kt-search-element="spinner">
                        <span class="spinner-border h-15px w-15px align-middle text-gray-400"></span>
                    </span>
                    <!--end::Spinner-->

                    <!--begin::Reset-->
                    <span class="btn btn-flush btn-active-color-primary position-absolute top-50 end-0 translate-middle-y lh-0 d-none"
                        data-kt-search-element="clear">
                        <!--begin::Svg Icon | path: icons/duotune/arrows/arr061.svg-->
                    </span>
                    <!--end::Reset-->

                    <!--begin::Toolbar-->
                    <div class="position-absolute top-50 end-0 translate-middle-y" data-kt-search-element="toolbar">
                        <!--begin::Preferences toggle-->
                        <div data-kt-search-element="preferences-show"
                            class="btn btn-icon w-20px btn-sm btn-active-color-primary me-1"
                            data-bs-toggle="tooltip"
                            title="Show search preferences">
                            <!--begin::Svg Icon | path: icons/duotune/coding/cod001.svg-->
                        </div>
                        <!--end::Preferences toggle-->

                        <!--begin::Advanced search toggle-->
                        <div data-kt-search-element="advanced-options-form-show"
                            class="btn btn-icon w-20px btn-sm btn-active-color-primary"
                            data-bs-toggle="tooltip"
                            title="Show more search options">
                            <!--begin::Svg Icon | path: icons/duotune/arrows/arr072.svg-->
                        </div>
                        <!--end::Advanced search toggle-->
                    </div>
                    <!--end::Toolbar-->
                </form>
                <!--end::Form-->

                <!--begin::Search results-->
                <div data-kt-search-element="results" class="d-none">
                    ...
                </div>
                <!--end::Search results-->

                <!--begin::Main content element-->
                <div data-kt-search-element="main">
                    ...
                </div>
                <!--end::Main content element-->

                <!--begin::Empty search-->
                <div data-kt-search-element="empty" class="text-center d-none">
                    ...
                </div>
                <!--end::Empty search-->
            </div>
            <!--end::Wrapper-->

            <!--begin::Search Advanced Options-->
            <div data-kt-search-element="advanced-options-form">
                ...
            </div>
            <!--end::Search Advanced Options-->

            <!--begin::Search Preference-->
            <div data-kt-search-element="preferences">
                ...
            </div>
            <!--end::Search Preference-->
        </div>
        <!--end::Menu-->
    </div>
    <!--end::Main wrapper-->

# Responsive Layout

This demo showcases Search UI's responsive solution. It displays as a full inline input field on large screens, and converts into an icon toggle button on smaller screens.
In this demo, we're simulating the search results by randomly showing and hiding the search results layer on keypress within the input field.

    var processs = function(search) {
        var timeout = setTimeout(function() {
            var number = KTUtil.getRandomInt(1, 3);

            // Hide recently viewed
            recentlyViewedElement.classList.add("d-none");

            if (number === 3) {
                // Hide results
                resultsElement.classList.add("d-none");
                // Show empty message
                emptyElement.classList.remove("d-none");
            } else {
                // Show results
                resultsElement.classList.remove("d-none");
                // Hide empty message
                emptyElement.classList.add("d-none");
            }

            // Complete search
            search.complete();
        }, 1500);
    }

    var clear = function(search) {
        // Show recently viewed
        recentlyViewedElement.classList.remove("d-none");
        // Hide results
        resultsElement.classList.add("d-none");
        // Hide empty message
        emptyElement.classList.add("d-none");
    }

    // Elements
    element = document.querySelector("#kt_docs_search_handler_responsive");

    if (!element) {
        return;
    }

    wrapperElement = element.querySelector("[data-kt-search-element="wrapper"]");
    recentlyViewedElement = element.querySelector("[data-kt-search-element="recently-viewed"]");
    resultsElement = element.querySelector("[data-kt-search-element="results"]");
    emptyElement = element.querySelector("[data-kt-search-element="empty"]");
    preferencesElement = element.querySelector("[data-kt-search-element="preferences"]");
    preferencesShowElement = element.querySelector("[data-kt-search-element="preferences-show"]");
    preferencesDismissElement = element.querySelector("[data-kt-search-element="preferences-dismiss"]");

    // Initialize search handler
    searchObject = new KTSearch(element);

    // Search handler
    searchObject.on("kt.search.process", processs);

    // Clear handler
    searchObject.on("kt.search.clear", clear);

    // Preference show handler
    preferencesShowElement.addEventListener("click", function() {
        wrapperElement.classList.add("d-none");
        preferencesElement.classList.remove("d-none");
    });

    // Preference dismiss handler
    preferencesDismissElement.addEventListener("click", function() {
        wrapperElement.classList.remove("d-none");
        preferencesElement.classList.add("d-none");
    });
    }

    <!--begin::Main wrapper-->
    <div
        id="kt_docs_search_handler_responsive"
        class="d-flex align-items-center w-lg-400px"

        data-kt-search-keypress="true"
        data-kt-search-min-length="2"
        data-kt-search-enter="enter"
        data-kt-search-layout="menu"
        data-kt-search-responsive="lg"

        data-kt-menu-trigger="auto"
        data-kt-menu-permanent="true"
        data-kt-menu-placement="bottom-start">

        <!--begin::Tablet and mobile search toggle-->
        <div data-kt-search-element="toggle" class="d-flex d-lg-none align-items-center">
            <div class="btn btn-icon btn-active-light-primary">
                <?php echo Theme::getSvgIcon("icons/duotune/general/gen021.svg", "svg-icon-1")?>
            </div>
        </div>
        <!--end::Tablet and mobile search toggle-->

        <!--begin::Form-->
        <form data-kt-search-element="form" class="d-none d-lg-block w-100 position-relative mb-5 mb-lg-0" autocomplete="off">
            <!--begin::Hidden input(Added to disable form autocomplete)-->
            <input type="hidden"/>
            <!--end::Hidden input-->

            <!--begin::Icon-->
            <?php echo Theme::getSvgIcon("icons/duotune/general/gen021.svg", "svg-icon-2 svg-icon-lg-1 svg-icon-gray-500 position-absolute top-50 translate-middle-y ms-5")?>
            <!--end::Icon-->

            <!--begin::Input-->
            <input type="text" class="form-control form-control-solid ps-14" name="search" value="" placeholder="Search..." data-kt-search-element="input"/>
            <!--end::Input-->

            <!--begin::Spinner-->
            <span class="position-absolute top-50 end-0 translate-middle-y lh-0 d-none me-6" data-kt-search-element="spinner">
                <span class="spinner-border h-15px w-15px align-middle text-gray-400"></span>
            </span>
            <!--end::Spinner-->

            <!--begin::Reset-->
            <span class="btn btn-flush btn-active-color-primary position-absolute top-50 end-0 translate-middle-y lh-0 me-5 d-none" data-kt-search-element="clear">
                <?php echo Theme::getSvgIcon("icons/duotune/arrows/arr061.svg", "svg-icon-2 svg-icon-lg-1 me-0")?>
            </span>
            <!--end::Reset-->
        </form>
        <!--end::Form-->

        <!--begin::Menu-->
        <div data-kt-search-element="content" class="menu menu-sub menu-sub-dropdown w-300px w-md-400px py-7 px-7 overflow-hidden">
            <!--begin::Wrapper-->
            <div data-kt-search-element="wrapper">
                <!--begin::Categories-->
                <div data-kt-search-element="categories">
                    ...
                </div>
                <!--end::Categories-->

                <!--begin::Search results-->
                <div data-kt-search-element="results" class="d-none">
                    ...
                </div>
                <!--end::Search results-->

                <!--begin::Recently viewed-->
                <div data-kt-search-element="recently-viewed">
                    ...
                </div>
                <!--end::Recently viewed-->

                <!--begin::Empty search-->
                <div data-kt-search-element="empty" class="text-center d-none">
                    ...
                </div>
                <!--end::Empty search-->
            </div>
            <!--end::Wrapper-->

            <!--begin::Preferences-->
            <div data-kt-search-element="preferences"
                ...
            </div>
            <!--end::Preferences-->
        </div>
        <!--end::Menu-->
    </div>
    <!--end::Main wrapper-->

# Markup Reference

Main wrapper HTML Attribute references
Quick Search uses HTML attributes within the Main Wrapper to configure the frontend logic. Here are the references for each below

Name | Type | Description
--- | --- | ---
`data-kt-search-keypress` | `optional` | Enable search on any keyboard keypress. Accepts `true`or `false`values.
`data-kt-search-enter` | `optional` | Enable search on any keyboard `Enter`keypress. Accepts `true`or `false`values.
`data-kt-search-responsive` | `optional` | Defines the responsive mode for the input field's position. Useful for an inline input field to display itself within a dropdown menu on mobile to save space. Accepts `sm, md, lg, xl`and `null`values. For example: `data-kt-search-responsive="lg"`indicates that the Quick Search component input field will be displayed inline with the parent container from `lg`screen sizes and above, and hidden (re-positioned into the dropdown menu) on smaller screens.
`data-kt-search-min-length` | `optional` | Defines the number of characters required before the search event is triggered. Accepts `numeric`values.
`data-kt-search-layout` | `optional` | Defines Quick Search's layout type. Accepts `inline`and `menu`values.
`data-kt-search-show-on-focus` | `optional` | Enables menu dropdown to show when the input field detects a focus event. Accepts `true`or `false`values.

HTML Attribute Identifiers references
Quick Search also use HTML attributes to identify the HTML elements that are used within the Main Wrapper. Here are the references for each below

Name | Type | Description
--- | --- | ---
`data-kt-search-element` | `mandatory` | Identifies the HTML element as a specific Quick Search element. All Quick Search elements must be added within the Main Wrapper. The main wrapper does not have a specific attribute to identify it. It's simply a wrapping `div`element that wraps all Quick Search inner elements. Here are the list of Quick Search elements available: `form` `input` `spinner` `clear` `toggle` `content` `toolbar` `empty` `results` `suggestions`
    <div>
        <div data-kt-search-element="form">
            ...
            <input data-kt-search-element="input" />
            ...
        </div>
    </div>

# Methods

The following are Search UI's functionality methods for more control.

Name | Description
--- | ---
Static Methods
`getInstance(DOMElement element)` | Get the Search UI instance that has been created and returns the Search UI DOM element.
    var searchElement = document.querySelector("#kt_search_example_1");
    var search = KTSearch.getInstance(searchElement);
Public Methods
`new KTSearch(DOMElement element)` | Initialize a new Quick Search control.
    var searchElement = document.querySelector("#kt_search_control");
    var search = new KTSearch(searchElement);
`show` | Triggers the menu to show. Only applicable when `data-kt-search-layout`is set to `menu`
    search.show();
`hide` | Triggers the menu to hide. Only applicable when `data-kt-search-layout`is set to `menu`
    search.hide();
`update` | Updates the menu responsiveness. Only applicable when `data-kt-search-layout`is set to `menu`
    search.update();
`search` | Triggers the search event to begin searching.
    search.search();
`complete` | Triggers the completed search event.
    search.complete();
`clear` | Clears the search input field and resets the Search UI.
    search.clear();
`isProcessing` | Returns `true`or `false`to indicate if there's a search event still running.
    search.isProcessing();
`getQuery` | Returns the Search UI input string.
    search.getQuery();
`getMenu` | Returns the Search UI menu element. Only applicable when `data-kt-search-layout`is set to `menu`
    search.getMenu();
`getFormElement` | Returns the Search UI form element.
    search.getFormElement();
`getInputElement` | Returns the Search UI input field element.
    search.getInputElement();
`getContentElement` | Returns the Search UI content element.
    search.getContentElement();
`getElement` | Returns the Search UI element.
    search.getElement();

# Events

Below are few events for hooking into Quick Search's functionality.

Event Type | Description
--- | ---
`kt.search.process` | This event fires when search begins processing.
    var searchElement = document.querySelector("#kt_search_example_1");
    var search = KTSearch.getInstance(searchElement);
    search.on("kt.search.process", function() {
        // console.log("kt.search.process event is fired");
    });
`kt.search.clear` | This event fires when search input field is about to be cleared.
    var searchElement = document.querySelector("#kt_search_example_1");
    var search = KTSearch.getInstance(searchElement);
    search.on("kt.search.clear", function() {
        // console.log("kt.search.clear event is fired");
    });
`kt.search.cleared` | This event fires when search input field has been cleared.
    var searchElement = document.querySelector("#kt_search_example_1");
    var search = KTSearch.getInstance(searchElement);
    search.on("kt.search.cleared", function() {
        // console.log("kt.search.cleared event is fired");
    });

### Explore

### Metronic Licenses

License FAQs
Regular License
For single end product used by you or one client
$ 39
Extended License
For single SaaS app with paying users
$ 969
Custom License
Reach us for custom license offers.
Contact Us
Buy Now

### Metronic Demos

Demo 1
Demo 2
Demo 3
Demo 4
Demo 5
Demo 6
Demo 7
Demo 8
Demo 9
Demo 10
Demo 11
Demo 12
Demo 13
Demo 14
Demo 15
Demo 16
Demo 17
Demo 18
Demo 19
Demo 20
Demo 21
Demo 22
Coming soon
Coming soon

##### Learn & Get Inspired

## Support at devs.keenthemes.com

Join our developers community to find answer to your question and help others. FAQs
Get Support
Documentation & Videos
From guides and video tutorials, to live demos and code examples to get started.
Plugins & Components
Check out our 300+ in-house components and customized 3rd-party plugins.
Layout Builder
Build your layout, preview it and export the HTML for server side integration.
Metronic Downloads
Download your prefered framework and demo with one click.
What's New
Latest features and improvements added with our users feedback in mind.
Buy now