自动完成

Framework7 附带了一个移动友好且触摸优化的自动补全组件。

自动补全可以以独立模式或作为下拉菜单使用。

Autocomplete应用方法

自动补全只能使用 JavaScript 创建和初始化。我们需要使用相关应用的方法:

app.autocomplete.create(参数)- 创建自动补全实例

  • 参数 - 对象. 带有自动补全参数的对象

方法返回创建的自动补全实例

app.autocomplete.destroy(el)- 销毁自动补全实例

  • el - HTMLElement字符串(使用 CSS 选择器) 或对象. 要销毁的自动补全实例。

app.autocomplete.get(el)- 通过 HTML 元素获取自动补全实例

  • el - HTMLElement字符串(使用 CSS 选择器)。自动补全元素。

方法返回自动补全实例

app.autocomplete.open(el)- 打开自动补全

  • el - HTMLElement字符串(使用 CSS 选择器)。要打开的自动补全元素。

方法返回自动补全实例

app.autocomplete.close(el)- 关闭自动补全

  • el - HTMLElement字符串(使用 CSS 选择器)。要关闭的自动补全元素。

方法返回自动补全实例

例如:

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

Autocomplete参数

让我们查看所有可用参数的列表:

参数类型默认描述
openIn字符串page定义如何打开自动补全,可以是pagepopup(对于独立模式) 或dropdown
函数 (query, render)接受搜索的函数queryrender你需要传递匹配项数组的函数
限制数字限制每个查询中显示的最大自动补全项目数
加载器布尔值falseSet totrue将预加载器包含在自动补全布局中
加载器颜色字符串预加载器颜色,可以是默认颜色之一
数组默认选中值的数组
valueProperty字符串id匹配项对象表示项目值的键的名称
textProperty字符串text匹配项对象表示显示值(用作显示选项的标题)的键的名称
独立自动补全参数
requestSourceOnOpen布尔值false如果启用,则在自动补全打开时会请求传递给source函数
openerEl字符串
HTMLElement
CSS 选择器字符串或 HTMLElement,表示点击时将打开独立自动补全页面或弹出的链接
popupCloseLinkText字符串Close作为弹出的“关闭”按钮的默认文本
pageBackLinkText字符串Back作为页面打开的“返回”链接的默认文本
pageTitle字符串自动补全文档标题。如果未指定并传递,并且是 List View 的一个项目,则将使用openerEl元素的文本值item-title元素
popupPush布尔值false启用自动补全弹窗在打开时将视图/页面推到后面
popupSwipeToClose布尔值undefined启用使用滑动手势关闭自动补全弹窗的能力。如果未指定,则继承应用的弹窗swipeToCloseparameter
sheetPush布尔值false启用自动补全表单在打开时将视图/页面推到后面
sheetSwipeToClose布尔值undefined启用使用滑动手势关闭自动补全表单的能力。如果未指定,则继承应用的表单swipeToCloseparameter
searchbarPlaceholder字符串搜索...搜索栏占位符文本
searchbarDisableText字符串取消搜索栏“取消”按钮的文本
searchbarSpellcheck布尔值false设置搜索栏输入元素的spellcheck属性的值
notFoundText字符串未找到当未找到匹配项时显示的文本
multiple布尔值falseSet totrue允许多选
closeOnSelect布尔值falseSet totrue并且当用户选择值时自动补全会关闭。如果multiple启用,则不可用
自动聚焦布尔值falseSet totrue在自动补全打开时自动聚焦搜索字段
animate布尔值trueSet tofalse以无动画的方式打开独立自动补全
navbarColorTheme字符串导航栏颜色主题。默认颜色主题之一
formColorTheme字符串表单(复选框或单选按钮)颜色主题。默认颜色主题之一
routableModals布尔值false将打开的自动补全模态(当openIn: 'popup')添加到路由历史记录中,这提供了通过在路由历史记录中向后导航来关闭自动补全并设置当前路由为自动补全模态的能力
url字符串select/独立自动补全的 URL,它将被设置为当前路由
view对象如果你想要使用独立自动补全,则为初始化的视图实例的链接。默认情况下,如果未指定,它将在主视图中打开。
下拉自动补全参数
inputEl字符串
HTMLElement
带有 CSS 选择器或 HTMLElement 的相关文本输入
inputEvents字符串input允许配置用于处理自动补全操作和源请求的输入事件。例如,如果你使用带中文输入法的键盘,可以更改为change keyup compositionend如果使用带中文输入法的键盘
highlightMatches布尔值true在自动补全结果中突出显示匹配项
typeahead布尔值false启用 type ahead,将用匹配项中的第一个项目预填充输入值
dropdownPlaceholderText字符串指定下拉占位符文本
updateInputValueOnSelect布尔值true如果true那么相关输入的值也会更新
dropdownContainerEl字符串
HTMLElement
默认情况下,下拉菜单将添加到父 page-content 元素中。你可以在这里指定不同的元素,将下拉元素添加到其中
渲染函数
renderDropdownfunction(items)渲染自动补全下拉菜单的函数,必须返回下拉菜单的 HTML 字符串
renderPagefunction(items)渲染自动补全页面的函数,必须返回页面的 HTML 字符串
renderPopupfunction(items)渲染自动补全弹出的函数,必须返回弹出的 HTML 字符串
renderItemfunction(item, index)渲染单个自动补全的函数,必须返回项目的 HTML 字符串
renderSearchbar函数渲染搜索栏的函数,必须返回搜索栏的 HTML 字符串
renderNavbar函数渲染导航栏的函数,必须返回导航栏的 HTML 字符串
事件
on对象

