自動完成

Framework7 附帶了行動裝置友善且針對觸控最佳化的自動完成元件。

自動完成可以用在獨立模式或下拉式選單中。

自動完成應用程式方法

自動完成只能使用 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) {
    ...
  }
});

自動完成參數

讓我們來看看所有可用參數的清單

參數類型預設值說明
openIn字串page定義如何開啟自動完成,可以是 pagepopup (針對獨立模式) 或 dropdown
source函式 (query, render)接受搜尋 查詢呈現 函式的函式,您需要傳遞包含配對項目陣列
限制數字限制每個查詢在自動完成中顯示的最大項目數
預載器布林值false設為 true 以將預載器包含到自動完成版面
預載器顏色字串預載器顏色,預設顏色之一
陣列包含預設選取值的陣列
值屬性字串id代表項目值的配對項目物件金鑰的名稱
文字屬性字串文字代表項目顯示值(用作顯示選項標題)的配對項目物件金鑰的名稱
獨立自動完成參數
開啟時請求來源布林值false如果啟用,則會在自動完成開啟時請求傳遞給 來源 函式
開啟元素字串
HTMLElement
包含 CSS 選擇器或連結的字串,連結會在按一下時開啟獨立自動完成頁面或快顯視窗
快顯視窗關閉連結文字字串關閉以快顯視窗開啟時,「關閉」按鈕的預設文字
頁面返回連結文字字串返回以頁面開啟時,「返回」連結的預設文字
頁面標題字串自動完成頁面標題。如果未指定且傳遞的 開啟元素 是清單檢視的項目,則會使用 項目標題 元素的文字值
快顯視窗推播布林值false啟用自動完成快顯視窗在開啟時推播後面的檢視
快顯視窗滑動關閉布林值未定義啟用使用滑動關閉自動完成快顯視窗的功能。未指定時,會繼承應用程式的快顯視窗 滑動關閉 參數
工作表推播布林值false啟用自動完成工作表在開啟時推播後面的檢視
工作表滑動關閉布林值未定義啟用使用滑動關閉自動完成工作表的功能。未指定時,會繼承應用程式的工作表 滑動關閉 參數
搜尋列提示字字串搜尋...搜尋列提示字文字
搜尋列停用文字字串取消搜尋列「取消」按鈕文字
搜尋列拼字檢查布林值false設定搜尋列輸入元素上 拼字檢查 屬性的值
找不到文字字串找不到任何結果找不到任何配對時顯示的文字
多重布林值false設為 true 以允許多重選取
選取時關閉布林值false設為 true,當使用者選取值時,自動完成將會關閉。如果啟用 multiple,則不可用
autoFocus布林值false設為 true,在自動完成開啟時自動對焦搜尋欄位
animate布林值true設為 false,在沒有動畫的情況下開啟獨立的自動完成
navbarColorTheme字串導覽列色彩主題。其中一個預設的 色彩主題
formColorTheme字串表單(核取方塊或選項按鈕)色彩主題。其中一個預設的 色彩主題
routableModals布林值false將開啟的自動完成模態(當 openIn: 'popup')加入路由器記錄,這讓使用者可以透過回到路由器記錄並將目前的路由設為自動完成模態來關閉自動完成
url字串select/獨立的自動完成 URL,將會設為目前的路由
view物件如果你想使用獨立的自動完成,請連結到已初始化的 View 實例。如果未指定,預設會在 Main View 中開啟。
下拉式自動完成參數
inputEl字串
HTMLElement
相關文字輸入的 CSS 選擇器或 HTMLElement
inputEvents字串input允許設定用於處理自動完成動作和來源請求的輸入事件。如果你使用鍵盤輸入中文,可以變更為 change keyup compositionend
highlightMatches布林值true在自動完成結果中,反白顯示符合的項目
typeahead布林值false啟用鍵入提示,會使用符合項目的第一個項目預先填入輸入值
dropdownPlaceholderText字串指定下拉式選單的提示文字
updateInputValueOnSelect布林值true如果為 true,相關輸入的值也會更新
dropdownContainerEl字串
HTMLElement
預設會將下拉式選單加入父層的 page-content 元素。你可以指定不同的元素來加入下拉式選單元素
渲染函式
renderDropdownfunction(items)用於渲染自動完成下拉式選單的函式,必須回傳下拉式選單的 HTML 字串
renderPagefunction(items)用於渲染自動完成頁面的函式,必須回傳頁面的 HTML 字串
renderPopupfunction(items)用於渲染自動完成快顯視窗的函式,必須回傳快顯視窗的 HTML 字串
renderItem函數(項目, 索引)用於呈現單一自動完成的函數,必須傳回項目 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.params包含已傳遞初始化參數的物件
autocomplete.value包含已選取項目的陣列
autocomplete.opened如果自動完成目前已開啟,則為 **true**
autocomplete.openerEl自動完成開啟器元素的 HTML 元素(如果在初始化時傳遞)
autocomplete.$openerEl自動完成開啟器元素的 Dom7 執行個體(如果在初始化時傳遞)
autocomplete.inputEl自動完成輸入的 HTML 元素(如果在初始化時傳遞)
autocomplete.$inputEl自動完成輸入的 Dom7 執行個體(如果在初始化時傳遞)
autocomplete.$dropdownEl自動完成下拉式選單的 Dom7 執行個體
autocomplete.url自動完成網址(在 `url` 參數中傳遞)
autocomplete.view自動完成檢視(在 `view` 參數中傳遞)或找到的父檢視
autocomplete.el自動完成容器的 HTML 元素:下拉式選單元素、快顯視窗元素或頁面元素。在自動完成開啟時可用
autocomplete.$el自動完成容器的 Dom7 執行個體:下拉式選單元素、快顯視窗元素或頁面元素。在自動完成開啟時可用
autocomplete.searchbar自動完成頁面搜尋列執行個體
方法
autocomplete.open()開啟自動完成(下拉式選單、頁面或快顯視窗)
autocomplete.close()關閉自動完成
autocomplete.preloaderShow()顯示自動完成預載器
autocomplete.preloaderHide()隱藏自動完成預載器
autocomplete.destroy()銷毀自動完成執行個體並移除所有事件
autocomplete.on(事件, 處理常式)新增事件處理常式
autocomplete.once(事件, 處理常式)新增事件處理常式,該處理常式在觸發後將被移除
autocomplete.off(event, handler)移除事件處理常式
autocomplete.off(event)移除指定事件的所有處理常式
autocomplete.emit(event, ...args)在實例上觸發事件

自動完成事件

自動完成實例在自身實例和應用程式實例上觸發事件。應用程式實例事件具有相同的名稱,前面加上 autocomplete

事件目標參數說明
change自動完成自動完成、值當自動完成值變更時,將觸發事件。傳回的 是包含已選取項目陣列
autocompleteChange應用程式
開啟自動完成自動完成當自動完成開始開啟動畫時,將觸發事件。作為參數,事件處理常式接收自動完成實例
autocompleteOpen應用程式
已開啟自動完成自動完成當自動完成完成開啟動畫後,將觸發事件。作為參數,事件處理常式接收自動完成實例
autocompleteOpened應用程式
關閉自動完成自動完成當自動完成開始關閉動畫時,將觸發事件。作為參數,事件處理常式接收自動完成實例
autocompleteClose應用程式
已關閉自動完成自動完成當自動完成完成關閉動畫後,將觸發事件。作為參數,事件處理常式接收自動完成實例
autocompleteClosed應用程式
beforeDestroy自動完成自動完成在自動完成實例即將被銷毀之前,將觸發事件。作為參數,事件處理常式接收自動完成實例
autocompleteBeforeDestroy應用程式

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>