選擇器

選取器是一個強大的元件,可讓您建立自訂的覆蓋式選取器,看起來就像 iOS 原生選取器。

選取器可用作內嵌元件或覆蓋式元件。覆蓋式選取器在平板電腦(iPad)上會自動轉換為彈出視窗。

選取器應用程式方法

讓我們看看相關的應用程式方法,以使用選取器

app.picker.create(parameters)- 建立選取器執行個體

  • parameters - 物件。具有選取器參數的物件

方法傳回建立的選取器執行個體

app.picker.destroy(el)- 銷毀選取器執行個體

  • el - HTMLElement字串(含 CSS 選擇器)或 物件。要銷毀的選取器元素或選取器執行個體。

app.picker.get(el)- 透過 HTML 元素取得選取器執行個體

  • el - HTMLElement字串(含 CSS 選擇器)。選取器元素。

方法傳回選取器的執行個體

app.picker.close(el)- 關閉選取器

  • el - HTMLElement字串(含 CSS 選擇器)。要關閉的選取器元素。

方法傳回選取器的執行個體

例如

var picker = app.picker.create({
  inputEl: '#picker-input',
  cols: [
     {
       values: ['apple', 'orange', 'banana'],
       displayValues: ['Apple', 'Orange', 'Banana'],
     }
   ]
});

選取器參數

讓我們看看所有可用的選取器參數清單

參數類型預設值說明
rotateEffect布林值false啟用 3D 旋轉效果
freeMode布林值false停用值上的對齊
value陣列具有初始值的陣列。每個陣列項目代表相關欄位的數值
formatValue函式 (values, displayValues)格式化輸入值的函式,應傳回新的/格式化的字串值。valuesdisplayValues 是陣列,其中每個項目代表相關欄位的數值/顯示值
cols陣列包含欄位的陣列。每個陣列項目都代表具有欄位參數的物件
容器/開啟器特定參數
containerEl字串
HTMLElement
包含 CSS 選擇器或 HTMLElement 的字串,用於放置產生的 Picker HTML。僅用於內嵌式選擇器
openIn字串auto可以是 autopopover(在浮動視窗中開啟選擇器)、sheet(在工作表模式中開啟)。如果是 auto,會在小螢幕上以工作表模式開啟,在大螢幕上以浮動視窗開啟。
backdrop布林值為 Picker 容器(浮動視窗或工作表)啟用背景(後方的深色半透明圖層)。預設會根據開啟方式(在工作表或浮動視窗中)使用預設值。
sheetPush布林值false啟用 Picker 工作表在開啟時推動後方的檢視
sheetSwipeToClose布林值false啟用使用滑動關閉 Picker 工作表的功能
inputEl字串或 HTMLElement包含 CSS 選擇器或 HTMLElement 的字串,與相關的輸入元素有關
scrollToInput布林值true在開啟選擇器時將視窗(頁面內容)捲動到輸入
inputReadOnly布林值true在指定的輸入上設定「唯讀」屬性
cssClass字串要設定在選擇器元素上的其他 CSS 類別名稱
closeByOutsideClick布林值true如果啟用,將透過按一下選擇器或相關輸入元素以外的地方來關閉選擇器
toolbar布林值true啟用選擇器工具列
toolbarCloseText字串完成完成/關閉工具列按鈕的文字
routableModals布林值false會將開啟的選擇器加入路由器記錄,這能透過在路由器記錄中返回來關閉選擇器,並將目前的路由設定為選擇器模式
url字串select/會設定為目前路由的選擇器模式 URL
view物件當啟用 routableModals 時,要設定路由的檢視。預設為 inputEl 的父檢視,如果找不到父檢視,則為主要檢視
渲染函式
renderToolbar函式用於渲染工具列的函式。必須傳回工具列 HTML 字串
render函式用於渲染整個選擇器的函式。必須傳回選擇器完整的 HTML 字串
事件
on物件

包含事件處理常式的物件。例如

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

請注意,以下所有參數都可以在 picker 屬性下的全域應用程式參數中使用,以設定所有選擇器的預設值。例如

var app = new Framework7({
  picker: {
    rotateEffect: true,
    openIn: 'popover',
  }
});

欄位參數

當我們設定 Picker 時,需要傳遞 cols 參數。它是一個陣列,其中每個項目都是一個包含欄位參數的物件