带有事件处理程序的对象。例如:

var autocomplete = app.autocomplete.create({
  ...
  on: {
    opened: function () {
      console.log('Autocomplete opened')
    }
  }
})

注意,所有以下参数都可以在autocomplete设置所有自动补全默认值的属性。例如:

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

Autocomplete方法与属性

初始化自动补全后,我们在变量中(例如autocomplete上面示例中的变量)中具有其初始化实例,带有有用的方法和属性:

属性
autocomplete.params包含传递的初始化参数的对象
autocomplete.value选中项数组
autocomplete.openedtrue如果自动补全当前已打开
autocomplete.openerEl自动补全打开元素(如果在初始化时传递)的 HTML 元素
autocomplete.$openerEl自动补全打开元素的 Dom7 实例(如果在初始化时传递)
autocomplete.inputEl自动补全输入(如果在初始化时传递)的 HTML 元素
autocomplete.$inputEl自动补全输入的 Dom7 实例(如果在初始化时传递)
autocomplete.$dropdownEl自动补全下拉菜单的 Dom7 实例
autocomplete.url自动补全 URL(传递在url参数中)
autocomplete.view自动补全视图(传递在view参数中)或找到的父视图
autocomplete.el自动补全容器的 HTML 元素:下拉元素、弹出元素或页面元素。当自动补全打开时可用
autocomplete.$elAutocomplete容器Dom7实例:下拉元素、弹出元素或页面元素。在Autocomplete打开时可用
autocomplete.searchbarAutocomplete页面Searchbar实例
方法
autocomplete.open()打开Autocomplete(下拉、页面或弹出)
autocomplete.close()关闭Autocomplete
autocomplete.preloaderShow()显示Autocomplete预加载器
autocomplete.preloaderHide()隐藏Autocomplete预加载器
autocomplete.destroy()销毁Autocomplete实例并移除所有事件
autocomplete.on(事件上触发, 处理程序)添加事件处理程序
autocomplete.once(事件上触发, 处理程序)添加在触发后将被移除的事件处理程序
autocomplete.off(事件上触发, 处理程序)移除事件处理程序
autocomplete.off(事件上触发)移除指定事件的所有处理程序
autocomplete.emit(事件上触发, ...args)在实例上触发事件

Autocomplete事件

Autocomplete实例在自身实例和应用实例上发出事件。应用实例事件名称前缀为autocomplete.

