Searchbar

Searchbar allows user to search through List View elements. Or it can be used as a visual UI component for your custom search realization.

Searchbar Layout

<div class="searchbar-backdrop"></div>
<form class="searchbar">
  <div class="searchbar-inner">
    <div class="searchbar-input-wrap">
      <input type="search" placeholder="Search">
      <i class="searchbar-icon"></i>
      <span class="input-clear-button"></span>
    </div>
    <span class="searchbar-disable-button">Cancel</span>
  </div>
</form>

Where:

  • <div class="searchbar-input-wrap"> - wrapper for search field and clear button
    • <input type="search"> - search field
    • <i class="searchbar-icon"> - search icon
    • <span class="input-clear-button"> - button to clear field value and reset search results. Optional element
  • <span class="searchbar-disable-button"> - Searchbar "Cancel" button that will deactivate Searchbar, reset search results and clear search field. Optional element
  • <div class="searchbar-backdrop"> - semi transparent searchbar backdrop that becomes visible when we enable searchbar. It is recommended to place this element inside of scrollable page's page-content

Searchbar Type

Now let's see where we can place Searchbar in page structure. There are few options:

Fixed Searchbar is always visible on screen not depending on page scroll. In this case it must be placed according to one of the following rules:

  • It can be a direct child of page and if page has also fixed Navbar and/or Toolbar then it must be AFTER Navbar and Toolbar:
    <div class="page">
      <div class="navbar">...</div>
      <div class="toolbar toolbar-bottom">...</div>
      <!-- Searchbar goes after Navbar and Toolbar -->
      <form class="searchbar">...</form>
      <div class="page-content">
        <!-- Searchbar backdrop layer -->
        <div class="searchbar-backdrop"></div>
        <!-- page content here -->
      </div>
    </div>
  • It can be placed inside of Subnavbar which is inside of the Navbar (recommended way):
    <div class="page page-with-subnavbar">
      <div class="navbar">
        <div class="navbar-inner">
          ...
          <div class="subnavbar">
            <!-- Searchbar inside of Subnavbar -->
            <form class="searchbar">...</form>
          </div>
        </div>
      </div>
      <div class="page-content">
        <!-- Searchbar backdrop layer -->
        <div class="searchbar-backdrop"></div>
        <!-- page content here -->
      </div>
    </div>

In this case Searchbar is just part of the scrollable page content:

<div class="page">
  <div class="navbar">...</div>
  <div class="page-content">
    <!-- Searchbar backdrop layer -->
    <div class="searchbar-backdrop"></div>
    <!-- Searchbar is part of scrollable page content -->
    <form class="searchbar">...</form>
    <!-- page content here -->
  </div>
</div>

Expandable Searchbar is hidden when disabled and becomes visible when we enable it. Its layout is pretty strict, it must be placed inside of Navbar:

<div class="page">
  <div class="navbar">
    <div class="navbar-inner">
      <div class="left">...</div>
      <div class="title">...</div>
      <div class="right">
        <!-- Link to enable searchbar -->
        <a class="link icon-only searchbar-enable" data-searchbar=".searchbar">
          <i class="icon f7-icons if-not-md">search</i>
          <i class="icon material-icons md-only">search</i>
        </a>
      </div>
      <!-- Searchbar is a direct child of "navbar-inner" -->
      <form class="searchbar searchbar-expandable">
        <div class="searchbar-inner">
          <div class="searchbar-input-wrap">
            <input type="search" placeholder="Search"/>
            <i class="searchbar-icon"></i>
            <span class="input-clear-button"></span>
          </div>
          <span class="searchbar-disable-button">Cancel</span>
        </div>
      </form>
    </div>
  </div>
  <!-- Scrollable page content -->
  <div class="page-content">...</div>
</div>

Where:

  • <a class="link icon-only searchbar-enable" data-searchbar=".searchbar"> - link to enable/expand Searchbar. Optional or can be placed in any other place. data-searchbar attribute contains CSS selector of Searchbar to enable.
  • Searchbar has additional searchbar-expandable class. It is required for expandable Searchbar to work

Inline Searchbar is designed to be used inside of other components, specifically inside of Appbar. It has simplified layout - without .searchbar-inner, and it is recommended to use it without disable button.

We just need to add searchbar-inline class to Searchbar to make it inline