參數類型預設值說明
values陣列包含字串欄位值的陣列
displayValues陣列包含會顯示在 Picker 中的字串欄位值的陣列。如果未指定,它會顯示 values 參數中的值
cssClass字串cssClass
要設定在欄位 HTML 容器上的其他 CSS 類別名稱字串欄位值文字對齊,可以是「左」、「中」或「右」
寬度數字欄位寬度,單位為 px。如果您需要在具有依賴欄位的選擇器中修正欄位寬度,這會很有用。預設會自動計算
分隔線布林值false定義應作為視覺分隔線的欄位,沒有任何值
內容字串應為分隔線欄位 (divider:true) 指定欄位的內容
onChangefunction(picker, value, displayValue)當選擇器值變更時會執行的回呼函式。

選擇器方法和屬性

初始化選擇器後,變數中會有初始化的執行個體 (例如上述範例中的 picker 變數),其中包含有用的方法和屬性

屬性
picker.app連結至全域應用程式執行個體
picker.containerEl選擇器包裝容器 HTML 元素 (當使用內嵌式選擇器時)
picker.$containerEl包含選擇器包裝容器 HTML 元素的 Dom7 執行個體 (當使用內嵌式選擇器時)
picker.el選擇器 HTML 元素
picker.$el包含選擇器 HTML 元素的 Dom7 執行個體
picker.inputEl選擇器輸入 HTML 元素 (傳遞給 inputEl 參數)
picker.$inputEl包含選擇器輸入 HTML 元素的 Dom7 執行個體 (傳遞給 inputEl 參數)
picker.value陣列,其中每個項目代表每個欄位目前選取的值
picker.cols包含指定選擇器欄位的陣列。每個欄位也有自己的方法和屬性 (請參閱下方)
picker.opened如果選擇器目前已開啟,則為 true
picker.inline當使用內嵌式選擇器時為 true
picker.url選擇器 URL (傳遞給 url 參數)
picker.view選擇器檢視 (傳遞給 view 參數) 或找到父檢視
picker.params包含初始化參數的物件
方法
picker.setValue(values)設定新的選擇器值。values 是陣列,其中每個項目代表每個欄位的值。
picker.getValue()傳回目前的選擇器值
picker.open()開啟選擇器
picker.close()關閉選擇器
picker.destroy()銷毀選擇器執行個體並移除所有事件
picker.on(event, handler)新增事件處理常式
picker.once(event, handler)新增事件處理器,該處理器在觸發後會被移除
picker.off(event, handler)移除事件處理器
picker.off(event)移除指定事件的所有處理器
picker.emit(event, ...args)在實例上觸發事件

欄位方法和屬性

picker.cols 陣列中的每個欄位也有其自己的有用方法和屬性。

//Get first column
var col = picker.cols[0];
屬性
col.el欄位 HTML 元素
col.$el具有欄位 HTML 容器的 Dom7 實例
col.items具有欄位項目 HTML 元素的 Dom7 實例
col.value目前選取的欄位值
col.displayValue目前選取的欄位顯示值
col.activeIndex目前選取/啟用項目的索引編號
方法
col.setValue(value)設定目前欄位的新值。value 是新值。
col.replaceValues(values, displayValues)用新的值取代欄位值和顯示值

選取器事件

選取器會在選取器元素上觸發下列 DOM 事件,以及在應用程式和選取器實例上觸發事件

DOM 事件

事件目標說明
picker:open選取器元素<div class="picker">當選取器開始其開啟動畫時,會觸發事件
picker:opened選取器元素<div class="picker">當選取器完成其開啟動畫後,會觸發事件
picker:close選取器元素<div class="picker">當選取器開始其關閉動畫時,會觸發事件
picker:closed選取器元素<div class="picker">當選取器完成其關閉動畫後,會觸發事件

應用程式和選取器實例事件

選取器實例會在自身實例和應用程式實例上發出事件。應用程式實例事件具有相同的名稱,並加上 picker 前綴。

