UNPKG

iuap-design

Version:
1,485 lines (1,202 loc) 130 kB
/*! * Mobiscroll v2.13.2 * http://mobiscroll.com * * Copyright 2010-2014, Acid Media * Licensed under the MIT license. * */ (function ($, undefined) { function testProps(props) { var i; for (i in props) { if (mod[props[i]] !== undefined) { return true; } } return false; } function testPrefix() { var prefixes = ['Webkit', 'Moz', 'O', 'ms'], p; for (p in prefixes) { if (testProps([prefixes[p] + 'Transform'])) { return '-' + prefixes[p].toLowerCase() + '-'; } } return ''; } function init(that, options, args) { var ret = that; // Init if (typeof options === 'object') { return that.each(function () { if (!this.id) { this.id = 'mobiscroll' + (++id); } if (instances[this.id]) { instances[this.id].destroy(); } new $.mobiscroll.classes[options.component || 'Scroller'](this, options); }); } // Method call if (typeof options === 'string') { that.each(function () { var r, inst = instances[this.id]; if (inst && inst[options]) { r = inst[options].apply(this, Array.prototype.slice.call(args, 1)); if (r !== undefined) { ret = r; return false; } } }); } return ret; } var id = +new Date(), touches = {}, instances = {}, extend = $.extend, mod = document.createElement('modernizr').style, has3d = testProps(['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']), hasFlex = testProps(['flex', 'msFlex', 'WebkitBoxDirection']), prefix = testPrefix(), pr = prefix.replace(/^\-/, '').replace(/\-$/, '').replace('moz', 'Moz'); $.fn.mobiscroll = function (method) { extend(this, $.mobiscroll.components); return init(this, method, arguments); }; $.mobiscroll = $.mobiscroll || { version: '2.13.2', util: { prefix: prefix, jsPrefix: pr, has3d: has3d, hasFlex: hasFlex, testTouch: function (e) { if (e.type == 'touchstart') { touches[e.target] = true; } else if (touches[e.target]) { delete touches[e.target]; return false; } return true; }, isNumeric: function (a) { return a - parseFloat(a) >= 0; }, getCoord: function (e, c) { var ev = e.originalEvent || e; return ev.changedTouches ? ev.changedTouches[0]['page' + c] : e['page' + c]; }, constrain: function (val, min, max) { return Math.max(min, Math.min(val, max)); } }, tapped: false, presets: { scroller: {}, numpad: {} }, themes: { listview: {} }, i18n: {}, instances: instances, classes: {}, components: {}, defaults: { theme: 'mobiscroll', context: 'body' }, userdef: {}, setDefaults: function (o) { extend(this.userdef, o); }, presetShort: function (name, c, p) { this.components[name] = function (s) { return init(this, extend(s, { component: c, preset: p === false ? undefined : name }), arguments); }; } }; $.scroller = $.scroller || $.mobiscroll; $.fn.scroller = $.fn.scroller || $.fn.mobiscroll; })(jQuery); (function ($) { $.mobiscroll.i18n.zh = $.extend($.mobiscroll.i18n.zh, { // Core setText: '确定', cancelText: '取消', clearText: '明确', selectedText: '选', // Datetime component dateFormat: 'yy/mm/dd', dateOrder: 'yymmdd', dayNames: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], dayNamesShort: ['日', '一', '二', '三', '四', '五', '六'], dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'], dayText: '日', hourText: '时', minuteText: '分', monthNames: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], monthNamesShort: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'], monthText: '月', secText: '秒', timeFormat: 'HH:ii', timeWheels: 'HHii', yearText: '年', nowText: '当前', pmText: '下午', amText: '上午', // Calendar component dateText: '日', timeText: '时间', calendarText: '日历', closeText: '关闭', // Daterange component fromText: '开始时间', toText: '结束时间', // Measurement components wholeText: '合计', fractionText: '分数', unitText: '单位', // Time / Timespan component labels: ['年', '月', '日', '小时', '分钟', '秒', ''], labelsShort: ['年', '月', '日', '点', '分', '秒', ''], // Timer component startText: '开始', stopText: '停止', resetText: '重置', lapText: '圈', hideText: '隐藏' }); })(jQuery); // theme : android (function ($) { $.mobiscroll.themes.android = { dateOrder: 'Mddyy', mode: 'clickpick', height: 50, showLabel: false, btnStartClass: 'mbsc-ic mbsc-ic-play3', btnStopClass: 'mbsc-ic mbsc-ic-pause2', btnResetClass: 'mbsc-ic mbsc-ic-stop2', btnLapClass: 'mbsc-ic mbsc-ic-loop2' }; })(jQuery); // theme : android-holo (function ($) { var themes = $.mobiscroll.themes, theme = { dateOrder: 'Mddyy', //mode: 'mixed', rows: 5, minWidth: 76, height: 36, showLabel: false, selectedLineHeight: true, selectedLineBorder: 2, useShortLabels: true, icon: { filled: 'star3', empty: 'star' }, btnPlusClass: 'mbsc-ic mbsc-ic-arrow-down6', btnMinusClass: 'mbsc-ic mbsc-ic-arrow-up6', // @deprecated since 2.12.0, backward compatibility code // --- onThemeLoad: function (lang, s) { if (s.theme) { s.theme = s.theme.replace('android-ics', 'android-holo').replace(' light', '-light'); } }, // --- onMarkupReady: function (markup) { markup.addClass('mbsc-android-holo'); } }; themes['android-holo'] = theme; themes['android-holo-light'] = theme; // @deprecated since 2.12.0, backward compatibility code themes['android-ics'] = theme; themes['android-ics light'] = theme; themes['android-holo light'] = theme; })(jQuery); // theme : ios (function ($) { $.mobiscroll.themes.ios = { display: 'bottom', dateOrder: 'MMdyy', rows: 5, height: 30, minWidth: 60, headerText: false, showLabel: false, btnWidth: false, selectedLineHeight: true, selectedLineBorder: 2, useShortLabels: true }; })(jQuery); // theme : ios7 (function ($) { $.mobiscroll.themes.ios7 = { display: 'bottom', dateOrder: 'MMdyy', rows: 5, height: 34, minWidth: 55, headerText: false, showLabel: false, btnWidth: false, selectedLineHeight: true, selectedLineBorder: 1, useShortLabels: true, deleteIcon: 'backspace3', checkIcon: 'ion-ios7-checkmark-empty', btnCalPrevClass: 'mbsc-ic mbsc-ic-arrow-left5', btnCalNextClass: 'mbsc-ic mbsc-ic-arrow-right5', btnPlusClass: 'mbsc-ic mbsc-ic-arrow-down5', btnMinusClass: 'mbsc-ic mbsc-ic-arrow-up5' }; })(jQuery); // theme : jquery mobile (function ($) { var ver = $.mobile && $.mobile.version.match(/1\.4/); $.mobiscroll.themes.jqm = { jqmBorder: 'a', jqmBody: ver ? 'a' : 'c', jqmHeader: 'b', jqmWheel: 'd', jqmLine: 'b', jqmClickPick: 'c', jqmSet: 'b', jqmCancel: 'c', disabledClass: 'ui-disabled', activeClass: 'ui-btn-active', activeTabInnerClass: 'ui-btn-active', btnCalPrevClass: '', btnCalNextClass: '', selectedLineHeight: true, selectedLineBorder: 1, onThemeLoad: function (lang, s) { var cal = s.jqmBody || 'c', txt = s.jqmEventText || 'b', bubble = s.jqmEventBubble || 'a'; s.dayClass = 'ui-body-a ui-body-' + cal; s.innerDayClass = 'ui-state-default ui-btn ui-btn-up-' + cal; s.calendarClass = 'ui-body-a ui-body-' + cal; s.weekNrClass = 'ui-body-a ui-body-' + cal; s.eventTextClass = 'ui-btn-up-' + txt; s.eventBubbleClass = 'ui-body-' + bubble; }, onEventBubbleShow: function (evd, evc) { $('.dw-cal-event-list', evc).attr('data-role', 'listview'); evc.page().trigger('create'); }, onMarkupInserted: function (elm, inst) { var s = inst.settings; if (ver) { elm.addClass('mbsc-jqm14'); $('.mbsc-np-btn, .dwwb, .dw-cal-sc-m-cell .dw-i', elm).addClass('ui-btn'); $('.dwbc div.dwb, .dw-dr', elm).addClass('ui-btn ui-mini ui-corner-all'); $('.dw-cal-prev .dw-cal-btn-txt', elm).addClass('ui-btn ui-icon-arrow-l ui-btn-icon-notext ui-shadow ui-corner-all'); $('.dw-cal-next .dw-cal-btn-txt', elm).addClass('ui-btn ui-icon-arrow-r ui-btn-icon-notext ui-shadow ui-corner-all'); } $('.dw', elm).removeClass('dwbg').addClass('ui-selectmenu ui-overlay-shadow ui-corner-all ui-body-' + s.jqmBorder); $('.dwbc .dwb', elm).attr('data-role', 'button').attr('data-mini', 'true').attr('data-theme', s.jqmCancel); $('.dwb-s .dwb', elm).addClass('ui-btn-' + s.jqmSet).attr('data-theme', s.jqmSet); $('.dwwb', elm).attr('data-role', 'button').attr('data-theme', s.jqmClickPick); $('.dwv', elm).addClass('ui-header ui-bar-' + s.jqmHeader); $('.dwwr', elm).addClass('ui-corner-all ui-body-' + s.jqmBody); $('.dwwl', elm).addClass('ui-body-' + s.jqmWheel); $('.dwwol', elm).addClass('ui-body-' + s.jqmLine); $('.dwl', elm).addClass('ui-body-' + s.jqmBody); // Calendar base $('.dw-cal-tabs', elm).attr('data-role', 'navbar'); $('.dw-cal-prev .dw-cal-btn-txt', elm).attr('data-role', 'button').attr('data-icon', 'arrow-l').attr('data-iconpos', 'notext'); $('.dw-cal-next .dw-cal-btn-txt', elm).attr('data-role', 'button').attr('data-icon', 'arrow-r').attr('data-iconpos', 'notext'); // Calendar events $('.dw-cal-events', elm).attr('data-role', 'page'); // Rangepicker $('.dw-dr', elm).attr('data-role', 'button').attr('data-mini', 'true'); // Numpad $('.mbsc-np-btn', elm).attr('data-role', 'button').attr('data-corners', 'false'); elm.trigger('create'); } }; })(jQuery); // theme : sense-ui (function ($) { $.mobiscroll.themes['sense-ui'] = { btnStartClass: 'mbsc-ic mbsc-ic-play3', btnStopClass: 'mbsc-ic mbsc-ic-pause2', btnResetClass: 'mbsc-ic mbsc-ic-stop2', btnLapClass: 'mbsc-ic mbsc-ic-loop2' }; })(jQuery); // theme : windows phone (function ($) { var themes = $.mobiscroll.themes, theme = { minWidth: 76, height: 76, accent: 'none', dateOrder: 'mmMMddDDyy', headerText: false, showLabel: false, deleteIcon: 'backspace4', icon: { filled: 'star3', empty: 'star' }, btnWidth: false, btnStartClass: 'mbsc-ic mbsc-ic-play3', btnStopClass: 'mbsc-ic mbsc-ic-pause2', btnResetClass: 'mbsc-ic mbsc-ic-stop2', btnLapClass: 'mbsc-ic mbsc-ic-loop2', btnHideClass: 'mbsc-ic mbsc-ic-close', btnCalPrevClass: 'mbsc-ic mbsc-ic-arrow-left2', btnCalNextClass: 'mbsc-ic mbsc-ic-arrow-right2', btnPlusClass: 'mbsc-ic mbsc-ic-plus', btnMinusClass: 'mbsc-ic mbsc-ic-minus', onMarkupInserted: function (elm, inst) { var click, touch, active; elm.addClass('mbsc-wp'); $('.dw', elm).addClass('mbsc-wp-' + inst.settings.accent); $('.dwb-s .dwb', elm).addClass('mbsc-ic mbsc-ic-checkmark'); $('.dwb-c .dwb', elm).addClass('mbsc-ic mbsc-ic-close'); $('.dwb-cl .dwb', elm).addClass('mbsc-ic mbsc-ic-close'); $('.dwb-n .dwb', elm).addClass('mbsc-ic mbsc-ic-loop2'); $('.dwwl', elm).on('touchstart mousedown DOMMouseScroll mousewheel', function (e) { if (e.type === 'mousedown' && touch) { return; } touch = e.type === 'touchstart'; click = true; active = $(this).hasClass('wpa'); $('.dwwl', elm).removeClass('wpa'); $(this).addClass('wpa'); }).on('touchmove mousemove', function () { click = false; }).on('touchend mouseup', function (e) { if (click && active && $(e.target).closest('.dw-li').hasClass('dw-sel')) { $(this).removeClass('wpa'); } if (e.type === 'mouseup') { touch = false; } click = false; }); }, onThemeLoad: function (lang, s) { if (lang && lang.dateOrder && !s.dateOrder) { var ord = lang.dateOrder; ord = ord.match(/mm/i) ? ord.replace(/mmMM|mm|MM/, 'mmMM') : ord.replace(/mM|m|M/, 'mM'); ord = ord.match(/dd/i) ? ord.replace(/ddDD|dd|DD/, 'ddDD') : ord.replace(/dD|d|D/, 'dD'); s.dateOrder = ord; } // @deprecated since 2.12.0, backward compatibility code // --- if (s.theme) { s.theme = s.theme.replace(' light', '-light'); } // --- } }; themes.wp = theme; themes['wp-light'] = theme; // @deprecated since 2.12.0, backward compatibility code themes['wp light'] = theme; })(jQuery); (function ($, undefined) { var ms = $.mobiscroll; ms.datetime = { defaults: { shortYearCutoff: '+10', monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], dayNamesMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], monthText: 'Month', amText: 'am', pmText: 'pm', getYear: function (d) { return d.getFullYear(); }, getMonth: function (d) { return d.getMonth(); }, getDay: function (d) { return d.getDate(); }, getDate: function (y, m, d, h, i, s) { return new Date(y, m, d, h || 0, i || 0, s || 0); }, getMaxDayOfMonth: function (y, m) { return 32 - new Date(y, m, 32).getDate(); }, getWeekNumber: function (d) { // Copy date so don't modify original d = new Date(d); d.setHours(0, 0, 0); // Set to nearest Thursday: current date + 4 - current day number // Make Sunday's day number 7 d.setDate(d.getDate() + 4 - (d.getDay() || 7)); // Get first day of year var yearStart = new Date(d.getFullYear(), 0, 1); // Calculate full weeks to nearest Thursday return Math.ceil((((d - yearStart) / 86400000) + 1) / 7); } }, /** * Format a date into a string value with a specified format. * @param {String} format Output format. * @param {Date} date Date to format. * @param {Object} [settings={}] Settings. * @return {String} Returns the formatted date string. */ formatDate: function (format, date, settings) { if (!date) { return null; } var s = $.extend({}, ms.datetime.defaults, settings), look = function (m) { // Check whether a format character is doubled var n = 0; while (i + 1 < format.length && format.charAt(i + 1) == m) { n++; i++; } return n; }, f1 = function (m, val, len) { // Format a number, with leading zero if necessary var n = '' + val; if (look(m)) { while (n.length < len) { n = '0' + n; } } return n; }, f2 = function (m, val, s, l) { // Format a name, short or long as requested return (look(m) ? l[val] : s[val]); }, i, year, output = '', literal = false; for (i = 0; i < format.length; i++) { if (literal) { if (format.charAt(i) == "'" && !look("'")) { literal = false; } else { output += format.charAt(i); } } else { switch (format.charAt(i)) { case 'd': output += f1('d', s.getDay(date), 2); break; case 'D': output += f2('D', date.getDay(), s.dayNamesShort, s.dayNames); break; case 'o': output += f1('o', (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3); break; case 'm': output += f1('m', s.getMonth(date) + 1, 2); break; case 'M': output += f2('M', s.getMonth(date), s.monthNamesShort, s.monthNames); break; case 'y': year = s.getYear(date); output += (look('y') ? year : (year % 100 < 10 ? '0' : '') + year % 100); //output += (look('y') ? date.getFullYear() : (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); break; case 'h': var h = date.getHours(); output += f1('h', (h > 12 ? (h - 12) : (h === 0 ? 12 : h)), 2); break; case 'H': output += f1('H', date.getHours(), 2); break; case 'i': output += f1('i', date.getMinutes(), 2); break; case 's': output += f1('s', date.getSeconds(), 2); break; case 'a': output += date.getHours() > 11 ? s.pmText : s.amText; break; case 'A': output += date.getHours() > 11 ? s.pmText.toUpperCase() : s.amText.toUpperCase(); break; case "'": if (look("'")) { output += "'"; } else { literal = true; } break; default: output += format.charAt(i); } } } return output; }, /** * Extract a date from a string value with a specified format. * @param {String} format Input format. * @param {String} value String to parse. * @param {Object} [settings={}] Settings. * @return {Date} Returns the extracted date. */ parseDate: function (format, value, settings) { var s = $.extend({}, ms.datetime.defaults, settings), def = s.defaultValue || new Date(); if (!format || !value) { return def; } // If already a date object if (value.getTime) { return value; } value = (typeof value == 'object' ? value.toString() : value + ''); var shortYearCutoff = s.shortYearCutoff, year = s.getYear(def), month = s.getMonth(def) + 1, day = s.getDay(def), doy = -1, hours = def.getHours(), minutes = def.getMinutes(), seconds = 0, //def.getSeconds(), ampm = -1, literal = false, // Check whether a format character is doubled lookAhead = function (match) { var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); if (matches) { iFormat++; } return matches; }, getNumber = function (match) { // Extract a number from the string value lookAhead(match); var size = (match == '@' ? 14 : (match == '!' ? 20 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))), digits = new RegExp('^\\d{1,' + size + '}'), num = value.substr(iValue).match(digits); if (!num) { return 0; } iValue += num[0].length; return parseInt(num[0], 10); }, getName = function (match, s, l) { // Extract a name from the string value and convert to an index var names = (lookAhead(match) ? l : s), i; for (i = 0; i < names.length; i++) { if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) { iValue += names[i].length; return i + 1; } } return 0; }, checkLiteral = function () { iValue++; }, iValue = 0, iFormat; for (iFormat = 0; iFormat < format.length; iFormat++) { if (literal) { if (format.charAt(iFormat) == "'" && !lookAhead("'")) { literal = false; } else { checkLiteral(); } } else { switch (format.charAt(iFormat)) { case 'd': day = getNumber('d'); break; case 'D': getName('D', s.dayNamesShort, s.dayNames); break; case 'o': doy = getNumber('o'); break; case 'm': month = getNumber('m'); break; case 'M': month = getName('M', s.monthNamesShort, s.monthNames); break; case 'y': year = getNumber('y'); break; case 'H': hours = getNumber('H'); break; case 'h': hours = getNumber('h'); break; case 'i': minutes = getNumber('i'); break; case 's': seconds = getNumber('s'); break; case 'a': ampm = getName('a', [s.amText, s.pmText], [s.amText, s.pmText]) - 1; break; case 'A': ampm = getName('A', [s.amText, s.pmText], [s.amText, s.pmText]) - 1; break; case "'": if (lookAhead("'")) { checkLiteral(); } else { literal = true; } break; default: checkLiteral(); } } } if (year < 100) { year += new Date().getFullYear() - new Date().getFullYear() % 100 + (year <= (typeof shortYearCutoff != 'string' ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)) ? 0 : -100); } if (doy > -1) { month = 1; day = doy; do { var dim = 32 - new Date(year, month - 1, 32).getDate(); if (day <= dim) { break; } month++; day -= dim; } while (true); } hours = (ampm == -1) ? hours : ((ampm && hours < 12) ? (hours + 12) : (!ampm && hours == 12 ? 0 : hours)); var date = s.getDate(year, month - 1, day, hours, minutes, seconds); if (s.getYear(date) != year || s.getMonth(date) + 1 != month || s.getDay(date) != day) { return def; // Invalid date } return date; } }; // @deprecated since 2.11.0, backward compatibility code // --- ms.formatDate = ms.datetime.formatDate; ms.parseDate = ms.datetime.parseDate; // --- })(jQuery); (function ($, window, document, undefined) { var $activeElm, preventShow, extend = $.extend, ms = $.mobiscroll, instances = ms.instances, userdef = ms.userdef, util = ms.util, pr = util.jsPrefix, has3d = util.has3d, getCoord = util.getCoord, constrain = util.constrain, isOldAndroid = /android [1-3]/i.test(navigator.userAgent), animEnd = 'webkitAnimationEnd animationend', empty = function () { }, prevdef = function (ev) { ev.preventDefault(); }; ms.classes.Widget = function (el, settings, inherit) { var $ariaDiv, $ctx, $header, $markup, $overlay, $persp, $popup, $wnd, $wrapper, buttons, btn, doAnim, hasButtons, isModal, lang, modalWidth, modalHeight, posEvents, preset, preventPos, s, scrollLock, setReadOnly, theme, wasReadOnly, wndWidth, wndHeight, that = this, $elm = $(el), elmList = [], posDebounce = {}; function onBtnStart(ev) { // Can't call preventDefault here, it kills page scroll if (btn) { btn.removeClass('dwb-a'); } btn = $(this); // Active button if (!btn.hasClass('dwb-d') && !btn.hasClass('dwb-nhl')) { btn.addClass('dwb-a'); } if (ev.type === 'mousedown') { $(document).on('mouseup', onBtnEnd); } } function onBtnEnd(ev) { if (btn) { btn.removeClass('dwb-a'); btn = null; } if (ev.type === 'mouseup') { $(document).off('mouseup', onBtnEnd); } } function onShow(prevFocus) { if (!prevFocus) { $popup.focus(); } that.ariaMessage(s.ariaMessage); } function onHide(prevAnim) { var activeEl, value, type, focus = s.focusOnClose; $markup.remove(); if ($activeElm && !prevAnim) { setTimeout(function () { if (focus === undefined) { preventShow = true; activeEl = $activeElm[0]; type = activeEl.type; value = activeEl.value; try { activeEl.type = 'button'; } catch (ex) { } $activeElm.focus(); activeEl.type = type; activeEl.value = value; } else if (focus) { // If a mobiscroll field is focused, allow show if (instances[$(focus).attr('id')]) { ms.tapped = false; } $(focus).focus(); } }, 200); } that._isVisible = false; event('onHide', []); } function onPosition(ev) { clearTimeout(posDebounce[ev.type]); posDebounce[ev.type] = setTimeout(function () { var isScroll = ev.type == 'scroll'; if (isScroll && !scrollLock) { return; } that.position(!isScroll); }, 200); } function event(name, args) { var ret; args.push(that); $.each([userdef, theme, preset, settings], function (i, v) { if (v && v[name]) { // Call preset event ret = v[name].apply(el, args); } }); return ret; } /** * Positions the scroller on the screen. */ that.position = function (check) { var w, l, t, anchor, aw, // anchor width ah, // anchor height ap, // anchor position at, // anchor top al, // anchor left arr, // arrow arrw, // arrow width arrl, // arrow left dh, scroll, sl, // scroll left st, // scroll top totalw = 0, minw = 0, css = {}, nw = Math.min($wnd[0].innerWidth || $wnd.innerWidth(), $persp.width()), //$persp.width(), // To get the width without scrollbar nh = $wnd[0].innerHeight || $wnd.innerHeight(); if ((wndWidth === nw && wndHeight === nh && check) || preventPos) { return; } if (isModal && that._isLiquid && s.display!== 'bubble') { // Set width, if document is larger than viewport, needs to be set before onPosition (for calendar) $popup.width(nw); } if (event('onPosition', [$markup, nw, nh]) === false || !isModal) { return; } sl = $wnd.scrollLeft(); st = $wnd.scrollTop(); anchor = s.anchor === undefined ? $elm : $(s.anchor); // Set / unset liquid layout based on screen width, but only if not set explicitly by the user if (that._isLiquid && s.layout !== 'liquid') { if (nw < 400) { $markup.addClass('dw-liq'); } else { $markup.removeClass('dw-liq'); } } if (/modal|bubble/.test(s.display)) { $wrapper.width(''); $('.mbsc-w-p', $markup).each(function () { w = $(this).outerWidth(true); totalw += w; minw = (w > minw) ? w : minw; }); w = totalw > nw ? minw : totalw; $wrapper.width(w).css('white-space', totalw > nw ? '' : 'nowrap'); } modalWidth = $popup.outerWidth(); modalHeight = $popup.outerHeight(true); scrollLock = modalHeight <= nh && modalWidth <= nw; that.scrollLock = scrollLock; if (s.display == 'modal') { l = Math.max(0, sl + (nw - modalWidth) / 2); t = st + (nh - modalHeight) / 2; } else if (s.display == 'bubble') { scroll = true; arr = $('.dw-arrw-i', $markup); ap = anchor.offset(); at = Math.abs($ctx.offset().top - ap.top); al = Math.abs($ctx.offset().left - ap.left); // horizontal positioning aw = anchor.outerWidth(); ah = anchor.outerHeight(); l = constrain(al - ($popup.outerWidth(true) - aw) / 2, sl + 3, sl + nw - modalWidth - 3); // vertical positioning t = at - modalHeight; // above the input if ((t < st) || (at > st + nh)) { // if doesn't fit above or the input is out of the screen $popup.removeClass('dw-bubble-top').addClass('dw-bubble-bottom'); t = at + ah; // below the input } else { $popup.removeClass('dw-bubble-bottom').addClass('dw-bubble-top'); } // Calculate Arrow position arrw = arr.outerWidth(); arrl = constrain(al + aw / 2 - (l + (modalWidth - arrw) / 2), 0, arrw); // Limit Arrow position $('.dw-arr', $markup).css({ left: arrl }); } else { l = sl; if (s.display == 'top') { t = st; } else if (s.display == 'bottom') { t = st + nh - modalHeight; } } t = t < 0 ? 0 : t; css.top = t; css.left = l; $popup.css(css); // If top + modal height > doc height, increase doc height $persp.height(0); dh = Math.max(t + modalHeight, s.context == 'body' ? $(document).height() : $ctx[0].scrollHeight); $persp.css({ height: dh }); // Scroll needed if (scroll && ((t + modalHeight > st + nh) || (at > st + nh))) { preventPos = true; setTimeout(function () { preventPos = false; }, 300); $wnd.scrollTop(Math.min(t + modalHeight - nh, dh - nh)); } wndWidth = nw; wndHeight = nh; }; /** * Show mobiscroll on focus and click event of the parameter. * @param {jQuery} $elm - Events will be attached to this element. * @param {Function} [beforeShow=undefined] - Optional function to execute before showing mobiscroll. */ that.attachShow = function ($elm, beforeShow) { elmList.push($elm); if (s.display !== 'inline') { $elm .on('mousedown.dw', function (ev) { if (setReadOnly) { // Prevent input to get focus on tap (virtual keyboard pops up on some devices) ev.preventDefault(); } }) .on((s.showOnFocus ? 'focus.dw' : '') + (s.showOnTap ? ' click.dw' : ''), function (ev) { if ((ev.type !== 'focus' || (ev.type === 'focus' && !preventShow)) && !ms.tapped) { if (beforeShow) { beforeShow(); } // Hide virtual keyboard if ($(document.activeElement).is('input,textarea')) { $(document.activeElement).blur(); } $activeElm = $elm; that.show(); } setTimeout(function () { preventShow = false; }, 300); // With jQuery < 1.9 focus is fired twice in IE }); } }; /** * Set button handler. */ that.select = function () { if (!isModal || that.hide(false, 'set') !== false) { that._fillValue(); event('onSelect', [that.val]); } }; /** * Cancel and hide the scroller instance. */ that.cancel = function () { if (!isModal || that.hide(false, 'cancel') !== false) { event('onCancel', [that.val]); } }; /** * Clear button handler. */ that.clear = function () { event('onClear', [$markup]); if (isModal && !that.live) { that.hide(false, 'clear'); } that.setValue(null, true); }; /** * Enables the scroller and the associated input. */ that.enable = function () { s.disabled = false; if (that._isInput) { $elm.prop('disabled', false); } }; /** * Disables the scroller and the associated input. */ that.disable = function () { s.disabled = true; if (that._isInput) { $elm.prop('disabled', true); } }; /** * Shows the scroller instance. * @param {Boolean} prevAnim - Prevent animation if true * @param {Boolean} prevFocus - Prevent focusing if true */ that.show = function (prevAnim, prevFocus) { // Create wheels var html; if (s.disabled || that._isVisible) { return; } if (doAnim !== false) { if (s.display == 'top') { doAnim = 'slidedown'; } if (s.display == 'bottom') { doAnim = 'slideup'; } } // Parse value from input that._readValue(); event('onBeforeShow', []); // Create wheels containers html = '<div lang="' + s.lang + '" class="mbsc-' + s.theme + ' dw-' + s.display + ' ' + (s.cssClass || '') + (that._isLiquid ? ' dw-liq' : '') + (isOldAndroid ? ' mbsc-old' : '') + (hasButtons ? '' : ' dw-nobtn') + '">' + '<div class="dw-persp">' + (isModal ? '<div class="dwo"></div>' : '') + // Overlay '<div' + (isModal ? ' role="dialog" tabindex="-1"' : '') + ' class="dw' + (s.rtl ? ' dw-rtl' : ' dw-ltr') + '">' + // Popup (s.display === 'bubble' ? '<div class="dw-arrw"><div class="dw-arrw-i"><div class="dw-arr"></div></div></div>' : '') + // Bubble arrow '<div class="dwwr">' + // Popup content '<div aria-live="assertive" class="dw-aria dw-hidden"></div>' + (s.headerText ? '<div class="dwv">' + s.headerText + '</div>' : '') + // Header '<div class="dwcc">'; // Wheel group container html += that._generateContent(); html += '</div>'; if (hasButtons) { html += '<div class="dwbc">'; $.each(buttons, function (i, b) { b = (typeof b === 'string') ? that.buttons[b] : b; html += '<div' + (s.btnWidth ? ' style="width:' + (100 / buttons.length) + '%"' : '') + ' class="dwbw ' + b.css + '"><div tabindex="0" role="button" class="dwb dwb' + i + ' dwb-e">' + b.text + '</div></div>'; }); html += '</div>'; } html += '</div></div></div></div>'; $markup = $(html); $persp = $('.dw-persp', $markup); $overlay = $('.dwo', $markup); $wrapper = $('.dwwr', $markup); $header = $('.dwv', $markup); $popup = $('.dw', $markup); $ariaDiv = $('.dw-aria', $markup); that._markup = $markup; that._header = $header; that._isVisible = true; posEvents = 'orientationchange resize'; that._markupReady(); event('onMarkupReady', [$markup]); // Show if (isModal) { // Enter / ESC $(window).on('keydown.dw', function (ev) { if (ev.keyCode == 13) { that.select(); } else if (ev.keyCode == 27) { that.cancel(); } }); // Prevent scroll if not specified otherwise if (s.scrollLock) { $markup.on('touchstart touchmove', function (ev) { if (scrollLock) { ev.preventDefault(); } }); } // Disable inputs to prevent bleed through (Android bug) if (pr !== 'Moz') { $('input,select,button', $ctx).each(function () { if (!this.disabled) { $(this).addClass('dwtd').prop('disabled', true); } }); } posEvents += ' scroll'; ms.activeInstance = that; $markup.appendTo($ctx); if (has3d && doAnim && !prevAnim) { $markup.addClass('dw-in dw-trans').on(animEnd, function () { $markup.removeClass('dw-in dw-trans').find('.dw').removeClass('dw-' + doAnim); onShow(prevFocus); }).find('.dw').addClass('dw-' + doAnim); } } else if ($elm.is('div')) { $elm.html($markup); } else { $markup.insertAfter($elm); } event('onMarkupInserted', [$markup]); // Set position that.position(); $wnd.on(posEvents, onPosition); // Events $markup .on('selectstart mousedown', prevdef) // Prevents blue highlight on Android and text selection in IE .on('click', '.dwb-e', prevdef) .on('keydown', '.dwb-e', function (ev) { if (ev.keyCode == 32) { // Space ev.preventDefault(); ev.stopPropagation(); $(this).click(); } }); setTimeout(function () { // Init buttons $.each(buttons, function (i, b) { that.tap($('.dwb' + i, $markup), function (ev) { b = (typeof b === 'string') ? that.buttons[b] : b; b.handler.call(this, ev, that); }, true); }); if (s.closeOnOverlay) { that.tap($overlay, function () { that.cancel(); }); } if (isModal && !doAnim) { onShow(prevFocus); } $markup .on('touchstart mousedown', '.dwb-e', onBtnStart) .on('touchend', '.dwb-e', onBtnEnd); that._attachEvents($markup); }, 300); event('onShow', [$markup, that._valueText]); }; /** * Hides the scroller instance. */ that.hide = function (prevAnim, btn, force) { // If onClose handler returns false, prevent hide if (!that._isVisible || (!force && !that._isValid && btn == 'set') || (!force && event('onClose', [that._valueText, btn]) === false)) { return false; } // Hide wheels and overlay if ($markup) { // Re-enable temporary disabled fields if (pr !== 'Moz') { $('.dwtd', $ctx).each(function () { $(this).prop('disabled', false).removeClass('dwtd'); }); } if (has3d && isModal && doAnim && !prevAnim && !$markup.hasClass('dw-trans')) { // If dw-trans class was not removed, means that there was no animation $markup.addClass('dw-out dw-trans').find('.dw').addClass('dw-' + doAnim).on(animEnd, function () { onHide(prevAnim); }); } else { onHide(prevAnim); } // Stop positioning on window resize $wnd.off(posEvents, onPosition); } delete ms.activeInstance; }; that.ariaMessage = function (txt) { $ariaDiv.html(''); setTimeout(function () { $ariaDiv.html(txt); }, 100); }; /** * Return true if the scroller is currently visible. */ that.isVisible = function () { return that._isVisible; }; // Protected functions to override that.setValue = empty; that._generateContent = empty; that._attachEvents = empty; that._readValue = empty; that._fillValue = empty; that._markupReady = empty; that._processSettings = empty; // Generic widget functions /** * Attach tap event to the given element. */ that.tap = function (el, handler, prevent) { var startX, startY, moved; if (s.tap) { el.on('touchstart.dw', function (ev) { // Can't always call preventDefault here, it kills page scroll