事件Target参数描述
changeautocompleteautocomplete, value当Autocomplete值变化时触发事件。返回value是一个包含选中项的数组
autocompleteChangeapp
open为前缀autocompleteautocomplete当Autocomplete开始其打开动画时触发事件。作为参数事件处理程序接收Autocomplete实例
autocompleteOpenapp
openedautocompleteautocomplete当Autocomplete完成其打开动画后触发事件。作为参数事件处理程序接收Autocomplete实例
autocompleteOpenedapp
closeautocompleteautocomplete当Autocomplete开始其关闭动画时触发事件。作为参数事件处理程序接收Autocomplete实例
autocompleteCloseapp
closedautocompleteautocomplete当Autocomplete完成其关闭动画后触发事件。作为参数事件处理程序接收Autocomplete实例
autocompleteClosedapp
beforeDestroyautocompleteautocomplete在Autocomplete实例将被销毁之前触发事件。作为参数事件处理程序接收Autocomplete实例
autocompleteBeforeDestroyapp

CSS 变量

以下是相关CSS 变量(CSS 自定义属性) 的列表。

注意,注释掉的变量默认未指定,其值在这种情况下是它们回退到的值。

:root {
  --f7-autocomplete-dropdown-placeholder-color: #a9a9a9;
  --f7-autocomplete-dropdown-preloader-size: 20px;
  --f7-autocomplete-dropdown-font-size: var(--f7-list-font-size);
  /*
  --f7-autocomplete-dropdown-selected-bg-color: rgba(var(--f7-theme-color-rgb), 0.2);
  */
}
.ios {
  --f7-autocomplete-dropdown-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
  --f7-autocomplete-dropdown-text-matching-font-weight: 600;
  --f7-autocomplete-dropdown-bg-color: #fff;
  --f7-autocomplete-dropdown-text-color: #000;
  --f7-autocomplete-dropdown-text-matching-color: #000;
}
.ios .dark,
.ios.dark {
  --f7-autocomplete-dropdown-bg-color: #1c1c1d;
  --f7-autocomplete-dropdown-text-color: #fff;
  --f7-autocomplete-dropdown-text-matching-color: #fff;
}
.md {
  --f7-autocomplete-dropdown-box-shadow: none;
  --f7-autocomplete-dropdown-text-matching-font-weight: 500;
  --f7-autocomplete-dropdown-text-matching-color: #000;
}
.md .dark,
.md.dark {
  --f7-autocomplete-dropdown-text-matching-color: #fff;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-autocomplete-dropdown-bg-color: var(--f7-md-surface-2);
  --f7-autocomplete-dropdown-text-color: var(--f7-md-on-surface);
}

示例