<!-- Additional "searchbar-inline" class -->
<div class="searchbar searchbar-inline">
  <div class="searchbar-input-wrap">
    <input type="search" placeholder="Search">
    <i class="searchbar-icon"></i>
    <span class="input-clear-button"></span>
  </div>
</div>

Searchbar Behavior Classes

There are also several CSS classes that can be added to elements that will define their behavior when Searchbar is active:

  • searchbar-hide-on-enable - elements with such class on page will be hidden when searchbar is enabled
  • searchbar-hide-on-search - elements with such class on page will be hidden during search
  • searchbar-not-found - elements with such class are hidden by default and become visible when there is not any search results
  • searchbar-found - elements with such class are visible by default and become hidden when there is not any search results
  • searchbar-ignore - searchbar will not consider this elements in search results

For example:

<div class="page">
  <div class="navbar">...</div>
  <div class="page-content">
    <div class="searchbar-backdrop"></div>
    <form class="searchbar">...</form>

    <!-- Following block title and block will be hidden on search -->
    <div class="block-title searchbar-hide-on-search">Some block title</div>
    <div class="block">Lorem ipsum dolor sit amet...</div>

    <!-- We do search in super heroes list so the following title and list must be visible on search -->
    <div class="block-title searchbar-found">Super Heroes</div>
    <div class="list simple-list searchbar-found">
      <ul>
        <li>Hulk</li>
        <li>Batman</li>
        <li>Superman</li>
        ...
      </ul>
    </div>

    <!-- This list will be visible when there is not any search results -->
    <div class="list simple-list searchbar-not-found">
      <ul>
        <li>Nothing found</li>
      </ul>
    </div>
  </div>
</div>

Searchbar App Methods

Now, when we have Searchbar' HTML, we need to initialize it. We need to use related App's method:

app.searchbar.create(parameters)Initialize Searchbar with parameters
  • parameters - object - object with Searchbar parameters
  • Method returns initialized Searchbar instance
app.searchbar.destroy(el)Destroy Searchbar instance
  • el - HTMLElement or string (with CSS Selector) or object. Searchbar element or Searchbar instance to destroy.
app.searchbar.get(el)Get Searchbar instance by HTML element
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance
app.searchbar.clear(el)Clear Searchbar text input
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance
app.searchbar.enable(el)Enable Searchbar
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance
app.searchbar.disable(el)Disable Searchbar
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance
app.searchbar.toggle(el)Toggle Searchbar: enable if it was disabled, or disable if it was enabled
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance
app.searchbar.search(el, query)get Searchbar instance by HTML element
  • el - HTMLElement or string (with CSS Selector). Searchbar element.
  • Method returns Searchbar's instance

Searchbar Parameters

Let's look on list of all available parameters we need to create/init Searchbar:

ParameterTypeDefaultDescription
elstring
HTMLElement
CSS selector or HTML element of searchbar element (form class="searchbar")
inputElstring
HTMLElement
CSS selector or HTML element of searchbar input element. By default (if not passed) will try to look for input type="search" inside of searchbar
disableButtonbooleantrueEnables disable button
disableButtonElstring
HTMLElement
CSS selector or HTML element of searchbar disable button. By default (if not passed) will try to look for element with search-disable-button class inside of searchbar
searchContainerstring
HTMLElement
CSS selector or HTML element of list block to search in
searchInstringCSS selector of List View element's field where we need to search. Usually we search through element titles, in this case we need to pass .item-title. It is also possible to pass few elements for search like .item-title, .item-text
searchItemstringliCSS selector of single search item. If we do a search in List View, then it must be a single list element li
searchGroupstring.list-groupCSS selector of group element. Used when hideGroups enabled to hide groups. If we do a search in List View, then it usually a list group.
searchGroupTitlestring.list-group-title, .item-dividerCSS selector of group titles and dividers. Used when hideDividers enabled to hide group titles and dividers. If we do a search in List View, then it usually a list group title or list item divider.
foundElstring
HTMLElement
.searchbar-foundCSS selector or HTMLElement of searchbar "found" element to make it hidden when there is no search results
notFoundElstring
HTMLElement
.searchbar-not-foundCSS selector or HTMLElement of searchbar "not-found" element to make it visible when there is no search results
hideOnEnableElstring
HTMLElement
.searchbar-hide-on-enableCSS selector or HTMLElement of elements to be hidden when searchbar enabled
hideOnSearchElstring
HTMLElement
.searchbar-hide-on-searchCSS selector or HTMLElement of elements to be hidden on searchbar search
backdropbooleanEnables searchbar backdrop element. By default, disabled for Aurora theme or for inline searchbar
backdropElstring
HTMLElement
CSS selector or HTMLElement of searchbar backdrop element. If not passed and backdrop parameter is true then it will look for .searchbar-backdrop element. In case none found it will create one automatically
ignorestring.searchbar-ignoreCSS selector for items to be ignored by searchbar and always present in search results
customSearchbooleanfalseWhen enabled searchbar will not search through any of list blocks specified by searchContainer and you will be able to use custom search functionality, for example, for calling external APIs with search results and for displaying them manually
removeDiacriticsbooleanfalseEnable to remove/replace diacritics (á, í, ó, etc.) during search
hideDividersbooleantrueIf enabled, then search will consider item dividers and group titles and hide them if there are no found items right after them
hideGroupsbooleantrueIf enabled, then search will consider list view groups hide them if there are no found items inside of these groups
onobjectObject with events handlers. For example:
var searchbar = app.searchbar.create({
  el: '.searchbar',
  on: {
    enable: function () {
      console.log('Searchbar enabled')
    }
  }
})

