Autocomplete

    Framework7 comes with mobile-friendly and touch optimized Autocomplete component.

    Autocomplete could be used in standalone mode or as a dropdown.

    Autocomplete App Methods

    Autocomplete can be created and initialized only using JavaScript. We need to use related App's method:

    app.autocomplete.create(parameters)- create Autocomplete instance

    • parameters - object. Object with autocomplete parameters

    Method returns created Autocomplete's instance

    app.autocomplete.destroy(el)- destroy Autocomplete instance

    • el - HTMLElement or string (with CSS Selector) or object. Autocomplete instance to destroy.

    app.autocomplete.get(el)- get Autocomplete instance by HTML element

    • el - HTMLElement or string (with CSS Selector). Autocomplete element.

    Method returns Autocomplete's instance

    app.autocomplete.open(el)- open Autocomplete

    • el - HTMLElement or string (with CSS Selector). Autocomplete element to open.

    Method returns Autocomplete's instance

    app.autocomplete.close(el)- closes Autocomplete

    • el - HTMLElement or string (with CSS Selector). Autocomplete element to close.

    Method returns Autocomplete's instance

    For example:

    var autocomplete = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown',
      openIn: 'dropdown',
      source: function (query, render) {
        ...
      }
    });

    Autocomplete Parameters

    Let's look on list of all available parameters:

    Parameter Type Default Description
    openIn string page Defines how to open Autocomplete, can be page or popup (for Standalone) or dropdown
    source function (query, render) Function which accepts search query and render function where you need to pass array with matched items
    limit number Limit number of maximum displayed items in autocomplete per query
    preloader boolean false Set to true to include Preloader to autocomplete layout
    preloaderColor string Preloader color, one of the default colors
    value array Array with default selected values
    valueProperty string id Name of matched item object's key that represents item value
    textProperty string text Name of matched item object's key that represents item display value which is used as title of displayed options
    Standalone Autocomplete Parameters
    requestSourceOnOpen boolean false If enabled, then it will request passed to source function on autocomplete open
    openerEl string
    HTMLElement
    String with CSS selector or HTMLElement of link which will open standalone autocomplete page or popup on click
    popupCloseLinkText string Close Default text for "Close" button when opened as Popup
    pageBackLinkText string Back Default text for "Back" link when opened as Page
    pageTitle string Autocomplete page title. If nothing is specified and passed openerEl is an item of List View, then text value of item-title element will be used
    searchbarPlaceholder string Search... Searchbar placeholder text
    searchbarDisableText string Cancel Searchbar "Cancel" button text
    notFoundText string Nothing found Text which is displayed when no matches found
    multiple boolean false Set to true to allow multiple selections
    closeOnSelect boolean false Set to true and autocomplete will be closed when user picks value. Not available if multiple is enabled
    autoFocus boolean false Set to true to auto focus search field on autocomplete open
    animate boolean true Set to false to open standalone autocomplete without animation
    navbarColorTheme string Navbar color theme. One of the default color themes
    formColorTheme string Form (checkboxes or radios) color theme. One of the default color themes
    routableModals boolean true Will add opened autocomplete modal (when openIn: 'popup') to router history which gives ability to close autocomplete by going back in router history and set current route to the autocomplete modal
    url string select/ Standalone autocomplete URL that will be set as a current route
    view object Link to initialized View instance if you want use standalone Autcomplete. By default, if not specified, it will be opened in Main View.
    Dropdown Autocomplete Parameters
    inputEl string
    HTMLElement
    String with CSS selector or HTMLElement of related text input
    inputEvents string input Allows to configure input events used to handle Autcomplete actions and source request. Can be changed for example to change keyup compositionend if you use keyboard with composition of Chinese characters
    highlightMatches boolean true Highlight matches in autcomplete results
    typeahead boolean false Enables type ahead, will prefill input value with first item in match
    dropdownPlaceholderText string Specify dropdown placeholder text
    updateInputValueOnSelect boolean true If true then value of related input will be update as well
    expandInput boolean false If true then input which is used as item-input in List View will be expanded to full screen wide during dropdown visible.
    dropdownContainerEl string
    HTMLElement
    By default dropdown will be added to parent page-content element. You can specify here different element where to add dropdown element
    Render functions
    renderDropdown function(items) Function to render autocomplete dropdown, must return dropdown HTML string
    renderPage function(items) Function to render autocomplete page, must return page HTML string
    renderPopup function(items) Function to render autocomplete popup, must return popup HTML string
    renderItem function(item, index) Function to render single autocomplete, must return item HTML string
    renderSearchbar function Function to render searchbar, must return searchbar HTML string
    renderNavbar function Function to render navbar, must return navbar HTML string
    Events
    on object Object with events handlers. For example:
    var autocomplete = app.autocomplete.create({
      ...
      on: {
        opened: function () {
          console.log('Autocomplete opened')
        }
      }
    })

    Note that all following parameters can be used in global app parameters under autocomplete property to set defaults for all autcompletes. For example:

    var app = new Framework7({
      autocomplete: {
        openIn: 'popup',
        animate: false,
      }
    });

    Autocomplete Methods & Properties

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

    Properties
    autocomplete.params Object with passed initialization parameters
    autocomplete.value Array with selected items
    autocomplete.opened true if Autocomplete is currently opened
    autocomplete.openerEl HTML element of Autcomplete opener element (if passed on init)
    autocomplete.$openerEl Dom7 instance of of Autcomplete opener element (if passed on init)
    autocomplete.inputEl HTML element of Autcomplete input (if passed on init)
    autocomplete.$inputEl Dom7 instance of of Autcomplete input (if passed on init)
    autocomplete.$dropdownEl Dom7 instance of Autcomplete dropdown
    autocomplete.url Autcomplete URL (that was passed in url parameter)
    autocomplete.view Autcomplete View (that was passed in view parameter) or found parent view
    autocomplete.el HTML element of Autcomplete container: dropdown element, or popup element, or page element. Available when Autocomplete opened
    autocomplete.$el Dom7 instance of Autcomplete container: dropdown element, or popup element, or page element. Available when Autocomplete opened
    autocomplete.searchbar Autcomplete page Searchbar instance
    Methods
    autocomplete.open() Open Autocomplete (Dropdown, Page or Popup)
    autocomplete.close() Close Autcomplete
    autocomplete.preloaderShow() Show autocomplete preloader
    autocomplete.preloaderHide() Hide autocomplete preloader
    autocomplete.destroy() Destroy Autocomplete instance and remove all events
    autocomplete.on(event, handler) Add event handler
    autocomplete.once(event, handler) Add event handler that will be removed after it was fired
    autocomplete.off(event, handler) Remove event handler
    autocomplete.off(event) Remove all handlers for specified event
    autocomplete.emit(event, ...args) Fire event on instance

    Autocomplete Events

    Autocomplete instance emits events on both self instance and app instance. App instance events has same names prefixed with autocomplete.

    Event Target Arguments Description
    change autocomplete autocomplete, value Event will be triggered when Autocomplete value changed. Returned value is an array with selected items
    autocompleteChange app
    open autocomplete autocomplete Event will be triggered when Autocomplete starts its opening animation. As an argument event handler receives autocomplete instance
    autocompleteOpen app
    opened autocomplete autocomplete Event will be triggered after Autocomplete completes its opening animation. As an argument event handler receives autocomplete instance
    autocompleteOpened app
    close autocomplete autocomplete Event will be triggered when Autocomplete starts its closing animation. As an argument event handler receives autocomplete instance
    autocompleteClose app
    closed autocomplete autocomplete Event will be triggered after Autocomplete completes its closing animation. As an argument event handler receives autocomplete instance
    autocompleteClosed app
    beforeDestroy autocomplete autocomplete Event will be triggered right before Autocomplete instance will be destroyed. As an argument event handler receives autocomplete instance
    autocompleteBeforeDestroy app

    Examples

    var app = new Framework7();
    
    var $$ = Dom7;
    
    // Fruits data demo array
    var fruits = ('Apple Apricot Avocado Banana Melon Orange Peach Pear Pineapple').split(' ');

    Simple Dropdown Autocomplete

    <div class="list no-hairlines-md">
      <div class="block-header">Simple Dropdown Autocomplete</div>
      <ul>
        <li class="item-content item-input inline-label">
          <div class="item-inner">
            <div class="item-title item-label">Fruit</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown" type="text" placeholder="Fruit">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownSimple = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown',
      openIn: 'dropdown',
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    });
    

    Dropdown With Input Expand

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With Input Expand</div>
      <ul>
        <li class="item-content item-input inline-label">
          <div class="item-inner">
            <div class="item-title item-label">Fruit</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-expand" type="text" placeholder="Fruit">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownExpand = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-expand',
      openIn: 'dropdown',
      expandInput: true, // expand input
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    });
    

    Dropdown With All Values

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With All Values</div>
      <ul>
        <li class="item-content item-input">
          <div class="item-inner">
            <div class="item-title item-label">Fruit</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-all" type="text" placeholder="Fruit">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownAll = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-all',
      openIn: 'dropdown',
      source: function (query, render) {
        var results = [];
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    });

    Dropdown With Placeholder

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With Placeholder</div>
      <ul>
        <li class="item-content item-input">
          <div class="item-inner">
            <div class="item-title item-label">Fruit</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-placeholder" type="text" placeholder="Fruit">
            </div>
          </div>
        </li>
      </ul>
    </div>
    
    var autocompleteDropdownPlaceholder = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-placeholder',
      openIn: 'dropdown',
      dropdownPlaceholderText: 'Try to type "Apple"',
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    });
    

    Dropdown With Typeahead

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With Typeahead</div>
      <ul>
        <li class="item-content item-input">
          <div class="item-inner">
            <div class="item-title item-label">Fruit</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-typeahead" type="text" placeholder="Fruit">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownTypeahead = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-typeahead',
      openIn: 'dropdown',
      dropdownPlaceholderText: 'Try to type "Pineapple"',
      typeahead: true,
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) === 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    });
    

    Dropdown With Ajax-Data

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With Ajax-Data</div>
      <ul>
        <li class="item-content item-input">
          <div class="item-inner">
            <div class="item-title item-label">Language</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-ajax" type="text" placeholder="Language">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownAjax = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-ajax',
      openIn: 'dropdown',
      preloader: true, //enable preloader
      /* If we set valueProperty to "id" then input value on select will be set according to this property */
      valueProperty: 'name', //object's "value" property name
      textProperty: 'name', //object's "text" property name
      limit: 20, //limit to 20 results
      dropdownPlaceholderText: 'Try "JavaScript"',
      source: function (query, render) {
        var autocomplete = this;
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Show Preloader
        autocomplete.preloaderShow();
    
        // Do Ajax request to Autocomplete data
        app.request({
          url: 'autocomplete-languages.json',
          method: 'GET',
          dataType: 'json',
          //send "query" to server. Useful in case you generate response dynamically
          data: {
            query: query,
          },
          success: function (data) {
            // Find matched items
            for (var i = 0; i < data.length; i++) {
              if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
            }
            // Hide Preoloader
            autocomplete.preloaderHide();
            // Render items by passing array with result items
            render(results);
          }
        });
      }
    });
    

    Dropdown With Ajax-Data + Typeahead

    <div class="list no-hairlines-md">
      <div class="block-header">Dropdown With Ajax-Data + Typeahead</div>
      <ul>
        <li class="item-content item-input">
          <div class="item-inner">
            <div class="item-title item-label">Language</div>
            <div class="item-input-wrap">
              <input id="autocomplete-dropdown-ajax-typeahead" type="text" placeholder="Language">
            </div>
          </div>
        </li>
      </ul>
    </div>
    var autocompleteDropdownAjaxTypeahead = app.autocomplete.create({
      inputEl: '#autocomplete-dropdown-ajax-typeahead',
      openIn: 'dropdown',
      preloader: true, //enable preloader
      /* If we set valueProperty to "id" then input value on select will be set according to this property */
      valueProperty: 'name', //object's "value" property name
      textProperty: 'name', //object's "text" property name
      limit: 20, //limit to 20 results
      typeahead: true,
      dropdownPlaceholderText: 'Try "JavaScript"',
      source: function (query, render) {
        var autocomplete = this;
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Show Preloader
        autocomplete.preloaderShow();
    
        // Do Ajax request to Autocomplete data
        app.request({
          url: 'autocomplete-languages.json',
          method: 'GET',
          dataType: 'json',
          //send "query" to server. Useful in case you generate response dynamically
          data: {
            query: query,
          },
          success: function (data) {
            // Find matched items
            for (var i = 0; i < data.length; i++) {
              if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) === 0) results.push(data[i]);
            }
            // Hide Preoloader
            autocomplete.preloaderHide();
            // Render items by passing array with result items
            render(results);
          }
        });
      }
    });

    Searchbar Dropdown

    <div class="page">
      <div class="navbar">
        <div class="navbar-inner sliding">
          ...
          <!-- Put searchbar in subnavbar -->
          <div class="subnavbar">
            <form class="searchbar" id="searchbar-autocomplete">
              <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>
      </div>
      ...
    </div>
    var searchbar = app.searchbar.create({
      el: '#searchbar-autocomplete',
      customSearch: true,
      on: {
        search: function (query) {
          console.log(query);
        }
      }
    });
    var autocompleteSearchbar = app.autocomplete.create({
      openIn: 'dropdown',
      inputEl: '#searchbar-autocomplete input[type="search"]',
      dropdownPlaceholderText: 'Type "Apple"',
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      }
    })

    Simple Standalone Autocomplete

    div class="list">
      <div class="block-header">Simple Standalone Autocomplete</div>
      <ul>
        <li>
          <a class="item-link item-content" href="#" id="autocomplete-standalone">
            <input type="hidden">
            <div class="item-inner">
              <div class="item-title">Favorite Fruite</div>
              <div class="item-after"></div>
            </div>
          </a>
        </li>
      </ul>
    </div>
    var autocompleteStandaloneSimple = app.autocomplete.create({
      openIn: 'page', //open in page
      openerEl: '#autocomplete-standalone', //link that opens autocomplete
      closeOnSelect: true, //go back after we select something
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      },
      on: {
        change: function (value) {
          console.log(value);
          // Add item text value to item-after
          $$('#autocomplete-standalone').find('.item-after').text(value[0]);
          // Add item value to input value
          $$('#autocomplete-standalone').find('input').val(value[0]);
        },
      },
    });
    

    Popup Autocomplete

    <div class="list">
      <div class="block-header">Popup Autocomplete</div>
      <ul>
        <li>
          <a class="item-link item-content" href="#" id="autocomplete-standalone-popup">
            <input type="hidden">
            <div class="item-inner">
              <div class="item-title">Favorite Fruite</div>
              <div class="item-after"></div>
            </div>
          </a>
        </li>
      </ul>
    </div>
    var autocompleteStandalonePopup = app.autocomplete.create({
      openIn: 'popup', //open in page
      openerEl: '#autocomplete-standalone-popup', //link that opens autocomplete
      closeOnSelect: true, //go back after we select something
      source: function (query, render) {
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      },
      on: {
        change: function (value) {
          // Add item text value to item-after
          $$('#autocomplete-standalone-popup').find('.item-after').text(value[0]);
          // Add item value to input value
          $$('#autocomplete-standalone-popup').find('input').val(value[0]);
        },
      },
    });
    

    Multiple Values

    <div class="list">
      <div class="block-header">Multiple Values</div>
      <ul>
        <li>
          <a class="item-link item-content" href="#" id="autocomplete-standalone-multiple">
            <input type="hidden">
            <div class="item-inner">
              <div class="item-title">Favorite Fruite</div>
              <div class="item-after"></div>
            </div>
          </a>
        </li>
      </ul>
    </div>
    var autocompleteStandaloneMultiple = app.autocomplete.create({
      openIn: 'page', //open in page
      openerEl: '#autocomplete-standalone-multiple', //link that opens autocomplete
      multiple: true, //allow multiple values
      source: function (query, render) {
        var autocomplete = this;
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Find matched items
        for (var i = 0; i < fruits.length; i++) {
          if (fruits[i].toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(fruits[i]);
        }
        // Render items by passing array with result items
        render(results);
      },
      on: {
        change: function (value) {
          // Add item text value to item-after
          $$('#autocomplete-standalone-multiple').find('.item-after').text(value.join(', '));
          // Add item value to input value
          $$('#autocomplete-standalone-multiple').find('input').val(value.join(', '));
        }
      }
    });
    

    Standalone With Ajax-Data

    <div class="list">
      <div class="block-header">With Ajax-Data</div>
      <ul>
        <li>
          <a class="item-link item-content" href="#" id="autocomplete-standalone-ajax">
            <input type="hidden">
            <div class="item-inner">
              <div class="item-title">Language</div>
              <div class="item-after"></div>
            </div>
          </a>
        </li>
      </ul>
    </div>
    var autocompleteStandaloneAjax = app.autocomplete.create({
      openIn: 'page', //open in page
      openerEl: '#autocomplete-standalone-ajax', //link that opens autocomplete
      multiple: true, //allow multiple values
      valueProperty: 'id', //object's "value" property name
      textProperty: 'name', //object's "text" property name
      limit: 50,
      preloader: true, //enable preloader
      source: function (query, render) {
        var autocomplete = this;
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Show Preloader
        autocomplete.preloaderShow();
        // Do Ajax request to Autocomplete data
        app.request({
          url: 'autocomplete-languages.json',
          method: 'GET',
          dataType: 'json',
          //send "query" to server. Useful in case you generate response dynamically
          data: {
            query: query
          },
          success: function (data) {
            // Find matched items
            for (var i = 0; i < data.length; i++) {
              if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
            }
            // Hide Preoloader
            autocomplete.preloaderHide();
            // Render items by passing array with result items
            render(results);
          }
        });
      },
      on: {
        change: function (value) {
          var itemText = [],
              inputValue = [];
          for (var i = 0; i < value.length; i++) {
            itemText.push(value[i].name);
            inputValue.push(value[i].id);
          }
          // Add item text value to item-after
          $$('#autocomplete-standalone-ajax').find('.item-after').text(itemText.join(', '));
          // Add item value to input value
          $$('#autocomplete-standalone-ajax').find('input').val(inputValue.join(', '));
        },
      },
    });