事件目標引數說明
changepicker(picker, value, displayValue)當選取器值變更時,會觸發事件
pickerChangeapp
initpicker(picker)當選取器初始化時,會觸發事件
pickerInitapp
openpicker(picker)當選取器開始其開啟動畫時,會觸發事件。事件處理器會收到選取器實例作為引數
pickerOpenapp
openedpicker(picker)當選取器完成其開啟動畫後,會觸發事件。事件處理器會收到選取器實例作為引數
pickerOpenedapp
closepicker(picker)當選取器開始其關閉動畫時,會觸發事件。事件處理器會收到選取器實例作為引數
pickerCloseapp
關閉picker(picker)在 Picker 完成其關閉動畫後觸發事件。作為一個參數,事件處理程序接收 picker 實例
pickerClosedapp
beforeDestroypicker(picker)在 Picker 實例被銷毀之前觸發事件。作為一個參數,事件處理程序接收 picker 實例
pickerBeforeDestroyapp

CSS 變數

以下是相關 CSS 變數(CSS 自訂屬性)清單。

請注意,註解的變數未預設指定,其值是它們在此情況下回退到的值。

:root {
  --f7-picker-height: 260px;
  --f7-picker-inline-height: 200px;
  --f7-picker-popover-height: 260px;
  --f7-picker-popover-width: 280px;
  --f7-picker-landscape-height: 200px;
  --f7-picker-item-height: 36px;
  /*
  --f7-picker-sheet-bg-color: var(--f7-sheet-bg-color);
  */
}
.ios {
  --f7-picker-column-font-size: 20px;
  --f7-picker-item-selected-text-color: #000;
  --f7-picker-item-selected-bg-color: rgba(0, 0, 0, 0.12);
  --f7-picker-divider-text-color: #000;
  --f7-picker-item-text-color: rgba(0, 0, 0, 0.45);
}
.ios .dark,
.ios.dark {
  --f7-picker-item-selected-text-color: #fff;
  --f7-picker-item-selected-bg-color: rgba(255, 255, 255, 0.1);
  --f7-picker-divider-text-color: #fff;
  --f7-picker-item-text-color: rgba(255, 255, 255, 0.55);
}
.md {
  --f7-picker-column-font-size: 20px;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-picker-item-selected-text-color: var(--f7-md-on-surface);
  --f7-picker-item-text-color: var(--f7-md-on-surface-variant);
  --f7-picker-divider-text-color: var(--f7-md-on-surface);
  --f7-picker-item-selected-border-color: var(--f7-md-outline);
}

範例