Searchbar Methods & Properties

To create a Searchbar we have to call:

var searchbar = app.searchbar.create({ /* parameters */ })

After we initialize Searchbar we have its initialized instance in variable (like searchbar variable in example above) with helpful methods and properties:

Properties
searchbar.paramsObject with passed initialization parameters
searchbar.queryCurrent search query (search input value)
searchbar.previousQueryPrevious search query (search input value)
searchbar.searchContainerSearchbar search container
searchbar.$searchContainerDom7 element with searchbar search container
searchbar.elSearchbar HTML element.
searchbar.$elDom7 element with searchbar HTML element.
searchbar.inputElSearchbar input HTML element
searchbar.$inputElDom7 element with searchbar input HTML element
searchbar.enabledBoolean value that represents is searchbar enabled or disabled
searchbar.expandableBoolean value that represents is searchbar expandable or not
Methods
searchbar.search(query);Force searchbar to search passed query
searchbar.enable();Enable/activate searchbar
searchbar.disable();Disable/deactivate searchbar
searchbar.toggle();Toggle searchbar
searchbar.clear();Clear search query and update results
searchbar.destroy();Destroy searchbar instance
searchbar.on(event, handler)Add event handler
searchbar.once(event, handler)Add event handler that will be removed after it was fired
searchbar.off(event, handler)Remove event handler
searchbar.off(event)Remove all handlers for specified event
searchbar.emit(event, ...args)Fire event on instance

Searchbar Events

Searchbar will fire the following DOM events on searchbar element and events on app and searchbar instance:

DOM Events

EventTargetDescription
searchbar:searchSearchbar Element<form class="searchbar">Event will be triggered during search (search field change). Event detail (e.detail) contains search query
searchbar:clearSearchbar Element<form class="searchbar">Event will be triggered when user clicks on Searchbar's "clear" element (a href="#" class="searchbar-clear"). Event detail (e.detail) contains previous (before clear) search query
searchbar:enableSearchbar Element<form class="searchbar">Event will be triggered when Searchbar becomes active/enabled
searchbar:disableSearchbar Element<form class="searchbar">Event will be triggered when Searchbar becomes disabled/inactive - when user clicks on "Cancel" button (a href="searchbar-cancel") or on "searchbar-overlay" element
searchbar:beforedestroySearchbar Element<form class="searchbar">Event will be triggered right before Searchbar instance will be destroyed

App and Searchbar Instance Events

Searchbar instance emits events on both self instance and app instance. App instance events has same names prefixed with searchbar.

EventTargetArgumentsDescription
searchsearchbar(searchbar, query, previousQuery)Event will be triggered during search (search field change). As an argument event handler receives searchbar instance, current query and previous query
searchbarSearchapp
clearsearchbar(searchbar, previousQuery)Event will be triggered when user clicks on Searchbar's "clear" element . As an argument event handler receives searchbar instance and previous (before clear) query
searchbarClearapp
enablesearchbar(searchbar)Event will be triggered when Searchbar becomes active/enabled. As an argument event handler receives searchbar instance
searchbarEnableapp
disablesearchbar(searchbar)Event will be triggered when Searchbar becomes inactive/disabled. As an argument event handler receives searchbar instance
searchbarDisableapp
beforeDestroysearchbar(searchbar)Event will be triggered right before Searchbar instance will be destroyed
searchbarBeforeDestroyapp

