ピッカー

ピッカーは、iOSネイティブピッカーのように見えるカスタムオーバーレイピッカーを作成できる強力なコンポーネントです。

ピッカーは、インラインコンポーネントまたはオーバーレイとして使用できます。オーバーレイピッカーは、タブレット(iPad)では自動的にポップオーバーに変換されます。

ピッカーアプリメソッド

ピッカーを操作するための関連するアプリメソッドを見てみましょう。

app.picker.create(パラメーター)- ピッカーインスタンスを作成します

  • パラメーター - オブジェクト。ピッカーパラメーターを含むオブジェクト

メソッドは作成されたピッカーのインスタンスを返します。

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'],
     }
   ]
});

ピッカーパラメーター

利用可能なすべてのピッカーパラメーターのリストを見てみましょう。

パラメーターデフォルト説明
rotateEffectbooleanfalse3D回転効果を有効にします。
freeModebooleanfalse値のスナップを無効にします。
value配列初期値を含む配列。各配列項目は関連する列の値を表します。
formatValuefunction (values, displayValues)入力値をフォーマットする関数で、新しい/フォーマットされた文字列値を返す必要があります。valuesdisplayValuesは、各項目が関連する列の値/表示値を表す配列です。
cols配列列を含む配列。各配列項目は、列パラメーターを含むオブジェクトを表します。
コンテナ/オープナー固有のパラメーター
containerEl文字列
HTMLElement
生成されたピッカーHTMLを配置するCSSセレクターまたはHTMLElementを含む文字列。インラインピッカーの場合のみ使用します
openIn文字列autoautopopover(ピッカーをポップオーバーで開く場合)、sheet(シートモーダルで開く場合)のいずれかになります。autoの場合、小さい画面ではシートモーダルで、大きい画面ではポップオーバーで開きます。
backdropbooleanピッカーコンテナ(ポップオーバーまたはシート)のバックドロップ(背後の暗い半透明レイヤー)を有効にします。デフォルトでは、それがどのように開かれているか(シートまたはポップオーバー)に基づいてデフォルト値を使用します。
sheetPushbooleanfalseピッカーシートを開いたときに背後のビューをプッシュできるようにします。
sheetSwipeToClosebooleanfalseスワイプでピッカーシートを閉じることができるようにします。
inputEl文字列またはHTMLElement関連する入力要素を含むCSSセレクターまたはHTMLElementを含む文字列
scrollToInputbooleantrueピッカーが開かれたときにビューポート(ページコンテンツ)を入力にスクロールします。
inputReadOnlybooleantrue指定された入力に「readonly」属性を設定します。
cssClass文字列ピッカー要素に設定する追加のCSSクラス名。
closeByOutsideClickbooleantrue有効にした場合、ピッカーまたは関連する入力要素の外側をクリックするとピッカーが閉じられます。
toolbarbooleantrueピッカーツールバーを有効にします。
toolbarCloseText文字列完了完了/閉じるツールバーボタンのテキスト。
routableModalsbooleanfalse開いているピッカーをルーター履歴に追加します。これにより、ルーター履歴で戻ることでピッカーを閉じることができ、現在のルートをピッカーモーダルに設定できます。
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',
  }
});

列パラメーター

ピッカーを設定する際には、colsパラメーターを渡す必要があります。これは、各項目が列パラメーターを含むオブジェクトである配列です。

パラメーターデフォルト説明
values配列文字列の列値を含む配列。
displayValues配列ピッカーに表示される文字列の列値を含む配列。指定しない場合、valuesパラメーターの値が表示されます。
cssClass文字列列のHTMLコンテナに設定する追加のCSSクラス名。
textAlign文字列列値のテキスト配置。「left」、「center」、「right」のいずれかになります。
width数値ピクセル単位の列幅。従属列を含むピッカーで列幅を固定する必要がある場合に役立ちます。デフォルトでは、自動的に計算されます。
dividerbooleanfalse視覚的な区切り線として使用される列を定義します。値はありません。
content文字列列のコンテンツを含む区切り線列(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)列の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
closedpicker(picker)ピッカーが閉じるアニメーションが完了した後にトリガーされるイベントです。引数として、イベントハンドラはピッカーインスタンスを受け取ります。
pickerClosedapp
beforeDestroypicker(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>