ピッカー
Pickerは、iOSネイティブのピッカーのようなカスタムオーバーレイピッカーを作成できるパワフルなコンポーネントです。
ピッカーは、インラインコンポーネントとしてもオーバーレイとしても使用できます。オーバーレイピッカーは、タブレット(iPad)では自動的にPopoverに変換されます。
ピッカーアプリのメソッド
ピッカーに関連するアプリのメソッドを見てみましょう。
app.picker.create(parameters)- ピッカーのインスタンスを作成する
- parameters - object. ピッカーのパラメータを持つオブジェクト
作成したPickerのインスタンスを返すメソッド
app.picker.destroy(el)- Pickerインスタンスの破棄
- el - HTMLElementまたはstring(CSSセレクタを使用)、またはobject。破壊するPicker要素またはPickerインスタンスを指定します。
app.picker.get(el)- HTML要素でPickerインスタンスを取得
- el - HTMLElement または string (CSS Selectorを使用)。Pickerの要素を指定します。
メソッドはPickerのインスタンスを返します。
app.picker.close(el)- ピッカーを閉じる
- el - HTMLElement または string (with CSS Selector)です。Pickerの要素を閉じます。
メソッドはPickerのインスタンスを返します。
例:
var picker = app.picker.create({
inputEl: '#picker-input',
cols: [
{
values: ['apple', 'orange', 'banana'],
displayValues: ['Apple', 'Orange', 'Banana'],
}
]
});
ピッカーのパラメータ
利用可能な Picker のパラメータの一覧を見てみましょう。
Parameter | Type | Default | Description |
---|---|---|---|
rotateEffect | boolean | false | 3D回転効果を有効にする |
momentumRatio | number | 7 | 値が大きいほど、高速でタッチして移動した後にピッカーを離したときの勢いが増します。 |
mousewheel | boolean | true | マウスホイールでピッカーの値をスクロールする機能を有効にする |
updateValuesOnMomentum | boolean | false | 勢いがあるときにピッカーと入力値を更新 |
updateValuesOnTouchmove | boolean | true | タッチ操作時にピッカーと入力値を更新 |
updateValuesOnMousewheel | boolean | true | マウスホイールでのスクロール中にピッカーと入力値を更新 |
freeMode | boolean | false | 値のスナップを無効にする |
value | array | 初期値を持つ配列。配列の各項目は関連する列の値を表す | |
formatValue | function (values, displayValues) | 入力値をフォーマットする関数で、新しい/フォーマットされた文字列を返します。valuesとdisplayValuesは、各項目が関連するカラムの値/表示値を表す配列です。 | |
cols | array | カラムを持つ配列。配列の各項目は、カラムのパラメータを持つオブジェクトを表す | |
Container/opener-specific parameters | |||
containerEl | string HTMLElement | 生成されたピッカーのHTMLを配置するためのCSSセレクタまたはHTML要素を持つ文字列。インラインピッカーにのみ使用してください。 | |
openIn | string | auto | auto, popover (ピッカーをポップオーバーで開く), sheet (シートモーダルで開く)のいずれかです。auto の場合、小さな画面ではシートモーダルで、大きな画面ではポップオーバーで開きます。 |
backdrop | boolean | ピッカーコンテナ(ポップオーバーまたはシート)の背景を有効にします(後ろに暗い半透明のレイヤー)。デフォルトでは、どのように開かれたか(シートまたはポップオーバー)に基づいて、デフォルトの値が使用されます。 | |
sheetPush | boolean | false | ピッカーシートを開いた時に後ろにビューを押し出すようにします。 |
sheetSwipeToClose | boolean | false | スワイプでピッカーシートを閉じることができるようになります。 |
inputEl | string or HTMLElement | CSSセレクタ付きの文字列、または関連するinput要素を持つHTML要素 | |
scrollToInput | boolean | true | ピッカーを開いたときにビューポート(ページ内容)を入力までスクロールさせる |
inputReadOnly | boolean | true | 指定した入力項目に "readonly "属性を設定する |
cssClass | string | ピッカー要素に設定される追加のCSSクラス名 | |
closeByOutsideClick | boolean | true | 有効にすると、ピッカーまたは関連する入力要素の外側をクリックしたときにピッカーを閉じるようにする |
toolbar | boolean | true | ピッカーツールバーを有効にする |
toolbarCloseText | string | Done | Done/Closeツールバーボタンのテキスト |
routableModals | boolean | false | 開いたピッカーをルータの履歴に追加し、ルータの履歴を遡ってピッカーを閉じることができるようにし、現在のルートをピッカーモーダルに設定します。 |
url | string | select/ | 現在のルートとして設定されるピッカーモーダルのURL |
view | object | routableModalsが有効な場合に、ルーティングを設定するビューです。親ビューが見つからない場合は、 inputEl` の親ビュー、もしくはメインビューがデフォルトとなります。 | |
Render Functions | |||
renderToolbar | function | ツールバーをレンダリングする関数です。ツールバーのHTML文字列を返す必要があります。 | |
render | function | ピッカー全体をレンダリングする関数です。ピッカー全体のHTML文字列を返す必要があります。 | |
Events | |||
on | object | イベントハンドラーを持つオブジェクトです。例えば、以下のようなものがあります。
|
なお、以下のパラメータはすべて、アプリのグローバルパラメータの picker
プロパティで使用でき、すべてのピッカーのデフォルト値を設定できます。例えば、以下のようになります。
var app = new Framework7({
picker: {
rotateEffect: true,
openIn: 'popover',
}
});
カラムのパラメータ
ピッカーを設定する際には、cols
パラメータを渡す必要があります。これは配列で、各アイテムはカラムパラメータを持つオブジェクトです。
Parameter | Type | Default | Description |
---|---|---|---|
values | array | カラムの値を表す文字列の配列 | |
displayValues | array | ピッカーに表示されるカラムの値を文字列で指定した配列です。指定しない場合は、valuesパラメータの値が表示されます。 | |
cssClass | string | カラムのHTMLコンテナに設定される追加のCSSクラス名 | |
textAlign | string | カラムの値のテキストの配置。"left"、"center"、"right "のいずれかを指定します。 | |
width | number | 列の幅をpxで指定します。カラムに依存するピッカーでカラムの幅を固定する必要がある場合に便利です。デフォルトでは、自動的に計算されます。 | |
divider | boolean | false | 視覚的な仕切りとして使用される列を定義し、値を持ちません。 |
content | string | divider-column (divider:true ) には、カラムの内容を指定する必要があります。 | |
onChange | function(picker, value, displayValue) | ピッカーの値が変更されたときに実行されるコールバック関数です。 |
ピッカーのメソッドとプロパティ
ピッカーを初期化すると、初期化されたインスタンスが変数(上記の例では picker
変数)に格納され、便利なメソッドやプロパティが用意されます。
Properties | |
---|---|
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 | 初期化パラメータを持つオブジェクト |
Methods | |
picker.setValue(values, duration) | 新しいピッカーの値を設定します。values は配列で、各項目が各カラムの値を表します。duration - ms単位の遷移時間 |
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
に含まれる各カラムにも、それぞれ有用なメソッドやプロパティがあります。
//最初のカラムの取得
var col = picker.cols[0];
Properties | |
---|---|
col.el | カラムの HTML 要素 |
col.$el | カラムを持つ Dom7 インスタンス HTML コンテナ |
col.items | カラムのアイテムを持つ Dom7 インスタンスの HTML 要素 |
col.value | 現在選択されている列の値 |
col.displayValue | 現在選択されている列の表示値 |
col.activeIndex | 現在選択されている/アクティブなアイテムのインデックス番号 |
Methods | |
col.setValue(value, duration) | 現在のカラムに新しい値を設定します。value は新しい値、 duration` - ms単位の遷移時間 |
col.replaceValues(values, displayValues) | カラムの値と displayValues を新しいものに置き換えます。 |
ピッカーのイベント
ピッカーは、以下のDOMイベントをピッカーエレメントに、イベントをアプリとピッカーインスタンスに発行します。
DOM イベント
Event | Target | Description |
---|---|---|
picker:open | Picker Element<div class="picker"> | イベントは、ピッカーがオープニングアニメーションを開始したときに発生します。 |
picker:opened | Picker Element<div class="picker"> | イベントは、ピッカーがそのオープニングアニメーションを完了した後に発生します。 |
picker:close | Picker Element<div class="picker"> | イベントは、ピッカーが閉じるアニメーションを開始したときに発生します。 |
picker:closed | Picker Element<div class="picker"> | イベントは、ピッカーが閉じるアニメーションを完了した後に発生します。 |
アプリとピッカーインスタンスのイベント
Picker インスタンスは self インスタンスと app インスタンスの両方にイベントを発行します。アプリのインスタンスのイベントは、同じ名前でプレフィックスが picker
となっています。
Event | Target | Arguments | Description |
---|---|---|---|
change | picker | (picker, value, displayValue) | ピッカーの値が変更されるとイベントが発生します。 |
pickerChange | app | ||
init | picker | (picker) | ピッカーが初期化されるとイベントが発生します。 |
pickerInit | app | ||
open | picker | (picker) | ピッカーがアニメーションを開始したときにイベントが発生します。イベントハンドラは、引数としてピッカーのインスタンスを受け取ります。 |
pickerOpen | app | ||
opened | picker | (picker) | イベントは、ピッカーがオープニングアニメーションを完了した後に発生します。As an argument event handler receive picker instance |
pickerOpened | app | ||
close | picker | (picker) | ピッカーが閉じるアニメーションを開始するとイベントが発生します。As an argument event handler receive picker instance |
pickerClose | app | ||
closed | picker | (picker) | イベントは、ピッカーが閉じるアニメーションを完了した後にトリガされます。As an argument event handler receive picker instance |
pickerClosed | app | ||
beforeDestroy | picker | (picker) | イベントはPickerインスタンスが破壊される直前に発生します。ピッカーインスタンスを受け取るイベントハンドラの引数として |
pickerBeforeDestroy | app |
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
Note that commented variables are not specified by default and their values is what they fallback to in this case.
: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);
*/
--f7-picker-item-selected-bg-color: rgba(0, 0, 0, 0.12);
--f7-picker-item-selected-text-color: #000;
}
:root .theme-dark,
:root.theme-dark {
--f7-picker-item-selected-bg-color: rgba(255, 255, 255, 0.1);
--f7-picker-item-selected-text-color: #fff;
}
.ios {
--f7-picker-column-font-size: 20px;
--f7-picker-divider-text-color: #000;
--f7-picker-item-text-color: rgba(0, 0, 0, 0.45);
}
.ios .theme-dark,
.ios.theme-dark {
--f7-picker-divider-text-color: #fff;
--f7-picker-item-text-color: rgba(255, 255, 255, 0.55);
}
.md {
--f7-picker-column-font-size: 20px;
--f7-picker-divider-text-color: rgba(0, 0, 0, 0.87);
--f7-picker-item-text-color: rgba(0, 0, 0, 0.54);
}
.md .theme-dark,
.md.theme-dark {
--f7-picker-item-text-color: rgba(255, 255, 255, 0.54);
--f7-picker-divider-text-color: rgba(255, 255, 255, 0.87);
}
.aurora {
--f7-picker-column-font-size: 20px;
--f7-picker-item-text-color: #888;
--f7-picker-divider-text-color: #000;
}
.aurora .theme-dark,
.aurora.theme-dark {
--f7-picker-divider-text-color: #fff;
}
Examples
<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-title">Picker with single value</div>
<div class="list no-hairlines-md">
<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 no-hairlines-md">
<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 no-hairlines-md">
<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 no-hairlines-md">
<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 no-padding no-margin margin-bottom">
<div id="demo-picker-date-container"></div>
</div>
</div>
</div>
</template>
<script>
export default (props, { $on, $f7 }) => {
$on('pageInit', () => {
var 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']
}
]
});
var 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']
};
var 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
var 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 href="#" class="link toolbar-randomize-link">Randomize</a>' +
'</div>' +
'<div class="right">' +
'<a href="#" 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
var today = new Date();
var 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').split(' '),
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: ' '
},
// 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);
}
},
}
});
})
return $render;
}
</script>