Searchbar Auto Initialization

If you don't need to use Searchbar API and your Searchbar is inside of the page and presented in DOM on moment of page initialization then it can be auto initialized with just adding additional searchbar-init class to searchbar element, and all required parameters can be passed using data- attributes:

<div class="page">
  <div class="navbar">...</div>
  <div class="page-content">
    <div class="searchbar-backdrop"></div>

    <!-- Searchbar with "searchbar-init" class for auto initialization and searchContainer, searchIn parameters passed in data- attributes  -->
    <form class="searchbar searchbar-init" data-search-container=".search-here">
      ...
    </form>

    <div class="list simple-list search-list searchbar-found">
      <ul>
        <li>Hulk</li>
        <li>Batman</li>
        <li>Superman</li>
        ...
      </ul>
    </div>

    ...
  </div>
</div>

Parameters that used in camelCase, for example searchContainer, in data- attributes should be used in kebab-case as data-search-container

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

Note that commented variables are not specified by default and their values is what they fallback to in this case.

:root {
  /*
  --f7-searchbar-link-color: var(--f7-bars-link-color);
  */
  --f7-searchbar-input-border-width: 0px;
  --f7-searchbar-input-border-color: transparent;
  --f7-searchbar-input-text-color: #000;
  --f7-searchbar-placeholder-color: #939398;
}
:root .theme-dark,
:root.theme-dark {
  --f7-searchbar-input-text-color: #fff;
}
.ios {
  /*
  --f7-searchbar-bg-image: var(--f7-bars-bg-image);
  --f7-searchbar-bg-color: var(--f7-bars-bg-color);
  --f7-searchbar-border-color: var(--f7-bars-border-color);
  */
  --f7-searchbar-height: 44px;
  --f7-searchbar-inner-padding-left: 8px;
  --f7-searchbar-inner-padding-right: 8px;
  /*
  --f7-searchbar-link-color: var(--f7-bars-link-color, var(--f7-theme-color));
  */
  --f7-searchbar-search-icon-color: #939398;
  --f7-searchbar-input-font-size: 17px;
  --f7-searchbar-input-bg-color: #e8e8ea;
  --f7-searchbar-input-border-radius: 8px;
  --f7-searchbar-input-height: 32px;
  --f7-searchbar-input-padding-horizontal: 28px;
  /*
  --f7-searchbar-inline-input-font-size: var(--f7-searchbar-input-font-size);
  --f7-searchbar-inline-input-height: var(--f7-searchbar-input-height);
  --f7-searchbar-inline-input-padding-horizontal: var(--f7-searchbar-input-padding-horizontal);
  --f7-searchbar-input-clear-button-color: var(--f7-input-clear-button-color);
  */
  --f7-searchbar-backdrop-bg-color: rgba(0, 0, 0, 0.4);
  --f7-searchbar-shadow-image: none;
  --f7-searchbar-in-page-content-margin: 0px;
  --f7-searchbar-in-page-content-box-shadow: none;
  --f7-searchbar-in-page-content-border-radius: 0;
  --f7-searchbar-in-page-content-input-border-radius: 0;
}
.ios .theme-dark,
.ios.theme-dark {
  --f7-searchbar-bg-color: #303030;
  --f7-searchbar-input-bg-color: #171717;
}
.md {
  --f7-searchbar-bg-color: #fff;
  --f7-searchbar-border-color: transparent;
  --f7-searchbar-height: 48px;
  --f7-searchbar-inner-padding-left: 0px;
  --f7-searchbar-inner-padding-right: 0px;
  --f7-searchbar-link-color: #737373;
  --f7-searchbar-search-icon-color: #737373;
  --f7-searchbar-input-font-size: 20px;
  --f7-searchbar-input-bg-color: #fff;
  --f7-searchbar-input-border-radius: 0px;
  --f7-searchbar-input-height: 100%;
  --f7-searchbar-input-padding-horizontal: 48px;
  /*
  --f7-searchbar-inline-input-font-size: var(--f7-searchbar-input-font-size);
  --f7-searchbar-inline-input-height: var(--f7-searchbar-input-height);
  */
  --f7-searchbar-inline-input-padding-horizontal: 24px;
  --f7-searchbar-input-clear-button-color: #737373;
  --f7-searchbar-backdrop-bg-color: rgba(0, 0, 0, 0.25);
  --f7-searchbar-shadow-image: var(--f7-bars-shadow-bottom-image);
  --f7-searchbar-in-page-content-margin: 8px;
  --f7-searchbar-in-page-content-box-shadow: var(--f7-elevation-1);
  --f7-searchbar-in-page-content-border-radius: 4px;
  --f7-searchbar-in-page-content-input-border-radius: 4px;
}
.md .theme-dark,
.md.theme-dark {
  --f7-searchbar-bg-color: #222222;
  --f7-searchbar-input-bg-color: #222222;
}
.aurora {
  /*
  --f7-searchbar-bg-image: var(--f7-bars-bg-image);
  --f7-searchbar-bg-color: var(--f7-bars-bg-color);
  --f7-searchbar-border-color: var(--f7-bars-border-color);
  */
  --f7-searchbar-height: 38px;
  --f7-searchbar-inner-padding-left: 8px;
  --f7-searchbar-inner-padding-right: 8px;
  /*
  --f7-searchbar-link-color: var(--f7-bars-link-color, var(--f7-theme-color));
  */
  --f7-searchbar-search-icon-color: #939398;
  --f7-searchbar-input-font-size: 13px;
  --f7-searchbar-input-bg-color: #fff;
  --f7-searchbar-input-border-radius: 4px;
  --f7-searchbar-input-height: 24px;
  --f7-searchbar-input-padding-horizontal: 24px;
  /*
  --f7-searchbar-inline-input-font-size: var(--f7-searchbar-input-font-size);
  --f7-searchbar-inline-input-height: var(--f7-searchbar-input-height);
  --f7-searchbar-inline-input-padding-horizontal: var(--f7-searchbar-input-padding-horizontal;
  --f7-searchbar-input-clear-button-color: var(--f7-input-clear-button-color);
  */
  --f7-searchbar-backdrop-bg-color: rgba(0, 0, 0, 0.4);
  --f7-searchbar-shadow-image: none;
  --f7-searchbar-in-page-content-margin: 0px;
  --f7-searchbar-in-page-content-box-shadow: none;
  --f7-searchbar-in-page-content-border-radius: 0;
  /*
  --f7-searchbar-in-page-content-input-border-radius: var(--f7-searchbar-input-border-radius);
  */
}
.aurora .theme-dark,
.aurora.theme-dark {
  --f7-searchbar-input-bg-color: #333;
}

