UNPKG

better-picker

Version:

h5 picker inspired by ios UIPickerView

189 lines (163 loc) 4.82 kB
import BScroll from 'better-scroll'; import EventEmitter from '../util/eventEmitter'; import {extend} from '../util/lang'; import { createDom, addEvent, addClass, removeClass } from '../util/dom'; import pickerTemplate from './picker.handlebars'; import itemTemplate from './item.handlebars'; import './picker.styl'; export default class Picker extends EventEmitter { constructor(options) { super(); this.options = { data: [], title: '', selectedIndex: null, showCls: 'show' }; extend(this.options, options); this.data = this.options.data; this.pickerEl = createDom(pickerTemplate({ data: this.data, title: this.options.title })); document.body.appendChild(this.pickerEl); this.maskEl = this.pickerEl.getElementsByClassName('mask-hook')[0]; this.wheelEl = this.pickerEl.getElementsByClassName('wheel-hook'); this.panelEl = this.pickerEl.getElementsByClassName('panel-hook')[0]; this.confirmEl = this.pickerEl.getElementsByClassName('confirm-hook')[0]; this.cancelEl = this.pickerEl.getElementsByClassName('cancel-hook')[0]; this.scrollEl = this.pickerEl.getElementsByClassName('wheel-scroll-hook'); this._init(); } _init() { this.selectedIndex = []; this.selectedVal = []; if (this.options.selectedIndex) { this.selectedIndex = this.options.selectedIndex; } else { for (let i = 0; i < this.data.length; i++) { this.selectedIndex[i] = 0; } } this._bindEvent(); } _bindEvent() { addEvent(this.pickerEl, 'touchmove', (e) => { e.preventDefault(); }); addEvent(this.confirmEl, 'click', () => { this.hide(); let changed = false; for (let i = 0; i < this.data.length; i++) { let index = this.wheels[i].getSelectedIndex(); this.selectedIndex[i] = index; let value = null; if (this.data[i].length) { value = this.data[i][index].value; } if (this.selectedVal[i] !== value) { changed = true; } this.selectedVal[i] = value; } this.trigger('picker.select', this.selectedVal, this.selectedIndex); if (changed) { this.trigger('picker.valuechange', this.selectedVal, this.selectedIndex); } }); addEvent(this.cancelEl, 'click', () => { this.hide(); this.trigger('picker.cancel'); }); } _createWheel(wheelEl, i) { this.wheels[i] = new BScroll(wheelEl[i], { wheel: true, selectedIndex: this.selectedIndex[i] }); ((index) => { this.wheels[index].on('scrollEnd', () => { let currentIndex = this.wheels[index].getSelectedIndex(); if (this.selectedIndex[i] !== currentIndex) { this.selectedIndex[i] = currentIndex; this.trigger('picker.change', index, currentIndex); } }); })(i); return this.wheels[i]; } show(next) { this.pickerEl.style.display = 'block'; let showCls = this.options.showCls; window.setTimeout(() => { addClass(this.maskEl, showCls); addClass(this.panelEl, showCls); if (!this.wheels) { this.wheels = []; for (let i = 0; i < this.data.length; i++) { this._createWheel(this.wheelEl, i); } } else { for (let i = 0; i < this.data.length; i++) { this.wheels[i].enable(); this.wheels[i].wheelTo(this.selectedIndex[i]); } } next && next(); }, 0); } hide() { let showCls = this.options.showCls; removeClass(this.maskEl, showCls); removeClass(this.panelEl, showCls); window.setTimeout(() => { this.pickerEl.style.display = 'none'; for (let i = 0; i < this.data.length; i++) { this.wheels[i].disable(); } }, 500); } refillColumn(index, data) { let scrollEl = this.scrollEl[index]; let wheel = this.wheels[index]; if (scrollEl && wheel) { let oldData = this.data[index]; this.data[index] = data; scrollEl.innerHTML = itemTemplate(data); let selectedIndex = wheel.getSelectedIndex(); let dist = 0; if (oldData.length) { let oldValue = oldData[selectedIndex].value; for (let i = 0; i < data.length; i++) { if (data[i].value === oldValue) { dist = i; break; } } } this.selectedIndex[index] = dist; wheel.refresh(); wheel.wheelTo(dist); return dist; } } refill(datas) { let ret = []; if (!datas.length) { return ret; } datas.forEach((data, index) => { ret[index] = this.refillColumn(index, data); }); return ret; } scrollColumn(index, dist) { let wheel = this.wheels[index]; wheel.wheelTo(dist); } }