autocomplete.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="title">Autocomplete</div>
        <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 class="page-content">
      <div class="block-title">Dropdown Autocomplete</div>
      <div class="block">
        <p>Dropdown autocomplete is good to use as a quick and simple solution to provide more options in addition to
          free-type value.</p>
      </div>
      <div class="list list-strong-ios list-outline-ios">
        <div class="block-header">Simple Dropdown Autocomplete</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 type="text" placeholder="Fruit" id="autocomplete-dropdown" />
              </div>
            </div>
          </li>
        </ul>
      </div>

      <div class="list list-strong-ios list-outline-ios">
        <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 type="text" placeholder="Fruit" id="autocomplete-dropdown-all" />
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="list list-strong-ios list-outline-ios">
        <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 type="text" placeholder="Fruit" id="autocomplete-dropdown-placeholder" />
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="list list-strong-ios list-outline-ios">
        <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 type="text" placeholder="Fruit" id="autocomplete-dropdown-typeahead" />
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="list list-strong-ios list-outline-ios">
        <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 type="text" placeholder="Language" id="autocomplete-dropdown-ajax" />
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="list list-strong-ios list-outline-ios">
        <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 type="text" placeholder="Language" id="autocomplete-dropdown-ajax-typeahead" />
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Standalone Autocomplete</div>
      <div class="block">
        <p>Standalone autocomplete provides better mobile UX by opening it in a new page or popup. Good to use when you
          need to get strict values without allowing free-type values.</p>
      </div>
      <div class="list list-strong list-outline-ios">
        <div class="block-header">Simple Standalone Autocomplete</div>
        <ul>
          <li>
            <a id="autocomplete-standalone" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">Favorite Fruite</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>
      <div class="list list-strong list-outline-ios">
        <div class="block-header">Popup Autocomplete</div>
        <ul>
          <li>
            <a id="autocomplete-standalone-popup" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">Favorite Fruite</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>
      <div class="list list-strong list-outline-ios">
        <div class="block-header">Multiple Values</div>
        <ul>
          <li>
            <a id="autocomplete-standalone-multiple" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">Favorite Fruite</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>
      <div class="list list-strong list-outline-ios">
        <div class="block-header">With Ajax-Data</div>
        <ul>
          <li>
            <a id="autocomplete-standalone-ajax" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">Language</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $, $f7, $onMounted, $onBeforeUnmount }) => {
    const fruits = 'Apple Apricot Avocado Banana Melon Orange Peach Pear Pineapple'.split(' ');

    let searchbar;
    let autocompleteDropdownSimple;
    let autocompleteDropdownAll;
    let autocompleteDropdownPlaceholder;
    let autocompleteDropdownTypeahead;
    let autocompleteDropdownAjax;
    let autocompleteDropdownAjaxTypeahead;
    let autocompleteStandaloneSimple;
    let autocompleteStandalonePopup;
    let autocompleteStandaloneMultiple;
    let autocompleteStandaloneAjax;

    $onBeforeUnmount(() => {
      searchbar.destroy();
      autocompleteDropdownSimple.destroy();
      autocompleteDropdownAll.destroy();
      autocompleteDropdownPlaceholder.destroy();
      autocompleteDropdownTypeahead.destroy();
      autocompleteDropdownAjax.destroy();
      autocompleteDropdownAjaxTypeahead.destroy();
      autocompleteStandaloneSimple.destroy();
      autocompleteStandalonePopup.destroy();
      autocompleteStandaloneMultiple.destroy();
      autocompleteStandaloneAjax.destroy();
    })

    $onMounted(() => {
      autocompleteDropdownSimple = $f7.autocomplete.create({
        inputEl: '#autocomplete-dropdown',
        openIn: 'dropdown',
        source: function (query, render) {
          console.log(query);
          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
      autocompleteDropdownAll = $f7.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
      autocompleteDropdownPlaceholder = $f7.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
      autocompleteDropdownTypeahead = $f7.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
      autocompleteDropdownAjax = $f7.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
          fetch(`./js/autocomplete-languages.json?query=${query}`)
            .then((res) => res.json())
            .then((data) => {
              // Find matched items
              for (let i = 0; i < data.length; i += 1) {
                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
      autocompleteDropdownAjaxTypeahead = $f7.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
          fetch(`./js/autocomplete-languages.json?query=${query}`)
            .then((res) => res.json())
            .then((data) => {
              // Find matched items
              for (let i = 0; i < data.length; i += 1) {
                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);
            });
        }
      });

      // Simple Standalone
      autocompleteStandaloneSimple = $f7.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]);
          },
        },
      });

      // Standalone Popup
      autocompleteStandalonePopup = $f7.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 Standalone
      autocompleteStandaloneMultiple = $f7.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
      autocompleteStandaloneAjax = $f7.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
          fetch(`./js/autocomplete-languages.json?query=${query}`)
            .then((res) => res.json())
            .then((data) => {
              // Find matched items
              for (let i = 0; i < data.length; i += 1) {
                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(', '));
          },
        },
      });

      // Searchbar Autocomplete
      autocompleteSearchbar = $f7.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);
        }
      })

      searchbar = $f7.searchbar.create({
        el: '#searchbar-autocomplete',
        customSearch: true,
        on: {
          search: function (sb, query) {
            console.log(query);
          }
        }
      })
    })

    return $render;
  }
</script>