Example

<div class="page">
  <div class="navbar">
    <div class="navbar-inner">
      <div class="title">Search Bar</div>
      <div class="subnavbar">
        <!-- Searchbar with auto init -->
        <form class="searchbar">
          <div class="searchbar-inner">
            <div class="searchbar-input-wrap">
              <input type="search" placeholder="Search">
              <i class="searchbar-icon"></i>
              <span class="input-clear-button"></span>
            </div>
            <span class="searchbar-disable-button if-not-aurora">Cancel</span>
          </div>
        </form>
      </div>
    </div>
  </div>
  <div class="page-content">
    <!-- Searchbar backdrop -->
    <div class="searchbar-backdrop"></div>
    <!-- hide-on-search element -->
    <div class="block searchbar-hide-on-search">
      <p>This block will be hidden on search. Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
    <!-- search target list -->
    <div class="list searchbar-found">
      <ul>
        <li class="item-content">
          <div class="item-inner">
            <div class="item-title">Acura</div>
          </div>
        </li>
        <li class="item-content">
          <div class="item-inner">
            <div class="item-title">Audi</div>
          </div>
        </li>
        <li class="item-content">
          <div class="item-inner">
            <div class="item-title">BMW</div>
          </div>
        </li>
        ...
        <li class="item-content">
          <div class="item-inner">
            <div class="item-title">Volvo</div>
          </div>
        </li>
      </ul>
    </div>
    <!-- Nothing found message -->
    <div class="block searchbar-not-found">
      <div class="block-inner">Nothing found</div>
    </div>
  </div>
</div>
var app = new Framework7();

// create searchbar
var searchbar = app.searchbar.create({
  el: '.searchbar',
  searchContainer: '.list',
  searchIn: '.item-title',
  on: {
    search(sb, query, previousQuery) {
      console.log(query, previousQuery);
    }
  }
});