picker.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="title">Picker</div>
      </div>
    </div>
    <div class="page-content">
      <div class="block">
        <p>Picker is a powerful component that allows you to create custom overlay pickers which looks like native
          picker.</p>
        <p>Picker could be used as inline component or as overlay. Overlay Picker will be automatically converted to
          Popover on tablets (iPad).</p>
      </div>
      <div class="block-title">Picker with single value</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Your iOS device" readonly="readonly" id="demo-picker-device" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">2 values and 3d-rotate effect</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Describe yourself" readonly="readonly" id="demo-picker-describe" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Dependent values</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Custom toolbar</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Describe yourself" readonly="readonly"
                    id="demo-picker-custom-toolbar" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Inline Picker / Date-time</div>
      <div class="list no-margin">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Date Time" readonly="readonly" id="demo-picker-date" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block block-strong block-outline-ios inset-md no-padding no-margin-top">
        <div id="demo-picker-date-container"></div>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $f7, $on }) => {
    let pickerDevice;
    let pickerDescribe;
    let pickerDependent;
    let pickerCustomToolbar;

    $on('pageInit', () => {
      // iOS Device picker
      pickerDevice = $f7.picker.create({
        inputEl: '#demo-picker-device',
        cols: [
          {
            textAlign: 'center',
            values: ['iPhone 4', 'iPhone 4S', 'iPhone 5', 'iPhone 5S', 'iPhone 6', 'iPhone 6 Plus', 'iPad 2', 'iPad Retina', 'iPad Air', 'iPad mini', 'iPad mini 2', 'iPad mini 3']
          }
        ]
      });

      // Describe yourself picker
      pickerDescribe = $f7.picker.create({
        inputEl: '#demo-picker-describe',
        rotateEffect: true,
        cols: [
          {
            textAlign: 'left',
            values: ('Super Amazing Bat Iron Rocket Lex Beautiful Wonderful Raining Happy Funny Cool Hot').split(' ')
          },
          {
            values: ('Man Luthor Woman Boy Girl Person Cutie Babe Raccoon').split(' ')
          },
        ]
      });

      // Dependent values
      var carVendors = {
        Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
        German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
        American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
      };
      pickerDependent = $f7.picker.create({
        inputEl: '#demo-picker-dependent',
        rotateEffect: true,
        formatValue: function (values) {
          return values[1];
        },
        cols: [
          {
            textAlign: 'left',
            values: ['Japanese', 'German', 'American'],
            onChange: function (picker, country) {
              if (picker.cols[1].replaceValues) {
                picker.cols[1].replaceValues(carVendors[country]);
              }
            }
          },
          {
            values: carVendors.Japanese,
            width: 160,
          },
        ]
      });

      // Custom Toolbar
      pickerCustomToolbar = $f7.picker.create({
        inputEl: '#demo-picker-custom-toolbar',
        rotateEffect: true,
        renderToolbar: function () {
          return '<div class="toolbar">' +
            '<div class="toolbar-inner">' +
            '<div class="left">' +
            '<a  class="link toolbar-randomize-link">Randomize</a>' +
            '</div>' +
            '<div class="right">' +
            '<a  class="link sheet-close popover-close">That\'s me</a>' +
            '</div>' +
            '</div>' +
            '</div>';
        },
        cols: [
          {
            values: ['Mr', 'Ms'],
          },
          {
            textAlign: 'left',
            values: ('Super Amazing Bat Iron Rocket Lex Beautiful Wonderful Raining Happy Funny Cool Hot').split(' ')
          },
          {
            values: ('Man Luthor Woman Boy Girl Person Cutie Babe Raccoon').split(' ')
          },
        ],
        on: {
          open: function (picker) {
            picker.$el.find('.toolbar-randomize-link').on('click', function () {
              var col0Values = picker.cols[0].values;
              var col0Random = col0Values[Math.floor(Math.random() * col0Values.length)];

              var col1Values = picker.cols[1].values;
              var col1Random = col1Values[Math.floor(Math.random() * col1Values.length)];

              var col2Values = picker.cols[2].values;
              var col2Random = col2Values[Math.floor(Math.random() * col2Values.length)];

              picker.setValue([col0Random, col1Random, col2Random]);
            });
          },
        }
      });
      // Inline date-time
      const today = new Date();
      pickerInline = $f7.picker.create({
        containerEl: '#demo-picker-date-container',
        inputEl: '#demo-picker-date',
        toolbar: false,
        rotateEffect: true,
        value: [
          today.getMonth(),
          today.getDate(),
          today.getFullYear(),
          today.getHours(),
          today.getMinutes() < 10 ? '0' + today.getMinutes() : today.getMinutes()
        ],
        formatValue: function (values, displayValues) {
          return displayValues[0] + ' ' + values[1] + ', ' + values[2] + ' ' + values[3] + ':' + values[4];
        },
        cols: [
          // Months
          {
            values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
            displayValues: ('January February March April May June July August September October November December').split(' '),
            textAlign: 'left'
          },
          // Days
          {
            values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
          },
          // Years
          {
            values: (function () {
              var arr = [];
              for (var i = 1950; i <= 2030; i++) { arr.push(i); }
              return arr;
            })(),
          },
          // Space divider
          {
            divider: true,
            content: '&nbsp;&nbsp;'
          },
          // Hours
          {
            values: (function () {
              var arr = [];
              for (var i = 0; i <= 23; i++) { arr.push(i); }
              return arr;
            })(),
          },
          // Divider
          {
            divider: true,
            content: ':'
          },
          // Minutes
          {
            values: (function () {
              var arr = [];
              for (var i = 0; i <= 59; i++) { arr.push(i < 10 ? '0' + i : i); }
              return arr;
            })(),
          }
        ],
        on: {
          change: function (picker, values, displayValues) {
            var daysInMonth = new Date(picker.value[2], picker.value[0] * 1 + 1, 0).getDate();
            if (values[1] > daysInMonth) {
              picker.cols[1].setValue(daysInMonth);
            }
          },
        }
      });
    });
    $on('pageBeforeRemove', () => {
      pickerDevice.destroy();
      pickerDescribe.destroy();
      pickerDependent.destroy();
      pickerCustomToolbar.destroy();
    });

    return $render;
  };

</script>