iuap-design
Version:
UI Framework Used For Enterprise.
1,485 lines (1,202 loc) • 130 kB
JavaScript
/*!
* 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