libreoffice-online/browser/js/w2ui-1.5.rc1.js
Szymon Kłos c991563fa9 Color selector: add no-fill as button
Make it more unified with "Office" color picker.
Use styling from jsdialog for color picker to match
all other ui components.

Unified with existing "Automatic" button for font color.

Signed-off-by: Szymon Kłos <szymon.klos@collabora.com>
Change-Id: I93d1031eaa7d3f3d52dc1812657eef20f4b88a82
2024-01-10 21:22:19 +01:00

6523 lines
316 KiB
JavaScript

/* -*- js-indent-level: 8 -*- */
/* w2ui 1.5.rc1 (nightly) (c) http://w2ui.com, vitmalina@gmail.com */
var w2ui = w2ui || {};
var w2obj = w2obj || {}; // expose object to be able to overwrite default functions
/************************************************
* Library: Web 2.0 UI for jQuery
* - Following objects are defines
* - w2ui - object that will contain all widgets
* - w2obj - object with widget prototypes
* - w2utils - basic utilities
* - $().w2render - common render
* - $().w2destroy - common destroy
* - $().w2marker - marker plugin
* - $().w2tag - tag plugin
* - $().w2overlay - overlay plugin
* - $().w2menu - menu plugin
* - w2utils.event - generic event object
* - Dependencies: jQuery
*
* == NICE TO HAVE ==
* - overlay should be displayed where more space (on top or on bottom)
* - write and article how to replace certain framework functions
* - add maxHeight for the w2menu
* - add time zone
* - TEST On IOS
* - $().w2marker() -- only unmarks first instance
* - subitems for w2menus()
* - add w2utils.lang wrap for all captions in all buttons.
* - $().w2date(), $().w2dateTime()
*
************************************************/
var w2utils = (function ($) {
var tmp = {}; // for some temp variables
var obj = {
version : '1.5.RC1',
settings : {
"locale" : "en-us",
"dateFormat" : "m/d/yyyy",
"timeFormat" : "hh:mi pm",
"datetimeFormat" : "m/d/yyyy|hh:mi pm",
"currencyPrefix" : "$",
"currencySuffix" : "",
"currencyPrecision" : 2,
"groupSymbol" : ",",
"decimalSymbol" : ".",
"shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
"shortdays" : ["M", "T", "W", "T", "F", "S", "S"],
"fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
"weekStarts" : "M", // can be "M" for Monday or "S" for Sunday
"dataType" : 'HTTPJSON', // can be HTTP, HTTPJSON, RESTFULL, RESTFULLJSON, JSON (case sensitive)
"phrases" : {}, // empty object for english phrases
"dateStartYear" : 1950, // start year for date-picker
"dateEndYear" : 2020 // end year for date picker
},
isBin : isBin,
isInt : isInt,
isFloat : isFloat,
isMoney : isMoney,
isHex : isHex,
isAlphaNumeric : isAlphaNumeric,
isEmail : isEmail,
isDate : isDate,
isTime : isTime,
isDateTime : isDateTime,
age : age,
interval : interval,
date : date,
formatSize : formatSize,
formatNumber : formatNumber,
formatDate : formatDate,
formatTime : formatTime,
formatDateTime : formatDateTime,
stripTags : stripTags,
encodeTags : encodeTags,
decodeTags : decodeTags,
escapeId : escapeId,
base64encode : base64encode,
base64decode : base64decode,
md5 : md5,
transition : transition,
lock : lock,
unlock : unlock,
message : message,
lang : lang,
locale : locale,
getSize : getSize,
getStrWidth : getStrWidth,
scrollBarSize : scrollBarSize,
checkName : checkName,
checkUniqueId : checkUniqueId,
parseRoute : parseRoute,
cssPrefix : cssPrefix,
getCursorPosition : getCursorPosition,
setCursorPosition : setCursorPosition,
testLocalStorage : testLocalStorage,
hasLocalStorage : testLocalStorage(),
// some internal variables
isIOS : ((navigator.userAgent.toLowerCase().indexOf('iphone') != -1 ||
navigator.userAgent.toLowerCase().indexOf('ipod') != -1 ||
navigator.userAgent.toLowerCase().indexOf('ipad') != -1)
? true : false),
isIE : ((navigator.userAgent.toLowerCase().indexOf('msie') != -1 ||
navigator.userAgent.toLowerCase().indexOf('trident') != -1 )
? true : false)
};
return obj;
function isBin (val) {
var re = /^[0-1]+$/;
return re.test(val);
}
function isInt (val) {
var re = /^[-+]?[0-9]+$/;
return re.test(val);
}
function isFloat (val) {
if (typeof val == 'string') val = val.replace(/\s+/g, '').replace(w2utils.settings.groupSymbol, '').replace(w2utils.settings.decimalSymbol, '.');
return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val));
}
function isMoney (val) {
var se = w2utils.settings;
var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +
'[-+]?'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +
'[0-9]*[\\'+ se.decimalSymbol +']?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i');
if (typeof val === 'string') {
val = val.replace(new RegExp(se.groupSymbol, 'g'), '');
}
if (typeof val === 'object' || val === '') return false;
return re.test(val);
}
function isHex (val) {
var re = /^[a-fA-F0-9]+$/;
return re.test(val);
}
function isAlphaNumeric (val) {
var re = /^[a-zA-Z0-9_-]+$/;
return re.test(val);
}
function isEmail (val) {
var email = /^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
return email.test(val);
}
function isDate (val, format, retDate) {
if (!val) return false;
var dt = 'Invalid Date';
var month, day, year;
if (format == null) format = w2utils.settings.dateFormat;
if (typeof val.getUTCFullYear === 'function') { // date object
year = val.getUTCFullYear();
month = val.getUTCMonth() + 1;
day = val.getUTCDate();
} else if (parseInt(val) == val && parseInt(val) > 0) {
val = new Date(parseInt(val));
year = val.getUTCFullYear();
month = val.getUTCMonth() + 1;
day = val.getUTCDate();
} else {
val = String(val);
// convert month formats
if (new RegExp('mon', 'ig').test(format)) {
format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase();
val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase();
for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) {
var t = w2utils.settings.fullmonths[m];
val = val.replace(new RegExp(t, 'ig'), (parseInt(m) + 1)).replace(new RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1));
}
}
// format date
var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/');
var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase();
if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; }
if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; }
if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; }
if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; }
if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; }
if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; }
if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; }
if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; }
if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; }
if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; }
if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; }
if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; }
if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; }
if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; }
if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; }
if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; }
}
if (!isInt(year)) return false;
if (!isInt(month)) return false;
if (!isInt(day)) return false;
year = +year;
month = +month;
day = +day;
dt = new Date(year, month - 1, day);
// do checks
if (month == null) return false;
if (String(dt) == 'Invalid Date') return false;
if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false;
if (retDate === true) return dt; else return true;
}
function isTime (val, retTime) {
// Both formats 10:20pm and 22:20
if (val == null) return false;
var max, am, pm;
// -- process american format
val = String(val);
val = val.toUpperCase();
am = val.indexOf('AM') >= 0;
pm = val.indexOf('PM') >= 0;
var ampm = (pm || am);
if (ampm) max = 12; else max = 24;
val = val.replace('AM', '').replace('PM', '');
val = $.trim(val);
// ---
var tmp = val.split(':');
var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0), s = parseInt(tmp[2] || 0);
// accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT:
if ((!ampm || tmp.length !== 1) && tmp.length !== 2 && tmp.length !== 3) { return false; }
if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; }
if (tmp.length > 1 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; }
if (tmp.length > 2 && (tmp[2] === '' || s < 0 || s > 59 || !this.isInt(tmp[2]) || tmp[2].length !== 2)) { return false; }
// check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00).
// meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are.
if (!ampm && max === h && (m !== 0 || s !== 0)) { return false; }
if (ampm && tmp.length === 1 && h === 0) { return false; }
if (retTime === true) {
if (pm && h !== 12) h += 12; // 12:00pm - is noon
if (am && h === 12) h += 12; // 12:00am - is midnight
return {
hours: h,
minutes: m,
seconds: s
};
}
return true;
}
function isDateTime (val, format, retDate) {
if (format == null) format = w2utils.settings.datetimeFormat;
var formats = format.split('|');
if (typeof val.getUTCFullYear === 'function') { // date object
if (retDate !== true) return true;
return val;
} else if (parseInt(val) == val && parseInt(val) > 0) {
val = new Date(parseInt(val));
if (retDate !== true) return true;
return val;
} else {
var tmp = String(val).indexOf(' ');
var values = [val.substr(0, tmp), val.substr(tmp).trim()];
formats[0] = formats[0].trim();
if (formats[1]) formats[1] = formats[1].trim();
// check
var tmp1 = w2utils.isDate(values[0], formats[0], true);
var tmp2 = w2utils.isTime(values[1], true);
if (tmp1 !== false && tmp2 !== false) {
if (retDate !== true) return true;
tmp1.setHours(tmp2.hours);
tmp1.setMinutes(tmp2.minutes);
tmp1.setSeconds(tmp2.seconds);
return tmp1;
} else {
return false;
}
}
}
function age(dateStr) {
var d1;
if (dateStr === '' || dateStr == null) return '';
if (typeof dateStr.getUTCFullYear === 'function') { // date object
d1 = dateStr;
} else if (parseInt(dateStr) == dateStr && parseInt(dateStr) > 0) {
d1 = new Date(parseInt(dateStr));
} else {
d1 = new Date(dateStr);
}
if (String(d1) == 'Invalid Date') return '';
var d2 = new Date();
var sec = (d2.getTime() - d1.getTime()) / 1000;
var amount = '';
var type = '';
if (sec < 0) {
amount = 0;
type = 'sec';
} else if (sec < 60) {
amount = Math.floor(sec);
type = 'sec';
if (sec < 0) { amount = 0; type = 'sec'; }
} else if (sec < 60*60) {
amount = Math.floor(sec/60);
type = 'min';
} else if (sec < 24*60*60) {
amount = Math.floor(sec/60/60);
type = 'hour';
} else if (sec < 30*24*60*60) {
amount = Math.floor(sec/24/60/60);
type = 'day';
} else if (sec < 365*24*60*60) {
amount = Math.floor(sec/30/24/60/60*10)/10;
type = 'month';
} else if (sec < 365*4*24*60*60) {
amount = Math.floor(sec/365/24/60/60*10)/10;
type = 'year';
} else if (sec >= 365*4*24*60*60) {
// factor in leap year shift (only older then 4 years)
amount = Math.floor(sec/365.25/24/60/60*10)/10;
type = 'year';
}
return amount + ' ' + type + (amount > 1 ? 's' : '');
}
function interval (value) {
var ret = '';
if (value < 1000) {
ret = "< 1 sec";
} else if (value < 60000) {
ret = Math.floor(value / 1000) + " secs";
} else if (value < 3600000) {
ret = Math.floor(value / 60000) + " mins";
} else if (value < 86400000) {
ret = Math.floor(value / 3600000 * 10) / 10 + " hours";
} else if (value < 2628000000) {
ret = Math.floor(value / 86400000 * 10) / 10 + " days";
} else if (value < 3.1536e+10) {
ret = Math.floor(value / 2628000000 * 10) / 10 + " months";
} else {
ret = Math.floor(value / 3.1536e+9) / 10 + " years";
}
return ret;
}
function date (dateStr) {
if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return '';
var d1 = new Date(dateStr);
if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps
if (String(d1) == 'Invalid Date') return '';
var months = w2utils.settings.shortmonths;
var d2 = new Date(); // today
var d3 = new Date();
d3.setTime(d3.getTime() - 86400000); // yesterday
var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear();
var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear();
var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear();
var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am');
var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am');
var dsp = dd1;
if (dd1 === dd2) dsp = time;
if (dd1 === dd3) dsp = w2utils.lang('Yesterday');
return '<span title="'+ dd1 +' ' + time2 +'">'+ dsp +'</span>';
}
function formatSize (sizeStr) {
if (!w2utils.isFloat(sizeStr) || sizeStr === '') return '';
sizeStr = parseFloat(sizeStr);
if (sizeStr === 0) return 0;
var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB'];
var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) );
return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + (sizes[i] || '??');
}
function formatNumber (val, fraction, useGrouping) {
if (val == null || val === '' || typeof val == 'object') return '';
var options = {
minimumFractionDigits : fraction,
maximumFractionDigits : fraction,
useGrouping : useGrouping
};
if (fraction == null || fraction < 0) {
options.minimumFractionDigits = 0;
options.maximumFractionDigits = 20;
}
return parseFloat(val).toLocaleString(w2utils.settings.locale, options);
}
function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String
if (!format) format = this.settings.dateFormat;
if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return '';
var dt = new Date(dateStr);
if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps
if (String(dt) == 'Invalid Date') return '';
var year = dt.getFullYear();
var month = dt.getMonth();
var date = dt.getDate();
return format.toLowerCase()
.replace('month', w2utils.settings.fullmonths[month])
.replace('mon', w2utils.settings.shortmonths[month])
.replace(/yyyy/g, year)
.replace(/yyy/g, year)
.replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2))
.replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceded by a letter
.replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1))
.replace(/dd/g, (date < 10 ? '0' : '') + date)
.replace(/th/g, (date == 1 ? 'st' : 'th'))
.replace(/th/g, (date == 2 ? 'nd' : 'th'))
.replace(/th/g, (date == 3 ? 'rd' : 'th'))
.replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceded by a letter
.replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceded by a letter
}
function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String
if (!format) format = this.settings.timeFormat;
if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return '';
var dt = new Date(dateStr);
if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps
if (w2utils.isTime(dateStr)) {
var tmp = w2utils.isTime(dateStr, true);
dt = new Date();
dt.setHours(tmp.hours);
dt.setMinutes(tmp.minutes);
}
if (String(dt) == 'Invalid Date') return '';
var type = 'am';
var hour = dt.getHours();
var h24 = dt.getHours();
var min = dt.getMinutes();
var sec = dt.getSeconds();
if (min < 10) min = '0' + min;
if (sec < 10) sec = '0' + sec;
if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) {
if (hour >= 12) type = 'pm';
if (hour > 12) hour = hour - 12;
}
return format.toLowerCase()
.replace('am', type)
.replace('pm', type)
.replace('hhh', (hour < 10 ? '0' + hour : hour))
.replace('hh24', (h24 < 10 ? '0' + h24 : h24))
.replace('h24', h24)
.replace('hh', hour)
.replace('mm', min)
.replace('mi', min)
.replace('ss', sec)
.replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceded by a letter
.replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceded by a letter
.replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceded by a letter
}
function formatDateTime(dateStr, format) {
var fmt;
if (dateStr === '' || dateStr == null || (typeof dateStr == 'object' && !dateStr.getMonth)) return '';
if (typeof format !== 'string') {
fmt = [this.settings.dateFormat, this.settings.timeFormat];
} else {
fmt = format.split('|');
fmt[0] = fmt[0].trim();
fmt[1] = fmt[1].trim();
}
// older formats support
if (fmt[1] == 'h12') fmt[1] = 'h:m pm';
if (fmt[1] == 'h24') fmt[1] = 'h24:m';
return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]);
}
function stripTags (html) {
if (html == null) return html;
switch (typeof html) {
case 'number':
break;
case 'string':
html = String(html).replace(/(<([^>]+)>)/ig, "");
break;
case 'object':
// does not modify original object, but creates a copy
if (Array.isArray(html)) {
html = $.extend(true, [], html);
for (var i = 0; i < html.length; i++) html[i] = this.stripTags(html[i]);
} else {
html = $.extend(true, {}, html);
for (var i in html) html[i] = this.stripTags(html[i]);
}
break;
}
return html;
}
function encodeTags (html) {
if (html == null) return html;
switch (typeof html) {
case 'number':
break;
case 'string':
html = String(html).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
break;
case 'object':
// does not modify original object, but creates a copy
if (Array.isArray(html)) {
html = $.extend(true, [], html);
for (var i = 0; i < html.length; i++) html[i] = this.encodeTags(html[i]);
} else {
html = $.extend(true, {}, html);
for (var i in html) html[i] = this.encodeTags(html[i]);
}
break;
}
return html;
}
function decodeTags (html) {
if (html == null) return html;
switch (typeof html) {
case 'number':
break;
case 'string':
html = String(html).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
break;
case 'object':
// does not modify original object, but creates a copy
if (Array.isArray(html)) {
html = $.extend(true, [], html);
for (var i = 0; i < html.length; i++) html[i] = this.decodeTags(html[i]);
} else {
html = $.extend(true, {}, html);
for (var i in html) html[i] = this.decodeTags(html[i]);
}
break;
}
return html;
}
function escapeId (id) {
if (id === '' || id == null) return '';
return String(id).replace(/([;&,\.\+\*\~'`:"\!\^#$%@\[\]\(\)=<>\|\/? {}\\])/g, '\\$1');
}
function base64encode (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
input = utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
}
function utf8_encode (string) {
string = String(string).replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
return output;
}
function base64decode (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 !== 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output = output + String.fromCharCode(chr3);
}
}
output = utf8_decode(output);
function utf8_decode (utftext) {
var string = "";
var i = 0;
var c = 0, c2, c3;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
return output;
}
function md5(input) {
/*
* Based on http://pajhome.org.uk/crypt/md5
*/
var hexcase = 0;
var b64pad = "";
function __pj_crypt_hex_md5(s) {
return __pj_crypt_rstr2hex(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s)));
}
function __pj_crypt_b64_md5(s) {
return __pj_crypt_rstr2b64(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s)));
}
function __pj_crypt_any_md5(s, e) {
return __pj_crypt_rstr2any(__pj_crypt_rstr_md5(__pj_crypt_str2rstr_utf8(s)), e);
}
function __pj_crypt_hex_hmac_md5(k, d)
{
return __pj_crypt_rstr2hex(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d)));
}
function __pj_crypt_b64_hmac_md5(k, d)
{
return __pj_crypt_rstr2b64(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d)));
}
function __pj_crypt_any_hmac_md5(k, d, e)
{
return __pj_crypt_rstr2any(__pj_crypt_rstr_hmac_md5(__pj_crypt_str2rstr_utf8(k), __pj_crypt_str2rstr_utf8(d)), e);
}
/*
* Calculate the MD5 of a raw string
*/
function __pj_crypt_rstr_md5(s)
{
return __pj_crypt_binl2rstr(__pj_crypt_binl_md5(__pj_crypt_rstr2binl(s), s.length * 8));
}
/*
* Calculate the HMAC-MD5, of a key and some data (raw strings)
*/
function __pj_crypt_rstr_hmac_md5(key, data)
{
var bkey = __pj_crypt_rstr2binl(key);
if (bkey.length > 16)
bkey = __pj_crypt_binl_md5(bkey, key.length * 8);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++)
{
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = __pj_crypt_binl_md5(ipad.concat(__pj_crypt_rstr2binl(data)), 512 + data.length * 8);
return __pj_crypt_binl2rstr(__pj_crypt_binl_md5(opad.concat(hash), 512 + 128));
}
/*
* Convert a raw string to a hex string
*/
function __pj_crypt_rstr2hex(input)
{
try {
hexcase
} catch (e) {
hexcase = 0;
}
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
var x;
for (var i = 0; i < input.length; i++)
{
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F)
+ hex_tab.charAt(x & 0x0F);
}
return output;
}
/*
* Convert a raw string to a base-64 string
*/
function __pj_crypt_rstr2b64(input)
{
try {
b64pad
} catch (e) {
b64pad = '';
}
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var output = "";
var len = input.length;
for (var i = 0; i < len; i += 3)
{
var triplet = (input.charCodeAt(i) << 16)
| (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0)
| (i + 2 < len ? input.charCodeAt(i + 2) : 0);
for (var j = 0; j < 4; j++)
{
if (i * 8 + j * 6 > input.length * 8)
output += b64pad;
else
output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
}
}
return output;
}
/*
* Convert a raw string to an arbitrary string encoding
*/
function __pj_crypt_rstr2any(input, encoding)
{
var divisor = encoding.length;
var i, j, q, x, quotient;
/* Convert to an array of 16-bit big-endian values, forming the dividend */
var dividend = Array(Math.ceil(input.length / 2));
for (i = 0; i < dividend.length; i++)
{
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
}
/*
* Repeatedly perform a long division. The binary array forms the dividend,
* the length of the encoding is the divisor. Once computed, the quotient
* forms the dividend for the next step. All remainders are stored for later
* use.
*/
var full_length = Math.ceil(input.length * 8 /
(Math.log(encoding.length) / Math.log(2)));
var remainders = Array(full_length);
for (j = 0; j < full_length; j++)
{
quotient = Array();
x = 0;
for (i = 0; i < dividend.length; i++)
{
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if (quotient.length > 0 || q > 0)
quotient[quotient.length] = q;
}
remainders[j] = x;
dividend = quotient;
}
/* Convert the remainders to the output string */
var output = "";
for (i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
return output;
}
/*
* Encode a string as utf-8.
* For efficiency, this assumes the input is valid utf-16.
*/
function __pj_crypt_str2rstr_utf8(input)
{
var output = "";
var i = -1;
var x, y;
while (++i < input.length)
{
/* Decode utf-16 surrogate pairs */
x = input.charCodeAt(i);
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
{
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
/* Encode output as utf-8 */
if (x <= 0x7F)
output += String.fromCharCode(x);
else if (x <= 0x7FF)
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
0x80 | (x & 0x3F));
else if (x <= 0xFFFF)
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0x80 | ((x >>> 6) & 0x3F),
0x80 | (x & 0x3F));
else if (x <= 0x1FFFFF)
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3F),
0x80 | ((x >>> 6) & 0x3F),
0x80 | (x & 0x3F));
}
return output;
}
/*
* Encode a string as utf-16
*/
function __pj_crypt_str2rstr_utf16le(input)
{
var output = "";
for (var i = 0; i < input.length; i++)
output += String.fromCharCode(input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF);
return output;
}
function __pj_crypt_str2rstr_utf16be(input)
{
var output = "";
for (var i = 0; i < input.length; i++)
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
input.charCodeAt(i) & 0xFF);
return output;
}
/*
* Convert a raw string to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
function __pj_crypt_rstr2binl(input)
{
var output = Array(input.length >> 2);
for (var i = 0; i < output.length; i++)
output[i] = 0;
for (var i = 0; i < input.length * 8; i += 8)
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
return output;
}
/*
* Convert an array of little-endian words to a string
*/
function __pj_crypt_binl2rstr(input)
{
var output = "";
for (var i = 0; i < input.length * 32; i += 8)
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
return output;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function __pj_crypt_binl_md5(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for (var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = __pj_crypt_md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = __pj_crypt_md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = __pj_crypt_md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = __pj_crypt_md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = __pj_crypt_md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = __pj_crypt_md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = __pj_crypt_md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = __pj_crypt_md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = __pj_crypt_md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = __pj_crypt_md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = __pj_crypt_md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = __pj_crypt_md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = __pj_crypt_md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = __pj_crypt_md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = __pj_crypt_md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = __pj_crypt_md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = __pj_crypt_md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = __pj_crypt_md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = __pj_crypt_md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = __pj_crypt_md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
a = __pj_crypt_md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = __pj_crypt_md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = __pj_crypt_md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = __pj_crypt_md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = __pj_crypt_md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = __pj_crypt_md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = __pj_crypt_md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = __pj_crypt_md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = __pj_crypt_md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = __pj_crypt_md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = __pj_crypt_md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = __pj_crypt_md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = __pj_crypt_md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = __pj_crypt_md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = __pj_crypt_md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = __pj_crypt_md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = __pj_crypt_md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = __pj_crypt_md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = __pj_crypt_md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = __pj_crypt_md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = __pj_crypt_md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = __pj_crypt_md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
c = __pj_crypt_md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = __pj_crypt_md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = __pj_crypt_md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = __pj_crypt_md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = __pj_crypt_md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = __pj_crypt_md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = __pj_crypt_md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
d = __pj_crypt_md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = __pj_crypt_md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = __pj_crypt_md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = __pj_crypt_md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = __pj_crypt_md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = __pj_crypt_md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = __pj_crypt_md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = __pj_crypt_md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = __pj_crypt_md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = __pj_crypt_md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = __pj_crypt_md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = __pj_crypt_md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = __pj_crypt_md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = __pj_crypt_md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = __pj_crypt_md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = __pj_crypt_safe_add(a, olda);
b = __pj_crypt_safe_add(b, oldb);
c = __pj_crypt_safe_add(c, oldc);
d = __pj_crypt_safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function __pj_crypt_md5_cmn(q, a, b, x, s, t)
{
return __pj_crypt_safe_add(__pj_crypt_bit_rol(__pj_crypt_safe_add(__pj_crypt_safe_add(a, q), __pj_crypt_safe_add(x, t)), s), b);
}
function __pj_crypt_md5_ff(a, b, c, d, x, s, t)
{
return __pj_crypt_md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function __pj_crypt_md5_gg(a, b, c, d, x, s, t)
{
return __pj_crypt_md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function __pj_crypt_md5_hh(a, b, c, d, x, s, t)
{
return __pj_crypt_md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function __pj_crypt_md5_ii(a, b, c, d, x, s, t)
{
return __pj_crypt_md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function __pj_crypt_safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function __pj_crypt_bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
return __pj_crypt_hex_md5(input);
}
function transition (div_old, div_new, type, callBack) {
var width = $(div_old).width();
var height = $(div_old).height();
var time = 0.5;
if (!div_old || !div_new) {
console.log('ERROR: Cannot do transition when one of the divs is null');
return;
}
div_old.parentNode.style.cssText += 'perspective: 900px; overflow: hidden;';
div_old.style.cssText += '; position: absolute; z-index: 1019; backface-visibility: hidden';
div_new.style.cssText += '; position: absolute; z-index: 1020; backface-visibility: hidden';
switch (type) {
case 'slide-left':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; transform: translate3d('+ width + 'px, 0, 0)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)';
div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(-'+ width +'px, 0, 0)';
}, 1);
break;
case 'slide-right':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; transform: translate3d(-'+ width +'px, 0, 0)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0px, 0, 0)';
div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d('+ width +'px, 0, 0)';
}, 1);
break;
case 'slide-down':
// init divs
div_old.style.cssText += 'overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)';
div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, '+ height +'px, 0)';
}, 1);
break;
case 'slide-up':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, '+ height +'px, 0)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)';
div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)';
}, 1);
break;
case 'flip-left':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)';
div_new.style.cssText += 'overflow: hidden; transform: rotateY(-180deg)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)';
div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(180deg)';
}, 1);
break;
case 'flip-right':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)';
div_new.style.cssText += 'overflow: hidden; transform: rotateY(180deg)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)';
div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(-180deg)';
}, 1);
break;
case 'flip-down':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)';
div_new.style.cssText += 'overflow: hidden; transform: rotateX(180deg)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)';
div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(-180deg)';
}, 1);
break;
case 'flip-up':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)';
div_new.style.cssText += 'overflow: hidden; transform: rotateX(-180deg)';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)';
div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(180deg)';
}, 1);
break;
case 'pop-in':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; transform: scale(1); opacity: 1;';
div_old.style.cssText += 'transition: '+ time +'s;';
}, 1);
break;
case 'pop-out':
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;';
div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;';
div_old.style.cssText += 'transition: '+ time +'s; transform: scale(1.7); opacity: 0;';
}, 1);
break;
default:
// init divs
div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)';
div_new.style.cssText += 'overflow: hidden; translate3d(0, 0, 0); opacity: 0;';
$(div_new).show();
// -- need a timing function because otherwise not working
window.setTimeout(function() {
div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;';
div_old.style.cssText += 'transition: '+ time +'s';
}, 1);
break;
}
setTimeout(function () {
if (type === 'slide-down') {
$(div_old).css('z-index', '1019');
$(div_new).css('z-index', '1020');
}
if (div_new) {
$(div_new).css({ 'opacity': '1' }).css(w2utils.cssPrefix({
'transition': '',
'transform' : ''
}));
}
if (div_old) {
$(div_old).css({ 'opacity': '1' }).css(w2utils.cssPrefix({
'transition': '',
'transform' : ''
}));
}
if (typeof callBack === 'function') callBack();
}, time * 1000);
}
function lock (box, msg, spinner) {
var options = {};
if (typeof msg === 'object') {
options = msg;
} else {
options.msg = msg;
options.spinner = spinner;
}
if (!options.msg && options.msg !== 0) options.msg = '';
w2utils.unlock(box);
$(box).prepend(
'<div class="w2ui-lock"></div>'+
'<div class="w2ui-lock-msg"></div>'
);
var $lock = $(box).find('.w2ui-lock');
var mess = $(box).find('.w2ui-lock-msg');
if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' });
if (options.spinner === true) options.msg = '<div class="w2ui-spinner" '+ (!options.msg ? 'style="width: 35px; height: 35px"' : '') +'></div>' + options.msg;
if (options.opacity != null) $lock.css('opacity', options.opacity);
if (typeof $lock.fadeIn == 'function') {
$lock.fadeIn(200);
mess.html(options.msg).fadeIn(200);
mess.css({ 'display': 'flex', 'justify-content': 'center', 'align-items': 'center' });
} else {
$lock.show();
mess.html(options.msg).show(0);
}
}
function unlock (box, speed) {
if (isInt(speed)) {
$(box).find('.w2ui-lock').fadeOut(speed);
setTimeout(function () {
$(box).find('.w2ui-lock').remove();
$(box).find('.w2ui-lock-msg').remove();
}, speed);
} else {
$(box).find('.w2ui-lock').remove();
$(box).find('.w2ui-lock-msg').remove();
}
}
/**
* Used in w2popup, w2grid, w2form, w2layout
* should be called with .call(...) method
*/
function message(where, options) {
var obj = this, closeTimer, edata;
// var where.path = 'w2popup';
// var where.title = '.w2ui-popup-title';
// var where.body = '.w2ui-box';
$().w2tag(); // hide all tags
if (!options) options = { width: 200, height: 100 };
if (options.on == null) $.extend(options, w2utils.event);
if (options.width == null) options.width = 200;
if (options.height == null) options.height = 100;
var pWidth = parseInt($(where.box).width());
var pHeight = parseInt($(where.box).height());
var titleHeight = parseInt($(where.box).find(where.title).css('height') || 0);
if (options.width > pWidth) options.width = pWidth - 10;
if (options.height > pHeight - titleHeight) options.height = pHeight - 10 - titleHeight;
options.originalWidth = options.width;
options.originalHeight = options.height;
if (parseInt(options.width) < 0) options.width = pWidth + options.width;
if (parseInt(options.width) < 10) options.width = 10;
if (parseInt(options.height) < 0) options.height = pHeight + options.height - titleHeight;
if (parseInt(options.height) < 10) options.height = 10;
if (options.hideOnClick == null) options.hideOnClick = false;
var poptions = $(where.box).data('options') || {};
if (options.width == null || options.width > poptions.width - 10) {
options.width = poptions.width - 10;
}
if (options.height == null || options.height > poptions.height - titleHeight - 5) {
options.height = poptions.height - titleHeight - 5; // need margin from bottom only
}
// negative value means margin
if (options.originalHeight < 0) options.height = pHeight + options.originalHeight - titleHeight;
if (options.originalWidth < 0) options.width = pWidth + options.originalWidth * 2; // x 2 because there is left and right margin
var head = $(where.box).find(where.title);
// if some messages are closing, insta close them
var $tmp = $(where.box).find('.w2ui-message.w2ui-closing');
if ($(where.box).find('.w2ui-message.w2ui-closing').length > 0) {
clearTimeout(closeTimer);
closeCB($tmp, $tmp.data('options') || {});
}
var msgCount = $(where.box).find('.w2ui-message').length;
// remove message
if ($.trim(options.html) === '' && $.trim(options.body) === '' && $.trim(options.buttons) === '') {
if (msgCount === 0) return; // no messages at all
var $msg = $(where.box).find('#w2ui-message'+ (msgCount-1));
var options = $msg.data('options') || {};
// before event
edata = options.trigger({ phase: 'before', type: 'close', target: 'self' });
if (edata.isCancelled === true) return;
// default behavior
$msg.css(w2utils.cssPrefix({
'transition': '0.15s',
'transform': 'translateY(-' + options.height + 'px)'
})).addClass('w2ui-closing');
if (msgCount == 1) {
if (this.unlock) {
if (where.param) this.unlock(where.param, 150); else this.unlock(150);
}
} else {
$(where.box).find('#w2ui-message'+ (msgCount-2)).css('z-index', 1500);
}
closeTimer = setTimeout(function () { closeCB($msg, options) }, 150);
} else {
if ($.trim(options.body) !== '' || $.trim(options.buttons) !== '') {
options.html = '<div class="w2ui-message-body">'+ (options.body || '') +'</div>'+
'<div class="w2ui-message-buttons">'+ (options.buttons || '') +'</div>';
}
// hide previous messages
$(where.box).find('.w2ui-message').css('z-index', 1390);
head.data('old-z-index', head.css('z-index'));
head.css('z-index', 1501);
// add message
$(where.box).find(where.body)
.before('<div id="w2ui-message' + msgCount + '" onmousedown="event.stopPropagation();" '+
' class="w2ui-message" style="display: none; z-index: 1500; ' +
(head.length === 0 ? 'top: 0px;' : 'top: ' + w2utils.getSize(head, 'height') + 'px;') +
(options.width != null ? 'width: ' + options.width + 'px; left: ' + ((pWidth - options.width) / 2) + 'px;' : 'left: 10px; right: 10px;') +
(options.height != null ? 'height: ' + options.height + 'px;' : 'bottom: 6px;') +
w2utils.cssPrefix('transition', '.3s', true) + '"' +
(options.hideOnClick === true
? where.param
? 'onclick="'+ where.path +'.message(\''+ where.param +'\');"'
: 'onclick="'+ where.path +'.message();"'
: '') + '>' +
'</div>');
$(where.box).find('#w2ui-message'+ msgCount)
.data('options', options)
.data('prev_focus', $(':focus'));
var display = $(where.box).find('#w2ui-message'+ msgCount).css('display');
$(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({
'transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)')
}));
if (display == 'none') {
$(where.box).find('#w2ui-message'+ msgCount).show().html(options.html);
options.box = $(where.box).find('#w2ui-message'+ msgCount);
// before event
edata = options.trigger({ phase: 'before', type: 'open', target: 'self' });
if (edata.isCancelled === true) {
head.css('z-index', head.data('old-z-index'));
$(where.box).find('#w2ui-message'+ msgCount).remove();
return;
}
// timer needs to animation
setTimeout(function () {
$(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({
'transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)')
}));
}, 1);
// timer for lock
if (msgCount === 0 && this.lock) {
if (where.param) this.lock(where.param); else this.lock();
}
setTimeout(function() {
// has to be on top of lock
$(where.box).find('#w2ui-message'+ msgCount).css(w2utils.cssPrefix({ 'transition': '0s' }));
// event after
options.trigger($.extend(edata, { phase: 'after' }));
}, 350);
}
}
function closeCB($msg, options) {
if (edata == null) {
// before event
edata = options.trigger({ phase: 'before', type: 'open', target: 'self' });
if (edata.isCancelled === true) {
head.css('z-index', head.data('old-z-index'));
$(where.box).find('#w2ui-message'+ msgCount).remove();
return;
}
}
var $focus = $msg.data('prev_focus');
$msg.remove();
if ($focus && $focus.length > 0) {
$focus.focus();
} else {
if (obj && obj.focus) obj.focus();
}
head.css('z-index', head.data('old-z-index'));
// event after
options.trigger($.extend(edata, { phase: 'after' }));
}
}
function getSize (el, type) {
var $el = $(el);
var bwidth = {
left : parseInt($el.css('border-left-width')) || 0,
right : parseInt($el.css('border-right-width')) || 0,
top : parseInt($el.css('border-top-width')) || 0,
bottom : parseInt($el.css('border-bottom-width')) || 0
};
var mwidth = {
left : parseInt($el.css('margin-left')) || 0,
right : parseInt($el.css('margin-right')) || 0,
top : parseInt($el.css('margin-top')) || 0,
bottom : parseInt($el.css('margin-bottom')) || 0
};
var pwidth = {
left : parseInt($el.css('padding-left')) || 0,
right : parseInt($el.css('padding-right')) || 0,
top : parseInt($el.css('padding-top')) || 0,
bottom : parseInt($el.css('padding-bottom')) || 0
};
switch (type) {
case 'top' : return bwidth.top + mwidth.top + pwidth.top;
case 'bottom' : return bwidth.bottom + mwidth.bottom + pwidth.bottom;
case 'left' : return bwidth.left + mwidth.left + pwidth.left;
case 'right' : return bwidth.right + mwidth.right + pwidth.right;
case 'width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width());
case 'height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height());
case '+width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right;
case '+height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom;
}
return 0;
}
function getStrWidth (str, styles) {
var w, html = '<div id="_tmp_width" style="position: absolute; top: -900px;'+ (styles || '') +'">'+
encodeTags(str) +
'</div>';
$('body').append(html);
w = $('#_tmp_width').width();
$('#_tmp_width').remove();
return w;
}
function lang (phrase) {
var translation = this.settings.phrases[phrase];
if (translation == null) return phrase; else return translation;
}
function locale (locale) {
if (!locale) locale = 'en-us';
// if the locale is an object, not a string, than we assume it's a
if(typeof locale !== "string" ) {
w2utils.settings = $.extend(true, w2utils.settings, locale);
return;
}
if (locale.length === 5) locale = 'locale/'+ locale +'.json';
// clear phrases from language before
w2utils.settings.phrases = {};
// load from the file
$.ajax({
url : locale,
type : "GET",
dataType : "JSON",
async : false,
success : function (data, status, xhr) {
w2utils.settings = $.extend(true, w2utils.settings, data);
},
error : function (xhr, status, msg) {
console.log('ERROR: Cannot load locale '+ locale);
}
});
}
function scrollBarSize () {
if (tmp.scrollBarSize) return tmp.scrollBarSize;
var html =
'<div id="_scrollbar_width" style="position: absolute; top: -300px; width: 100px; height: 100px; overflow-y: scroll;">'+
' <div style="height: 120px">1</div>'+
'</div>';
$('body').append(html);
tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width();
$('#_scrollbar_width').remove();
if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+
return tmp.scrollBarSize;
}
function checkName (params, component) { // was w2checkNameParam
if (!params || params.name == null) {
console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().');
return false;
}
if (w2ui[params.name] != null) {
console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').');
return false;
}
if (!w2utils.isAlphaNumeric(params.name)) {
console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). ');
return false;
}
return true;
}
function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId
if (!$.isArray(items)) items = [items];
for (var i = 0; i < items.length; i++) {
if (items[i].id === id) {
console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')');
return false;
}
}
return true;
}
function parseRoute(route) {
var keys = [];
var path = route
.replace(/\/\(/g, '(?:/')
.replace(/\+/g, '__plus__')
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional) {
keys.push({ name: key, optional: !! optional });
slash = slash || '';
return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '');
})
.replace(/([\/.])/g, '\\$1')
.replace(/__plus__/g, '(.+)')
.replace(/\*/g, '(.*)');
return {
path : new RegExp('^' + path + '$', 'i'),
keys : keys
};
}
function cssPrefix(field, value, returnString) {
var css = {};
var newCSS = {};
var ret = '';
if (!$.isPlainObject(field)) {
css[field] = value;
} else {
css = field;
if (value === true) returnString = true;
}
for (var c in css) {
newCSS[c] = css[c];
newCSS['-webkit-'+c] = css[c];
newCSS['-moz-'+c] = css[c].replace('-webkit-', '-moz-');
newCSS['-ms-'+c] = css[c].replace('-webkit-', '-ms-');
newCSS['-o-'+c] = css[c].replace('-webkit-', '-o-');
}
if (returnString === true) {
for (var c in newCSS) {
ret += c + ': ' + newCSS[c] + '; ';
}
} else {
ret = newCSS;
}
return ret;
}
function getCursorPosition(input) {
if (input == null) return null;
var caretOffset = 0;
var doc = input.ownerDocument || input.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (input.tagName && input.tagName.toUpperCase() == 'INPUT' && input.selectionStart) {
// standards browser
caretOffset = input.selectionStart;
} else {
if (win.getSelection) {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(input);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(input);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
}
return caretOffset;
}
function setCursorPosition(input, pos, posEnd) {
var range = document.createRange();
var el, sel = window.getSelection();
if (input == null) return;
for (var i = 0; i < input.childNodes.length; i++) {
var tmp = $(input.childNodes[i]).text();
if (input.childNodes[i].tagName) {
tmp = $(input.childNodes[i]).html();
tmp = tmp.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&')
.replace(/&quot;/g, '"')
.replace(/&nbsp;/g, ' ');
}
if (pos <= tmp.length) {
el = input.childNodes[i];
if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0];
if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0];
break;
} else {
pos -= tmp.length;
}
}
if (el == null) return;
if (pos > el.length) pos = el.length;
range.setStart(el, pos);
if (posEnd) {
range.setEnd(el, posEnd);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}
function testLocalStorage() {
// test if localStorage is available, see issue #1282
// original code: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
var str = 'w2ui_test';
try {
localStorage.setItem(str, str);
localStorage.removeItem(str);
return true;
} catch (e) {
return false;
}
}
})(jQuery);
/***********************************************************
* Formatters object
* --- Primariy used in grid
*
*********************************************************/
w2utils.formatters = {
'number': function (value, params) {
if (parseInt(params) > 20) params = 20;
if (parseInt(params) < 0) params = 0;
if (value == null || value === '') return '';
return w2utils.formatNumber(parseFloat(value), params, true);
},
'float': function (value, params) {
return w2utils.formatters['number'](value, params);
},
'int': function (value, params) {
return w2utils.formatters['number'](value, 0);
},
'money': function (value, params) {
if (value == null || value === '') return '';
var data = w2utils.formatNumber(Number(value), w2utils.settings.currencyPrecision || 2);
return (w2utils.settings.currencyPrefix || '') + data + (w2utils.settings.currencySuffix || '');
},
'currency': function (value, params) {
return w2utils.formatters['money'](value, params);
},
'percent': function (value, params) {
if (value == null || value === '') return '';
return w2utils.formatNumber(value, params || 1) + '%';
},
'size': function (value, params) {
if (value == null || value === '') return '';
return w2utils.formatSize(parseInt(value));
},
'date': function (value, params) {
if (params === '') params = w2utils.settings.dateFormat;
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, params, true);
if (dt === false) dt = w2utils.isDate(value, params, true);
return '<span title="'+ dt +'">' + w2utils.formatDate(dt, params) + '</span>';
},
'datetime': function (value, params) {
if (params === '') params = w2utils.settings.datetimeFormat;
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, params, true);
if (dt === false) dt = w2utils.isDate(value, params, true);
return '<span title="'+ dt +'">' + w2utils.formatDateTime(dt, params) + '</span>';
},
'time': function (value, params) {
if (params === '') params = w2utils.settings.timeFormat;
if (params === 'h12') params = 'hh:mi pm';
if (params === 'h24') params = 'h24:mi';
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, params, true);
if (dt === false) dt = w2utils.isDate(value, params, true);
return '<span title="'+ dt +'">' + w2utils.formatTime(value, params) + '</span>';
},
'timestamp': function (value, params) {
if (params === '') params = w2utils.settings.datetimeFormat;
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, params, true);
if (dt === false) dt = w2utils.isDate(value, params, true);
return dt.toString ? dt.toString() : '';
},
'gmt': function (value, params) {
if (params === '') params = w2utils.settings.datetimeFormat;
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, params, true);
if (dt === false) dt = w2utils.isDate(value, params, true);
return dt.toUTCString ? dt.toUTCString() : '';
},
'age': function (value, params) {
if (value == null || value === 0 || value === '') return '';
var dt = w2utils.isDateTime(value, null, true);
if (dt === false) dt = w2utils.isDate(value, null, true);
return '<span title="'+ dt +'">' + w2utils.age(value) + (params ? (' ' + params) : '') + '</span>';
},
'interval': function (value, params) {
if (value == null || value === 0 || value === '') return '';
return w2utils.interval(value) + (params ? (' ' + params) : '');
},
'toggle': function (value, params) {
return (value ? 'Yes' : '');
},
'password': function (value, params) {
var ret = "";
for (var i=0; i < value.length; i++) {
ret += "*";
}
return ret;
}
};
/***********************************************************
* Generic Event Object
* --- This object is reused across all other
* --- widgets in w2ui.
*
*********************************************************/
w2utils.event = {
on: function (edata, handler) {
var $ = jQuery;
var scope;
// allow 'eventName.scope' syntax
if (typeof edata == 'string' && edata.indexOf('.') != -1) {
var tmp = edata.split('.');
edata = tmp[0];
scope = tmp[1];
}
// allow 'eventName:after' syntax
if (typeof edata == 'string' && edata.indexOf(':') != -1) {
var tmp = edata.split(':');
if (['complete', 'done'].indexOf(edata[1]) != -1) edata[1] = 'after';
edata = {
type : tmp[0],
execute : tmp[1]
};
}
if (!$.isPlainObject(edata)) edata = { type: edata, scope: scope };
edata = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, edata);
// errors
if (!edata.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; }
if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; }
if (!$.isArray(this.handlers)) this.handlers = [];
// console.log('add', edata);
this.handlers.push({ edata: edata, handler: handler });
},
off: function (edata, handler) {
var $ = jQuery;
var scope;
// allow 'eventName.scope' syntax
if (typeof edata == 'string' && edata.indexOf('.') != -1) {
var tmp = edata.split('.');
edata = tmp[0];
scope = tmp[1];
}
// allow 'eventName:after' syntax
if (typeof edata == 'string' && edata.indexOf(':') != -1) {
var tmp = edata.split(':');
if (['complete', 'done'].indexOf(edata[1]) != -1) edata[1] = 'after';
edata = {
type : tmp[0],
execute : tmp[1]
}
}
if (!$.isPlainObject(edata)) edata = { type: edata };
edata = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, edata);
// errors
if (!edata.type && !scope) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; }
if (!handler) { handler = null; }
// remove handlers
var newHandlers = [];
for (var h = 0, len = this.handlers.length; h < len; h++) {
var t = this.handlers[h];
if ((t.edata.type === edata.type || edata.type === '*' || (t.edata.scope != null && edata.type == '')) &&
(t.edata.target === edata.target || edata.target == null) &&
(t.edata.execute === edata.execute || edata.execute == null) &&
(t.handler === handler || handler == null || (scope != null && t.edata.scope == scope)))
{
// match
} else {
newHandlers.push(t);
}
}
this.handlers = newHandlers;
},
trigger: function (edata) {
var $ = jQuery;
var edata = $.extend({ type: null, phase: 'before', target: null, doneHandlers: [] }, edata, {
isStopped : false,
isCancelled : false,
done : function (handler) { this.doneHandlers.push(handler); },
preventDefault : function () { this.isCancelled = true; },
stopPropagation : function () { this.isStopped = true; }
});
if (edata.phase === 'before') edata.onComplete = null;
var args, fun, tmp;
if (edata.target == null) edata.target = null;
if (!$.isArray(this.handlers)) this.handlers = [];
// process events in REVERSE order
for (var h = this.handlers.length-1; h >= 0; h--) {
var item = this.handlers[h];
if ((item.edata.type === edata.type || item.edata.type === '*') &&
(item.edata.target === edata.target || item.edata.target == null) &&
(item.edata.execute === edata.phase || item.edata.execute === '*' || item.edata.phase === '*'))
{
edata = $.extend({}, item.edata, edata);
// check handler arguments
args = [];
tmp = new RegExp(/\((.*?)\)/).exec(item.handler);
if (tmp) args = tmp[1].split(/\s*,\s*/);
if (args.length === 2) {
item.handler.call(this, edata.target, edata); // old way for back compatibility
} else {
item.handler.call(this, edata); // new way
}
if (edata.isStopped === true || edata.stop === true) return edata; // back compatibility edata.stop === true
}
}
// main object events
var funName = 'on' + edata.type.substr(0,1).toUpperCase() + edata.type.substr(1);
if (edata.phase === 'before' && typeof this[funName] === 'function') {
fun = this[funName];
// check handler arguments
args = [];
tmp = new RegExp(/\((.*?)\)/).exec(fun);
if (tmp) args = tmp[1].split(/\s*,\s*/);
if (args.length === 2) {
fun.call(this, edata.target, edata); // old way for back compatibility
} else {
fun.call(this, edata); // new way
}
if (edata.isStopped === true || edata.stop === true) return edata; // back compatibility edata.stop === true
}
// item object events
if (edata.object != null && edata.phase === 'before' &&
typeof edata.object[funName] === 'function')
{
fun = edata.object[funName];
// check handler arguments
args = [];
tmp = new RegExp(/\((.*?)\)/).exec(fun);
if (tmp) args = tmp[1].split(/\s*,\s*/);
if (args.length === 2) {
fun.call(this, edata.target, edata); // old way for back compatibility
} else {
fun.call(this, edata); // new way
}
if (edata.isStopped === true || edata.stop === true) return edata;
}
// execute onComplete
if (edata.phase === 'after') {
if (typeof edata.onComplete === 'function') edata.onComplete.call(this, edata);
for (var i = 0; i < edata.doneHandlers.length; i++) {
if (typeof edata.doneHandlers[i] == 'function') {
edata.doneHandlers[i].call(this, edata);
}
}
}
return edata;
}
};
/***********************************************************
* Commonly used plugins
* --- used primarily in grid and form
*
*********************************************************/
(function ($) {
$.fn.w2render = function (name) {
if ($(this).length > 0) {
if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]);
if (typeof name === 'object') name.render($(this)[0]);
}
};
$.fn.w2destroy = function (name) {
if (!name && this.length > 0) name = this.attr('name');
if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy();
if (typeof name === 'object') name.destroy();
};
$.fn.w2marker = function () {
var str = Array.prototype.slice.call(arguments, 0);
if (Array.isArray(str[0])) str = str[0];
if (str.length === 0 || !str[0]) { // remove marker
return $(this).each(clearMarkedText);
} else { // add marker
return $(this).each(function (index, el) {
clearMarkedText(index, el);
for (var s = 0; s < str.length; s++) {
var tmp = str[s];
if (typeof tmp !== 'string') tmp = String(tmp);
// escape regex special chars
tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&amp;').replace(/</g, '&gt;').replace(/>/g, '&lt;');
var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags
el.innerHTML = el.innerHTML.replace(regex, replaceValue);
}
function replaceValue(matched) { // mark new
return '<span class="w2ui-marker">' + matched + '</span>';
}
});
}
function clearMarkedText(index, el) {
while (el.innerHTML.indexOf('<span class="w2ui-marker">') != -1) {
el.innerHTML = el.innerHTML.replace(/\<span class=\"w2ui\-marker\"\>((.|\n|\r)*)\<\/span\>/ig, '$1'); // unmark
}
}
};
// -- w2tag - there can be multiple on screen at a time
$.fn.w2tag = function (text, options) {
// only one argument
if (arguments.length == 1 && typeof text == 'object') {
options = text;
if (options.html != null) text = options.html;
}
// default options
options = $.extend({
id : null, // id for the tag, otherwise input id is used
html : text, // or html
position : 'right|top', // can be left, right, top, bottom
align : 'none', // can be none, left, right (only works for position: top | bottom)
left : 0, // delta for left coordinate
top : 0, // delta for top coordinate
style : '', // adition style for the tag
css : {}, // add css for input when tag is shown
className : '', // add class bubble
inputClass : '', // add class for input when tag is shown
onShow : null, // callBack when shown
onHide : null, // callBack when hidden
hideOnKeyPress : true, // hide tag if key pressed
hideOnBlur : false, // hide tag on blur
hideOnClick : false // hide tag on document click
}, options);
if (options.name != null && options.id == null) options.id = options.name;
// for backward compatibility
if (options['class'] !== '' && options.inputClass === '') options.inputClass = options['class'];
// remove all tags
if ($(this).length === 0) {
$('.w2ui-tag').each(function (index, el) {
var opt = $(el).data('options');
if (opt == null) opt = {};
$($(el).data('taged-el'))
.removeClass(opt.inputClass)
.removeData('w2tag')
.removeData('checkIfMoved');
clearInterval($(el).data('timer'));
$(el).remove();
});
return;
}
return $(this).each(function (index, el) {
// show or hide tag
var origID = (options.id ? options.id : el.id);
var tagID = w2utils.escapeId(origID);
var $tags = $('#w2ui-tag-'+tagID);
if (text === '' || text == null) {
// remove element
$tags.css('opacity', 0);
clearInterval($tags.data('timer'));
$tags.remove();
return;
} else if ($tags.length !== 0) {
// if already present
options = $.extend($tags.data('options'), options);
$tags.data('options', options);
$tags.find('.w2ui-tag-body')
.attr('style', options.style)
.addClass(options.className)
.html(options.html);
checkIfMoved(true);
} else {
var originalCSS = '';
if ($(el).length > 0) originalCSS = $(el)[0].style.cssText;
// insert
$('body').append(
'<div onclick="event.stopPropagation()" style="display:none;" id="w2ui-tag-'+ origID +'" '+
' class="w2ui-tag '+ ($(el).parents('.w2ui-popup, .w2ui-overlay-popup, .w2ui-message').length > 0 ? 'w2ui-tag-popup' : '') + '">'+
' <div style="margin: -2px 0px 0px -2px; white-space: nowrap;">'+
' <div class="w2ui-tag-body '+ options.className +'" style="'+ (options.style || '') +'">'+ text +'</div>'+
' </div>' +
'</div>');
$tags = $('#w2ui-tag-'+tagID);
$(el).data('w2tag', $tags.get(0)).data('checkIfMoved', checkIfMoved);
}
// need time out to allow tag to be rendered
setTimeout(function () {
$tags.css('display', 'block');
if (!$(el).offset()) return;
var pos = checkIfMoved(true);
if (pos == null) return;
$tags.css({
opacity : '1',
left : pos.left + 'px',
top : pos.top + 'px'
})
.data('options', options)
.data('taged-el', el)
.data('position', pos.left + 'x' + pos.top)
.data('timer', setTimeout(checkIfMoved, 100))
.find('.w2ui-tag-body').addClass(pos['posClass']);
$(el).css(options.css)
.off('.w2tag')
.addClass(options.inputClass);
if (options.hideOnKeyPress) {
$(el).on('keypress.w2tag', hideTag);
}
if (options.hideOnBlur) {
$(el).on('blur.w2tag', hideTag);
}
if (options.hideOnClick) {
$(document).on('click.w2tag', hideTag)
}
if (typeof options.onShow === 'function') options.onShow();
}, 1);
// bind event to hide it
function hideTag() {
$tags = $('#w2ui-tag-'+tagID);
if ($tags.length <= 0) return;
clearInterval($tags.data('timer'));
$tags.remove();
$(document).off('.w2tag');
$(el).off('.w2tag', hideTag)
.removeClass(options.inputClass)
.removeData('w2tag')
.removeData('checkIfMoved');
if ($(el).length > 0) $(el)[0].style.cssText = originalCSS;
if (typeof options.onHide === 'function') options.onHide();
}
function checkIfMoved(checkOnly, instant) {
// monitor if destroyed
var offset = $(el).offset();
if ($(el).length === 0 || (offset.left === 0 && offset.top === 0) || $tags.find('.w2ui-tag-body').length === 0) {
clearInterval($tags.data('timer'));
hideTag();
return;
}
if (!instant) setTimeout(checkIfMoved, 200);
// monitor if moved
var posClass = 'w2ui-tag-right';
var posLeft = parseInt(offset.left + el.offsetWidth + (options.left ? options.left : 0));
var posTop = parseInt(offset.top + (options.top ? options.top : 0));
var tagBody = $tags.find('.w2ui-tag-body');
var width = tagBody[0].offsetWidth;
var height = tagBody[0].offsetHeight;
if (typeof options.position == 'string' && options.position.indexOf('|') != -1) {
options.position = options.position.split('|');
}
if (options.position == 'top') {
posClass = 'w2ui-tag-top';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14;
posTop = parseInt(offset.top + (options.top ? options.top : 0)) - height - 10;
}
else if (options.position == 'bottom') {
posClass = 'w2ui-tag-bottom';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14;
posTop = parseInt(offset.top + el.offsetHeight + (options.top ? options.top : 0)) + 10;
}
else if (options.position == 'left') {
posClass = 'w2ui-tag-left';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - width - 20;
posTop = parseInt(offset.top + (options.top ? options.top : 0));
}
else if (Array.isArray(options.position)) {
// try to fit the tag on screen in the order defined in the array
var maxWidth = window.innerWidth;
var maxHeight = window.innerHeight
for (var i=0; i<options.position.length; i++) {
var pos = options.position[i];
if (pos == 'right') {
posClass = 'w2ui-tag-right';
posLeft = parseInt(offset.left + el.offsetWidth + (options.left ? options.left : 0));
posTop = parseInt(offset.top + (options.top ? options.top : 0));
if (posLeft+width <= maxWidth) break;
}
else if (pos == 'left') {
posClass = 'w2ui-tag-left';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - width - 20;
posTop = parseInt(offset.top + (options.top ? options.top : 0));
if (posLeft >= 0) break;
}
else if (pos == 'top') {
posClass = 'w2ui-tag-top';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14;
posTop = parseInt(offset.top + (options.top ? options.top : 0)) - height - 10;
if(posLeft+width <= maxWidth && posTop >= 0) break;
}
else if (pos == 'bottom') {
posClass = 'w2ui-tag-bottom';
posLeft = parseInt(offset.left + (options.left ? options.left : 0)) - 14;
posTop = parseInt(offset.top + el.offsetHeight + (options.top ? options.top : 0)) + 10;
if (posLeft+width <= maxWidth && posTop+height <= maxHeight) break;
}
}
if (tagBody.data('posClass') !== posClass) {
tagBody.removeClass('w2ui-tag-right w2ui-tag-left w2ui-tag-top w2ui-tag-bottom')
.addClass(posClass)
.data('posClass', posClass);
}
}
if ($tags.data('position') !== posLeft + 'x' + posTop && checkOnly !== true) {
$tags.css(w2utils.cssPrefix({ 'transition': (instant ? '0s' : '.2s') })).css({
left: posLeft + 'px',
top : posTop + 'px'
}).data('position', posLeft + 'x' + posTop);
}
return { left: posLeft, top: posTop, posClass: posClass };
}
});
};
// w2overlay - appears under the element, there can be only one at a time
$.fn.w2overlay = function (html, options) {
var obj = this;
var name = '';
var defaults = {
name : null, // it not null, then allows multiple concurrent overlays
html : '', // html text to display
align : 'none', // can be none, left, right, both
left : 0, // offset left
top : 0, // offset top
tipLeft : 30, // tip offset left
noTip : false, // if true - no tip will be displayed
selectable : false,
width : 0, // fixed width
height : 0, // fixed height
maxWidth : null, // max width if any
maxHeight : null, // max height if any
contextMenu : false, // if true, it will be opened at mouse position
pageX : null,
pageY : null,
originalEvent : null,
style : '', // additional style for main div
'class' : '', // additional class name for main div
overlayStyle: '',
onShow : null, // event on show
onHide : null, // event on hide
openAbove : false, // show above control
tmp : {}
};
if (arguments.length == 1) {
if (typeof html == 'object') {
options = html;
} else {
options = { html: html };
}
}
if (arguments.length == 2) options.html = html;
if (!$.isPlainObject(options)) options = {};
options = $.extend({}, defaults, options);
if (options.name) name = '-' + options.name;
// hide
var tmp_hide;
if (this.length === 0 || options.html === '' || options.html == null) {
if ($('#w2ui-overlay'+ name).length > 0) {
tmp_hide = $('#w2ui-overlay'+ name)[0].hide;
if (typeof tmp_hide === 'function') tmp_hide();
} else {
$('#w2ui-overlay'+ name).remove();
}
return $(this);
}
// hide previous if any
if ($('#w2ui-overlay'+ name).length > 0) {
tmp_hide = $('#w2ui-overlay'+ name)[0].hide;
$(document).off('.w2overlayHide');
if (typeof tmp_hide === 'function') tmp_hide();
}
if (obj.length > 0 && (obj[0].tagName == null || obj[0].tagName.toUpperCase() == 'BODY')) options.contextMenu = true;
if (options.contextMenu && options.originalEvent) {
options.pageX = options.originalEvent.pageX;
options.pageY = options.originalEvent.pageY;
}
if (options.contextMenu && (options.pageX == null || options.pageY == null)) {
console.log('ERROR: to display menu at mouse location, pass options.pageX and options.pageY.');
}
// append
$('body').append(
'<div id="w2ui-overlay'+ name +'" style="display: none; left: 0px; top: 0px; '+ options.overlayStyle +'"'+
' class="w2ui-reset w2ui-overlay '+ ($(this).parents('.w2ui-popup, .w2ui-overlay-popup, .w2ui-message').length > 0 ? 'w2ui-overlay-popup' : '') +'">'+
' <style></style>'+
' <div style="min-width: 100%; '+ options.style +'" class="'+ options['class'] +'"></div>'+
'</div>'
);
// init
var div1 = $('#w2ui-overlay'+ name);
var div2 = div1.find(' > div');
div2.html(options.html);
// pick bg color of first div
var bc = div2.css('background-color');
if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css({ 'background-color': bc, 'border-color': bc });
var offset = $(obj).offset() || {};
div1.data('element', obj.length > 0 ? obj[0] : null)
.data('options', options)
.data('position', offset.left + 'x' + offset.top)
.fadeIn('fast')
.on('click', function (event) {
// if there is label for input, it will produce 2 click events
if (event.target.tagName.toUpperCase() == 'LABEL') event.stopPropagation();
})
.on('mousedown', function (event) {
$('#w2ui-overlay'+ name).data('keepOpen', true);
if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1 && !options.selectable) {
event.preventDefault();
}
});
div1[0].hide = hide;
div1[0].resize = resize;
// need time to display
setTimeout(function () {
resize();
$(document).off('.w2overlayHide').on('click.w2overlayHide', hide);
if (typeof options.onShow === 'function') options.onShow();
}, 10);
monitor();
return $(this);
// monitor position
function monitor() {
var tmp = $('#w2ui-overlay'+ name);
if (tmp.data('element') !== obj[0]) return; // it if it different overlay
if (tmp.length === 0) return;
var offset = $(obj).offset() || {};
var pos = offset.left + 'x' + offset.top;
if (tmp.data('position') !== pos) {
hide();
} else {
setTimeout(monitor, 250);
}
}
// click anywhere else hides the drop down
function hide(event) {
if (event && event.button !== 0) return; // only for left click button
var div1 = $('#w2ui-overlay'+ name);
if (div1.data('keepOpen') === true) {
div1.removeData('keepOpen');
return;
}
var result;
if (typeof options.onHide === 'function') result = options.onHide();
if (result === false) return;
div1.remove();
$(document).off('click', hide);
clearInterval(div1.data('timer'));
}
function resize () {
var div1 = $('#w2ui-overlay'+ name);
var div2 = div1.find(' > div');
var menu = $('#w2ui-overlay'+ name +' div.menu');
menu.css('overflow-y', 'hidden');
// if goes over the screen, limit height and width
if (div1.length > 0) {
div2.height('auto').width('auto');
// width/height
var overflowX = false;
var overflowY = false;
var h = div2.height();
var w = div2.width();
if (options.width && options.width < w) w = options.width;
if (w < 30) w = 30;
// if content of specific height
if (options.tmp.contentHeight) {
h = parseInt(options.tmp.contentHeight);
if (h > $(".leaflet-container").height()) h = $(".leaflet-container").height();
div2.height(h);
setTimeout(function () {
var $div = div2.find('div.menu');
if (h > $div.height()) {
div2.find('div.menu').css('overflow-y', 'hidden');
}
}, 1);
setTimeout(function () {
var $div = div2.find('div.menu');
if ($div.css('overflow-y') != 'auto') $div.css('overflow-y', 'auto');
}, 10);
}
if (options.tmp.contentWidth && options.align != 'both') {
w = parseInt(options.tmp.contentWidth);
div2.width(w);
setTimeout(function () {
if (w > div2.find('div.menu > table').width()) {
div2.find('div.menu > table').css('overflow-x', 'hidden');
}
}, 1);
setTimeout(function () {
div2.find('div.menu > table').css('overflow-x', 'auto');
}, 10);
}
// adjust position
var boxLeft = options.left;
var boxWidth = options.width;
var tipLeft = options.tipLeft;
// alignment
switch (options.align) {
case 'both':
boxLeft = 17;
if (options.width === 0) options.width = w2utils.getSize($(obj), 'width');
if (options.maxWidth && options.width > options.maxWidth) options.width = options.maxWidth;
break;
case 'left':
boxLeft = 17;
break;
case 'right':
boxLeft = w2utils.getSize($(obj), 'width') - w + 10;
tipLeft = w - 40;
break;
}
if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto');
var tmp = (w - 17) / 2;
if (boxWidth != 'auto') tmp = (boxWidth - 17) / 2;
if (tmp < 25) {
boxLeft = 25 - tmp;
tipLeft = Math.floor(tmp);
}
// Y coord
var X, Y, offsetTop;
if (options.contextMenu) { // context menu
X = options.pageX + 8;
Y = options.pageY - 0;
offsetTop = options.pageY;
} else {
var offset = obj.offset() || {};
X = ((offset.left > 25 ? offset.left : 25) + boxLeft);
Y = (offset.top + w2utils.getSize(obj, 'height') + options.top + 7);
offsetTop = offset.top;
}
div1.css({
left : X + 'px',
top : Y + 'px',
'min-width' : boxWidth,
'min-height': (options.height ? options.height : 'auto')
});
// $(window).height() - has a problem in FF20
var offset = div2.offset() || {};
var maxHeight = window.innerHeight + $(document).scrollTop() - offset.top - 7;
var maxWidth = window.innerWidth + $(document).scrollLeft() - offset.left - 7;
if (options.contextMenu) { // context menu
maxHeight = window.innerHeight + $(document).scrollTop() - options.pageY - 15;
maxWidth = window.innerWidth + $(document).scrollLeft() - options.pageX;
}
if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) {
var tipOffset;
// show on top
if (options.contextMenu) { // context menu
maxHeight = options.pageY - 7;
tipOffset = 5;
} else {
maxHeight = offset.top - $(document).scrollTop() - 7;
tipOffset = 24;
}
if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight;
if (h > maxHeight) {
overflowY = true;
div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' });
h = maxHeight;
}
div1.addClass('bottom-arrow');
div1.css('top', (offsetTop - h - tipOffset + options.top) + 'px');
div1.find('>style').html(
'#w2ui-overlay'+ name +':before { margin-left: '+ parseInt(tipLeft) +'px; }'+
'#w2ui-overlay'+ name +':after { margin-left: '+ parseInt(tipLeft) +'px; }'
);
} else {
// show under
if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight;
if (h > maxHeight) {
overflowY = true;
div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' });
}
div1.addClass('top-arrow');
div1.find('>style').html(
'#w2ui-overlay'+ name +':before { margin-left: '+ parseInt(tipLeft) +'px; }'+
'#w2ui-overlay'+ name +':after { margin-left: '+ parseInt(tipLeft) +'px; }'
);
}
// check width
w = div2.width();
maxWidth = window.innerWidth + $(document).scrollLeft() - offset.left - 7;
if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth;
if (w > maxWidth && options.align !== 'both') {
options.align = 'right';
setTimeout(function () { resize(); }, 1);
}
// don't show tip
if (options.contextMenu || options.noTip) { // context menu
div1.find('>style').html(
'#w2ui-overlay'+ name +':before { display: none; }'+
'#w2ui-overlay'+ name +':after { display: none; }'
);
}
// check scroll bar (needed to avoid horizontal scrollbar)
if (overflowY && options.align != 'both') div2.width(w + w2utils.scrollBarSize() + 2);
}
menu.css('overflow-y', 'auto');
}
};
$.fn.w2menu = function (menu, options) {
/*
ITEM STRUCTURE
item : {
id : null,
text : '',
style : '',
img : '',
icon : '',
count : '',
tooltip : '',
hidden : false,
checked : null,
disabled : false
...
}
*/
// if items is a function
if (options && typeof options.items == 'function') {
options.items = options.items();
}
var defaults = {
type : 'normal', // can be normal, radio, check
index : null, // current selected
items : [],
render : null,
msgNoItems : 'No items',
onSelect : null,
tmp : {}
};
var obj = this;
var name = '';
if (menu === 'refresh') {
// if not show - call blur
if ($('#w2ui-overlay'+ name).length > 0) {
options = $.extend($.fn.w2menuOptions, options);
var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop();
$('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML());
$('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop);
mresize();
} else {
$(this).w2menu(options);
}
} else if (menu === 'refresh-index') {
var $menu = $('#w2ui-overlay'+ name +' div.menu');
var cur = $menu.find('tr[index='+ options.index +']');
var scrTop = $menu.scrollTop();
$menu.find('tr.w2ui-selected').removeClass('w2ui-selected'); // clear all
cur.addClass('w2ui-selected'); // select current
// scroll into view
if (cur.length > 0) {
var top = cur[0].offsetTop - 5; // 5 is margin top
var height = $menu.height();
$menu.scrollTop(scrTop);
if (top < scrTop || top + cur.height() > scrTop + height) {
$menu.animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear');
}
}
mresize();
} else {
if (arguments.length === 1) options = menu; else options.items = menu;
if (typeof options !== 'object') options = {};
options = $.extend({}, defaults, options);
$.fn.w2menuOptions = options;
if (options.name) name = '-' + options.name;
if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select;
if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender;
// since only one overlay can exist at a time
$.fn.w2menuClick = function (event, index) {
var keepOpen = options.keepOpen || false;
if (['radio', 'check'].indexOf(options.type) != -1) {
if (event.shiftKey || event.metaKey || event.ctrlKey) keepOpen = true;
}
if (typeof options.onSelect === 'function') {
// need time so that menu first hides
setTimeout(function () {
options.onSelect({
index: index,
item: options.items[index],
keepOpen: keepOpen,
originalEvent: event
});
}, 10);
}
// do not uncomment (or enum search type is not working in grid)
// setTimeout(function () { $(document).click(); }, 50);
// -- hide
var div = $('#w2ui-overlay'+ name);
div.removeData('keepOpen');
if (typeof div[0].hide === 'function' && !keepOpen) {
div[0].hide();
}
};
$.fn.w2menuDown = function (event, index) {
if (event.type === 'keydown') {
if (event.code === 'ArrowDown')
document.activeElement.nextElementSibling.focus();
else if (event.code === 'ArrowUp')
document.activeElement.previousElementSibling.focus();
if (event.code === 'Enter' || event.code === 'Space') {
document.activeElement.click();
return;
}
}
var $el = $(event.target).parents('tr');
var tmp = $el.find('.w2ui-icon');
if ((options.type == 'check') || (options.type == 'radio')) {
var item = options.items[index];
item.checked = !item.checked;
if (item.checked) {
if (options.type == 'radio') {
tmp.parents('table').find('.w2ui-icon')
.removeClass('w2ui-icon-check')
.addClass('w2ui-icon-empty');
}
tmp.removeClass('w2ui-icon-empty').addClass('w2ui-icon-check');
} else if (options.type == 'check') {
tmp.removeClass('w2ui-icon-check').addClass('w2ui-icon-empty');
}
}
// highlight record
$el.parent().find('tr').removeClass('w2ui-selected');
$el.addClass('w2ui-selected');
};
var html = '';
if (options.search) {
html +=
'<div style="position: absolute; top: 0px; height: 40px; left: 0px; right: 0px; border-bottom: 1px solid silver; background-color: #ECECEC; padding: 8px 5px;">'+
' <div class="w2ui-icon icon-search" style="position: absolute; margin-top: 4px; margin-left: 6px; width: 11px; background-position: left !important;"></div>'+
' <input id="menu-search" type="text" style="width: 100%; outline: none; padding-left: 20px;" onclick="event.stopPropagation();"/>'+
'</div>';
options.style += ';background-color: #ECECEC';
options.index = 0;
for (var i = 0; i < options.items.length; i++) options.items[i].hidden = false;
}
html += '<div class="menu" style="position: absolute; top: '+ (options.search ? 40 : 0) + 'px; bottom: 0px; width: 100%;">' +
getMenuHTML() +
'</div>';
var ret = $(this).w2overlay(html, options);
setTimeout(function () {
$('#w2ui-overlay'+ name +' #menu-search')
.on('keyup', change)
.on('keydown', function (event) {
// cancel tab key
if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); }
});
if (options.search) {
if (['text', 'password'].indexOf($(obj)[0].type) != -1 || $(obj)[0].tagName.toUpperCase() == 'TEXTAREA') return;
$('#w2ui-overlay'+ name +' #menu-search').focus();
}
mresize();
}, 200);
mresize();
return ret;
}
return;
function mresize() {
setTimeout(function () {
// show selected
$('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected');
var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']');
var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop();
cur.addClass('w2ui-selected');
if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10);
if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width();
if ($('#w2ui-overlay'+ name).length > 0) $('#w2ui-overlay'+ name)[0].resize();
// scroll into view
if (cur.length > 0) {
var top = cur[0].offsetTop - 5; // 5 is margin top
var el = $('#w2ui-overlay'+ name +' div.menu');
var height = el.height();
$('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop);
if (top < scrTop || top + cur.height() > scrTop + height) {
$('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear');
}
}
}, 1);
}
function change(event) {
var search = this.value;
var key = event.keyCode;
var cancel = false;
switch (key) {
case 13: // enter
$('#w2ui-overlay'+ name).remove();
$.fn.w2menuClick(event, options.index);
break;
case 9: // tab
case 27: // escape
$('#w2ui-overlay'+ name).remove();
$.fn.w2menuClick(event, -1);
break;
case 38: // up
options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0;
options.index--;
while (options.index > 0 && options.items[options.index].hidden) options.index--;
if (options.index === 0 && options.items[options.index].hidden) {
while (options.items[options.index] && options.items[options.index].hidden) options.index++;
}
if (options.index < 0) options.index = 0;
cancel = true;
break;
case 40: // down
options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0;
options.index++;
while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++;
if (options.index === options.items.length-1 && options.items[options.index].hidden) {
while (options.items[options.index] && options.items[options.index].hidden) options.index--;
}
if (options.index >= options.items.length) options.index = options.items.length - 1;
cancel = true;
break;
}
// filter
if (!cancel) {
var shown = 0;
for (var i = 0; i < options.items.length; i++) {
var item = options.items[i];
var prefix = '';
var suffix = '';
if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^';
if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$';
try {
var re = new RegExp(prefix + search + suffix, 'i');
if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true;
} catch (e) {}
// do not show selected items
if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true;
if (item.hidden !== true) shown++;
}
options.index = 0;
while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++;
if (shown <= 0) options.index = -1;
}
$(obj).w2menu('refresh', options);
mresize();
}
function getMenuHTML() {
if (options.spinner) {
return '<table class="w2ui-drop-menu"><tbody><tr><td style="padding: 5px 10px 10px 10px; text-align: center">'+
' <div class="w2ui-spinner" style="width: 18px; height: 18px; position: relative; top: 5px;"></div> '+
' <div style="display: inline-block; padding: 3px; color: #999;">'+ w2utils.lang('Loading...') +'</div>'+
'</td></tr></tbody></table>';
}
var count = 0;
var menu_html = '<table cellspacing="0" cellpadding="0" class="w2ui-drop-menu"><tbody>';
var img = null, icon = null;
for (var f = 0; f < options.items.length; f++) {
var mitem = options.items[f];
if (typeof mitem === 'string') {
mitem = { id: mitem, text: mitem };
} else {
if (mitem.text != null && mitem.id == null) mitem.id = mitem.text;
if (mitem.text == null && mitem.id != null) mitem.text = mitem.id;
if (mitem.caption != null) mitem.text = mitem.caption;
img = mitem.img;
icon = mitem.icon;
if (img == null) img = null; // img might be undefined
if (icon == null) icon = null; // icon might be undefined
}
if (['radio', 'check'].indexOf(options.type) != -1) {
if (mitem.checked === true) icon = 'w2ui-icon-check'; else icon = 'w2ui-icon-empty';
}
if (mitem.hidden !== true) {
var imgd = '';
var txt = mitem.text;
if (typeof options.render === 'function') txt = options.render(mitem, options);
if (img) imgd = '<td class="menu-icon"><div class="w2ui-tb-image w2ui-icon '+ img +'"></div></td>';
if (icon) imgd = '<td class="menu-icon" align="center"><span class="w2ui-icon '+ icon +'"></span></td>';
// render only if non-empty
if (txt != null && txt !== '' && !(/^-+$/.test(txt))) {
var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd');
if (options.altRows !== true) bg = '';
var colspan = 1;
if (imgd === '') colspan++;
if (mitem.count == null && mitem.hotkey == null) colspan++;
if (mitem.tooltip == null && mitem.hint != null) mitem.tooltip = mitem.hint; // for backward compatibility
menu_html +=
'<tr index="'+ f + '" style="'+ (mitem.style ? mitem.style : '') +'" '+ (mitem.tooltip ? 'title="'+ w2utils.lang(mitem.tooltip) +'"' : '') +
' class="'+ bg +' '+ (options.index === f ? 'w2ui-selected' : '') + ' ' + (mitem.disabled === true ? 'w2ui-disabled' : '') +'"'+
' tabIndex=0' +
' onmousedown="if ('+ (mitem.disabled === true ? 'true' : 'false') + ') return;'+
' jQuery.fn.w2menuDown(event, \''+ f +'\');"'+
' onkeydown="if ('+ (mitem.disabled === true ? 'true' : 'false') + ') return;'+
' jQuery.fn.w2menuDown(event, \''+ f +'\');"'+
' onclick="event.stopPropagation(); '+
' if ('+ (mitem.disabled === true ? 'true' : 'false') + ') return;'+
' jQuery.fn.w2menuClick(event, \''+ f +'\');">'+
imgd +
' <td class="menu-text" colspan="'+ colspan +'">'+ w2utils.lang(txt) +'</td>'+
' <td class="menu-count">'+
(mitem.count != null ? '<span>' + mitem.count + '</span>' : '') +
(mitem.hotkey != null ? '<span class="hotkey">' + mitem.hotkey + '</span>' : '') +
'</td>' +
'</tr>';
count++;
} else {
// horizontal line
menu_html += '<tr><td colspan="3" style="padding: 6px; pointer-events: none"><div style="border-top: 1px solid silver;"></div></td></tr>';
}
}
options.items[f] = mitem;
}
if (count === 0) {
menu_html += '<tr><td style="padding: 13px; color: #999; text-align: center">'+ options.msgNoItems +'</div></td></tr>';
}
menu_html += "</tbody></table>";
return menu_html;
}
};
var toW2Palette = function (corePalette) {
var pal = [];
if (!corePalette)
return pal;
for (var i = 0; i < corePalette.length; i++) {
var row = [];
for (var j = 0; j < corePalette[i].length; j++) {
row.push(corePalette[i][j].Value);
}
pal.push(row);
}
return pal;
};
var generatePalette = function (paletteName, options) {
$.fn.w2colorPalette = toW2Palette(window.app.colorPalettes[paletteName].colors);
var customColorRow = localStorage.customColor;
var recentRow = localStorage.recentColor;
if (typeof customColorRow !== 'undefined') {
$.fn.w2colorPalette.push(JSON.parse(customColorRow));
} else {
$.fn.w2colorPalette.push(['F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2']); // custom colors (up to 4)
}
if (typeof recentRow !== 'undefined') {
$.fn.w2colorPalette.push(JSON.parse(recentRow));
} else {
$.fn.w2colorPalette.push(['F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2', 'F2F2F2']); // recent colors (up to 8)
}
var pal = $.fn.w2colorPalette;
if (typeof options == 'string') options = {
color: options,
transparent: true
};
return pal;
};
$.fn.w2color = function (options, callBack) {
var el = $(this)[0];
var index = [-1, -1];
function getCurrentPaletteName() {
return (localStorage && localStorage.colorPalette
&& window.app.colorPalettes[localStorage.colorPalette])
? localStorage.colorPalette : 'StandardColors';
};
function bindEvents(pal) {
$('#w2ui-overlay .color')
.off('.w2color')
.on('mousedown.w2color keydown.w2color', function (event) {
if (event.type === 'keydown') {
if (event.code !== 'Enter' && event.code !== 'Space')
return; // Handle keydown but only for specific keys.
}
var color = $(event.originalEvent.target).attr('name');
index = $(event.originalEvent.target).attr('index').split(':');
var theme = $(event.originalEvent.target).attr('theme');
$(el).data('_color', color);
$(el).data('_theme', theme);
var recentRow = $.fn.w2colorPalette[pal.length - 1];
if (recentRow.indexOf(color) !== -1) {
recentRow.splice(recentRow.indexOf(color), 1);
}
recentRow.unshift(color);
localStorage.setItem('recentColor', JSON.stringify(recentRow));
})
.on('mouseup.w2color keyup.w2color', function (event) {
setTimeout(function () {
if (event.type === 'keyup') {
if (event.code !== 'Enter' && event.code !== 'Space')
return; // Handle keydown but only for specific keys.
}
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide();
if (event.type === 'keyup') {
if (event.code === 'Enter' || event.code === 'Space')
app.map.focus(); // Focus back to document.
}
}, 10);
});
$('#w2ui-overlay input')
.off('.w2color')
.on('mousedown.w2color', function (event) {
$('#w2ui-overlay').data('keepOpen', true);
setTimeout(function () { $('#w2ui-overlay').data('keepOpen', true); }, 10);
event.stopPropagation();
})
.on('keyup.w2color', function (event) {
if (this.value !== '' && this.value[0] !== '#') this.value = '#' + this.value;
})
.on('change.w2color', function (event) {
var tmp = this.value;
if (tmp.substr(0, 1) == '#') tmp = tmp.substr(1);
if (tmp.length != 6) {
$(this).w2tag('Invalid color.');
return;
}
var customColorRow = $.fn.w2colorPalette[pal.length - 2];
if (customColorRow.indexOf(tmp) !== -1) {
customColorRow.splice(customColorRow.indexOf(tmp), 1);
}
customColorRow.unshift(tmp.toUpperCase());
localStorage.setItem('customColor', JSON.stringify(customColorRow));
$(el).w2color(options, callBack);
setTimeout(function() { $('#w2ui-overlay input')[0].focus(); }, 100);
})
.w2field('hex');
$('#transparent-color-button')
.on('mousedown.w2color keydown.w2color', function () {
$(el).data('_color', '');
$(el).data('_theme', undefined);
});
}
var currentPalette = getCurrentPaletteName();
var pal = generatePalette(currentPalette, options);
if (options.color) options.color = String(options.color).toUpperCase();
if ($('#w2ui-overlay').length === 0) {
$(el).w2overlay(getColorHTML(pal, options), {
onHide: function () {
var data = $(el).data('_color');
var theme = $(el).data('_theme');
if (typeof callBack == 'function')
callBack(data, theme);
$(el).removeData('_color');
$(el).removeData('_theme');
}
});
} else { // only refresh contents
$('#w2ui-overlay .w2ui-color').parent().html(getColorHTML(pal, options));
}
bindEvents(pal);
var updatePalette = function () {
var palette = $('#w2ui-overlay .color-palette-selector select option:selected').get(0).value;
localStorage.setItem('colorPalette', palette);
var pal = generatePalette(palette, options);
$('#w2ui-overlay .w2ui-color').parent().html(getColorHTML(pal, options));
bindEvents(pal);
$('#w2ui-overlay .color-palette-selector select')
.on('change', updatePalette);
};
$('#w2ui-overlay .color-palette-selector select')
.on('change', updatePalette);
el.nav = function (direction) {
switch (direction) {
case 'up':
index[0]--;
break;
case 'down':
index[0]++;
break;
case 'right':
index[1]++;
break;
case 'left':
index[1]--;
break;
}
if (index[0] < 0) index[0] = 0;
if (index[0] > pal.length - 2) index[0] = pal.length - 2;
if (index[1] < 0) index[1] = 0;
if (index[1] > pal[0].length - 1) index[1] = pal[0].length - 1;
color = pal[index[0]][index[1]];
$(el).data('_color', color);
return color;
};
function getColorHTML(pal, options) {
var html = '';
var currentPalette = getCurrentPaletteName();
var hasTransparent = options.transparent;
var buttonText = hasTransparent ? _('No fill') : _('Automatic');
html += '<button id="transparent-color-button" onmousedown="event.stopPropagation(); event.preventDefault()" class="jsdialog ui-pushbutton auto-color-button">' + buttonText + '</button>';
html += '<div class="jsdialog ui-listbox-container color-palette-selector">'
+ '<select class="jsdialog ui-listbox">';
for (var i in window.app.colorPalettes) {
html += '<option value="' + i + '" ' + (i === currentPalette ? 'selected="selected"' : '') + '>' + window.app.colorPalettes[i].name + '</option>';
}
html += '</select><span class="jsdialog ui-listbox-arrow"/></div>';
var detailedPalette = window.app.colorPalettes[currentPalette].colors
html += '<div class="w2ui-color" onmousedown="event.stopPropagation(); event.preventDefault()">'+ // prevent default is needed otherwiser selection gets unselected
'<table cellspacing="5"><tbody>';
for (var i = 0; i < pal.length - 2; i++) {
html += '<tr>';
for (var j = 0; j < pal[i].length; j++) {
var themeData = detailedPalette[i][j].Data ?
JSON.stringify(detailedPalette[i][j].Data) : undefined;
html += '<td>'+
' <div class="color '+ (pal[i][j] === '' ? 'no-color' : '') +'" style="background-color: #'+ pal[i][j] +';" ' +
' name="'+ pal[i][j] +'"tabIndex=0 index="'+ i + ':' + j +'" ' + (themeData ? 'theme=\'' + themeData : '') + '\'>'+ (options.color == pal[i][j] ? '&#149;' : '&#160;') +
' </div>'+
'</td>';
if (options.color == pal[i][j]) index = [i, j];
}
html += '</tr>';
if (i < 2) html += '<tr><td style="height: 8px" colspan="8"></td></tr>';
}
var tmp1 = pal[pal.length - 2];
var tmp2 = pal[pal.length - 1];
html += '<tr><td style="height: 8px" colspan="8"></td></tr>'+
'<tr>'+
' <td colspan="4" style="text-align: left"><input placeholder="#FFF000" style="margin-left: 1px; width: 74px" maxlength="7"/></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp1[0] +';" name="'+ tmp1[0] +'" index="8:0">'+ (options.color == tmp1[0] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp1[1] +';" name="'+ tmp1[1] +'" index="8:0">'+ (options.color == tmp1[1] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp1[2] +';" name="'+ tmp1[2] +'" index="8:0">'+ (options.color == tmp1[2] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp1[3] +';" name="'+ tmp1[3] +'" index="8:0">'+ (options.color == tmp1[3] ? '&#149;' : '&#160;') +'</div></td>'+
'</tr>'+
'<tr><td style="height: 4px" colspan="8"></td></tr>' +
'<tr><td style="text-align: left;" colspan="8"><span style="margin-left: 1px;">' + _('Recent') + '</span></td></tr>' +
'<tr>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[0] +';" name="'+ tmp2[0] +'" index="8:0">'+ (options.color == tmp2[0] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[1] +';" name="'+ tmp2[1] +'" index="8:0">'+ (options.color == tmp2[1] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[2] +';" name="'+ tmp2[2] +'" index="8:0">'+ (options.color == tmp2[2] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[3] +';" name="'+ tmp2[3] +'" index="8:0">'+ (options.color == tmp2[3] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[4] +';" name="'+ tmp2[4] +'" index="8:0">'+ (options.color == tmp2[4] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[5] +';" name="'+ tmp2[5] +'" index="8:0">'+ (options.color == tmp2[5] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[6] +';" name="'+ tmp2[6] +'" index="8:0">'+ (options.color == tmp2[6] ? '&#149;' : '&#160;') +'</div></td>'+
' <td><div class="color" tabIndex=0 style="background-color: #'+ tmp2[7] +';" name="'+ tmp2[7] +'" index="8:0">'+ (options.color == tmp2[7] ? '&#149;' : '&#160;') +'</div></td>'+
'</tr>'+
'<tr><td style="height: 4px" colspan="8"></td></tr>';
html += '</tbody></table></div>';
return html;
}
};
})(jQuery);
/************************************************************************
* Library: Web 2.0 UI for jQuery (using prototypical inheritance)
* - Following objects defined
* - w2field - various field controls
* - $().w2field - jQuery wrapper
* - Dependencies: jQuery, w2utils
*
* == NICE TO HAVE ==
* - upload (regular files)
* - BUG with prefix/postfix and arrows (test in different contexts)
* - multiple date selection
* - month selection, year selections
* - arrows no longer work (for int)
* - form to support custom types
* - rewrite suffix and prefix positioning with translateY()
* - prefix and suffix are slow (100ms or so)
* - MultiSelect - Allow Copy/Paste for single and multi values
* - add routeData to list/enum
* - for type: list -> read value from attr('value')
* - ENUM, LIST: should have same as grid (limit, offset, search, sort)
* - ENUM, LIST: should support wild chars
* - add selection of predefined times (used for appointments)
*
************************************************************************/
(function ($) {
var w2field = function (options) {
// public properties
this.el = null;
this.helpers = {}; // object or helper elements
this.type = options.type || 'text';
this.options = $.extend(true, {}, options);
this.onSearch = options.onSearch || null;
this.onRequest = options.onRequest || null;
this.onLoad = options.onLoad || null;
this.onError = options.onError || null;
this.onClick = options.onClick || null;
this.onAdd = options.onAdd || null;
this.onNew = options.onNew || null;
this.onRemove = options.onRemove || null;
this.onMouseOver = options.onMouseOver || null;
this.onMouseOut = options.onMouseOut || null;
this.onIconClick = options.onIconClick || null;
this.onScroll = options.onScroll || null;
this.tmp = {}; // temp object
// clean up some options
delete this.options.type;
delete this.options.onSearch;
delete this.options.onRequest;
delete this.options.onLoad;
delete this.options.onError;
delete this.options.onClick;
delete this.options.onMouseOver;
delete this.options.onMouseOut;
delete this.options.onIconClick;
delete this.options.onScroll;
// extend with defaults
$.extend(true, this, w2obj.field);
};
// ====================================================
// -- Registers as a jQuery plugin
$.fn.w2field = function (method, options) {
// call direct
if (this.length === 0) {
var pr = w2field.prototype;
if (pr[method]) {
return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1));
}
} else {
// if without arguments - return the object
if (arguments.length === 0) {
var obj = $(this).data('w2field');
return obj;
}
if (typeof method == 'string' && typeof options == 'object') {
method = $.extend(true, {}, options, { type: method });
}
if (typeof method == 'string' && options == null) {
method = { type: method };
}
method.type = String(method.type).toLowerCase();
return this.each(function (index, el) {
var obj = $(el).data('w2field');
// if object is not defined, define it
if (obj == null) {
var obj = new w2field(method);
$.extend(obj, { handlers: [] });
if (el) obj.el = $(el)[0];
obj.init();
$(el).data('w2field', obj);
return obj;
} else { // fully re-init
obj.clear();
if (method.type == 'clear') return;
var obj = new w2field(method);
$.extend(obj, { handlers: [] });
if (el) obj.el = $(el)[0];
obj.init();
$(el).data('w2field', obj);
return obj;
}
return null;
});
}
};
// ====================================================
// -- Implementation of core functionality
/* To add custom types
$().w2field('addType', 'myType', function (options) {
$(this.el).on('keypress', function (event) {
if (event.metaKey || event.ctrlKey || event.altKey
|| (event.charCode != event.keyCode && event.keyCode > 0)) return;
var ch = String.fromCharCode(event.charCode);
if (ch != 'a' && ch != 'b' && ch != 'c') {
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
return false;
}
});
$(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox
var ch = this.value;
if (ch != 'a' && ch != 'b' && ch != 'c') {
$(this).w2tag(w2utils.lang("Not a single character from the set of 'abc'"));
}
});
});
*/
w2field.prototype = {
custom: {}, // map of custom types
addType: function (type, handler) {
type = String(type).toLowerCase();
this.custom[type] = handler;
return true;
},
removeType: function (type) {
type = String(type).toLowerCase();
if (!this.custom[type]) return false;
delete this.custom[type];
return true;
},
init: function () {
var obj = this;
var options = this.options;
var defaults;
// Custom Types
if (typeof this.custom[this.type] == 'function') {
this.custom[this.type].call(this, options);
return;
}
// only for INPUT or TEXTAREA
if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName.toUpperCase()) == -1) {
console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el);
return;
}
switch (this.type) {
case 'text':
case 'int':
case 'float':
case 'money':
case 'currency':
case 'percent':
case 'alphanumeric':
case 'bin':
case 'hex':
defaults = {
min : null,
max : null,
step : 1,
autoFormat : true,
currencyPrefix : w2utils.settings.currencyPrefix,
currencySuffix : w2utils.settings.currencySuffix,
currencyPrecision : w2utils.settings.currencyPrecision,
decimalSymbol : w2utils.settings.decimalSymbol,
groupSymbol : w2utils.settings.groupSymbol,
arrows : false,
keyboard : true,
precision : null,
silent : true,
prefix : '',
suffix : ''
};
this.options = $.extend(true, {}, defaults, options);
options = this.options; // since object is re-created, need to re-assign
options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g');
options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol +']', 'g');
options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g');
// no keyboard support needed
if (['text', 'alphanumeric', 'hex', 'bin'].indexOf(this.type) != -1) {
options.arrows = false;
options.keyboard = false;
}
this.addPrefix(); // only will add if needed
this.addSuffix();
break;
case 'color':
defaults = {
prefix : '#',
suffix : '<div style="width: '+ (parseInt($(this.el).css('font-size')) || 12) +'px">&#160;</div>',
arrows : false,
keyboard : false,
transparent : true
};
$.extend(options, defaults);
this.addPrefix(); // only will add if needed
this.addSuffix(); // only will add if needed
// additional checks
$(this.el).attr('maxlength', 6);
if ($(this.el).val() !== '') setTimeout(function () { obj.change(); }, 1);
break;
case 'date':
defaults = {
format : w2utils.settings.dateFormat, // date format
keyboard : true,
silent : true,
start : '', // string or jquery object
end : '', // string or jquery object
blocked : {}, // { '4/11/2011': 'yes' }
colored : {}, // { '4/11/2011': 'red:white' }
blockWeekDays : null // array of numbers of weekday to block
};
this.options = $.extend(true, {}, defaults, options);
options = this.options; // since object is re-created, need to re-assign
if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format);
break;
case 'time':
defaults = {
format : w2utils.settings.timeFormat,
keyboard : true,
silent : true,
start : '',
end : '',
noMinutes : false
};
this.options = $.extend(true, {}, defaults, options);
options = this.options; // since object is re-created, need to re-assign
if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format);
break;
case 'datetime':
defaults = {
format : w2utils.settings.dateFormat + ' | ' + w2utils.settings.timeFormat,
keyboard : true,
silent : true,
start : '', // string or jquery object or Date object
end : '', // string or jquery object or Date object
blocked : [], // [ '4/11/2011', '4/12/2011' ] or [ new Date(2011, 4, 11), new Date(2011, 4, 12) ]
colored : {}, // { '12/17/2014': 'blue:green', '12/18/2014': 'gray:white' }; // key has to be formatted with w2utils.settings.dateFormat
placeholder : null, // optional. will fall back to this.format if not specified. Only used if this.el has no placeholder attribute.
btn_now : true, // show/hide the use-current-date-and-time button
noMinutes : false
};
this.options = $.extend(true, {}, defaults, options);
options = this.options; // since object is re-created, need to re-assign
if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.placeholder || options.format);
break;
case 'list':
case 'combo':
defaults = {
items : [],
selected : {},
url : null, // url to pull data from
recId : null, // map retrieved data from url to id, can be string or function
recText : null, // map retrieved data from url to text, can be string or function
method : null, // default comes from w2utils.settings.dataType
interval : 350, // number of ms to wait before sending server call on search
postData : {},
minLength : 1, // min number of chars when trigger search
cacheMax : 250,
maxDropHeight : 350, // max height for drop down menu
maxDropWidth : null, // if null then auto set
match : 'begins', // ['contains', 'is', 'begins', 'ends']
silent : true,
icon : null,
iconStyle : '',
onSearch : null, // when search needs to be performed
onRequest : null, // when request is submitted
onLoad : null, // when data is received
onError : null, // when data fails to load due to server error or other failure modes
onIconClick : null,
renderDrop : null, // render function for drop down item
compare : null, // compare function for filtering
filter : true, // weather to filter at all
prefix : '',
suffix : '',
openOnFocus : false, // if to show overlay onclick or when typing
markSearch : false
};
options.items = this.normMenu(options.items); // need to be first
if (this.type == 'list') {
// defaults.search = (options.items && options.items.length >= 10 ? true : false);
defaults.openOnFocus = true;
$(this.el).addClass('w2ui-select');
// if simple value - look it up
if (!$.isPlainObject(options.selected) && options.items) {
for (var i = 0; i< options.items.length; i++) {
var item = options.items[i];
if (item && item.id == options.selected) {
options.selected = $.extend(true, {}, item);
break;
}
}
}
this.watchSize();
}
options = $.extend({}, defaults, options, {
align : 'both', // same width as control
altRows : true // alternate row color
});
this.options = options;
if (!$.isPlainObject(options.selected)) options.selected = {};
$(this.el).data('selected', options.selected);
if (options.url) {
options.items = [];
this.request(0);
}
if (this.type == 'list') this.addFocus();
this.addPrefix();
this.addSuffix();
setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh
$(this.el).attr('autocomplete', 'off');
if (options.selected.text != null) $(this.el).val(options.selected.text);
break;
case 'enum':
defaults = {
items : [],
selected : [],
max : 0, // max number of selected items, 0 - unlim
url : null, // not implemented
recId : null, // map retrieved data from url to id, can be string or function
recText : null, // map retrieved data from url to text, can be string or function
interval : 350, // number of ms to wait before sending server call on search
method : null, // default comes from w2utils.settings.dataType
postData : {},
minLength : 1, // min number of chars when trigger search
cacheMax : 250,
maxWidth : 250, // max width for a single item
maxHeight : 350, // max height for input control to grow
maxDropHeight : 350, // max height for drop down menu
maxDropWidth : null, // if null then auto set
match : 'contains', // ['contains', 'is', 'begins', 'ends']
silent : true,
openOnFocus : false, // if to show overlay onclick or when typing
markSearch : true,
renderDrop : null, // render function for drop down item
renderItem : null, // render selected item
compare : null, // compare function for filtering
filter : true, // alias for compare
style : '', // style for container div
onSearch : null, // when search needs to be performed
onRequest : null, // when request is submitted
onLoad : null, // when data is received
onError : null, // when data fails to load due to server error or other failure modes
onClick : null, // when an item is clicked
onAdd : null, // when an item is added
onNew : null, // when new item should be added
onRemove : null, // when an item is removed
onMouseOver : null, // when an item is mouse over
onMouseOut : null, // when an item is mouse out
onScroll : null // when div with selected items is scrolled
};
options = $.extend({}, defaults, options, {
align : 'both', // same width as control
suffix : '',
altRows : true // alternate row color
});
options.items = this.normMenu(options.items);
options.selected = this.normMenu(options.selected);
this.options = options;
if (!$.isArray(options.selected)) options.selected = [];
$(this.el).data('selected', options.selected);
if (options.url) {
options.items = [];
this.request(0);
}
this.addSuffix();
this.addMulti();
this.watchSize();
break;
case 'file':
defaults = {
selected : [],
max : 0,
maxSize : 0, // max size of all files, 0 - unlim
maxFileSize : 0, // max size of a single file, 0 -unlim
maxWidth : 250, // max width for a single item
maxHeight : 350, // max height for input control to grow
maxDropHeight : 350, // max height for drop down menu
maxDropWidth : null, // if null then auto set
readContent : true, // if true, it will readAsDataURL content of the file
silent : true,
renderItem : null, // render selected item
style : '', // style for container div
onClick : null, // when an item is clicked
onAdd : null, // when an item is added
onRemove : null, // when an item is removed
onMouseOver : null, // when an item is mouse over
onMouseOut : null // when an item is mouse out
};
options = $.extend({}, defaults, options, {
align : 'both', // same width as control
altRows : true // alternate row color
});
this.options = options;
if (!$.isArray(options.selected)) options.selected = [];
$(this.el).data('selected', options.selected);
if ($(this.el).attr('placeholder') == null) {
$(this.el).attr('placeholder', w2utils.lang('Attach files by dragging and dropping or Click to Select'));
}
this.addMulti();
this.watchSize();
break;
}
// attach events
this.tmp = {
onChange : function (event) { obj.change.call(obj, event); },
onClick : function (event) { obj.click.call(obj, event); },
onFocus : function (event) { obj.focus.call(obj, event); },
onBlur : function (event) { obj.blur.call(obj, event); },
onKeydown : function (event) { obj.keyDown.call(obj, event); },
onKeyup : function (event) { obj.keyUp.call(obj, event); },
onKeypress : function (event) { obj.keyPress.call(obj, event); }
};
$(this.el)
.addClass('w2field w2ui-input')
.data('w2field', this)
.on('change.w2field', this.tmp.onChange)
.on('click.w2field', this.tmp.onClick) // ignore click because it messes overlays
.on('focus.w2field', this.tmp.onFocus)
.on('blur.w2field', this.tmp.onBlur)
.on('keydown.w2field', this.tmp.onKeydown)
.on('keyup.w2field', this.tmp.onKeyup)
.on('keypress.w2field', this.tmp.onKeypress)
.css(w2utils.cssPrefix('box-sizing', 'border-box'));
// format initial value
this.change($.Event('change'));
},
watchSize: function () {
var obj = this;
var tmp = $(obj.el).data('tmp') || {};
tmp.sizeTimer = setInterval(function () {
if ($(obj.el).parents('body').length > 0) {
obj.resize();
} else {
clearInterval(tmp.sizeTimer);
}
}, 200);
$(obj.el).data('tmp', tmp);
},
get: function () {
var ret;
if (['list', 'enum', 'file'].indexOf(this.type) != -1) {
ret = $(this.el).data('selected');
} else {
ret = $(this.el).val();
}
return ret;
},
set: function (val, append) {
if (['list', 'enum', 'file'].indexOf(this.type) != -1) {
if (this.type != 'list' && append) {
if ($(this.el).data('selected') == null) $(this.el).data('selected', []);
$(this.el).data('selected').push(val);
$(this.el).change();
} else {
var it = (this.type == 'enum' ? [val] : val);
$(this.el).data('selected', it).change();
}
this.refresh();
} else {
$(this.el).val(val);
}
},
setIndex: function (ind, append) {
if (['list', 'enum'].indexOf(this.type) != -1) {
var items = this.options.items;
if (items && items[ind]) {
if (this.type != 'list' && append) {
if ($(this.el).data('selected') == null) $(this.el).data('selected', []);
$(this.el).data('selected').push(items[ind]);
$(this.el).change();
} else {
var it = (this.type == 'enum' ? [items[ind]] : items[ind]);
$(this.el).data('selected', it).change();
}
this.refresh();
return true;
}
}
return false;
},
clear: function () {
var options = this.options;
// if money then clear value
if (['money', 'currency'].indexOf(this.type) != -1) {
$(this.el).val($(this.el).val().replace(options.moneyRE, ''));
}
if (this.type == 'percent') {
$(this.el).val($(this.el).val().replace(/%/g, ''));
}
if (this.type == 'color') {
$(this.el).removeAttr('maxlength');
}
if (this.type == 'list') {
$(this.el).removeClass('w2ui-select');
}
this.type = 'clear';
var tmp = $(this.el).data('tmp');
if (!this.tmp) return;
// restore paddings
if (tmp != null) {
$(this.el).height('auto');
if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']);
if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']);
if (tmp && tmp['old-background-color']) $(this.el).css('background-color', tmp['old-background-color']);
if (tmp && tmp['old-border-color']) $(this.el).css('border-color', tmp['old-border-color']);
// remove resize watcher
clearInterval(tmp.sizeTimer);
}
// remove events and (data)
$(this.el)
.val(this.clean($(this.el).val()))
.removeClass('w2field')
.removeData() // removes all attached data
.off('.w2field'); // remove only events added by w2field
// remove helpers
for (var h in this.helpers) $(this.helpers[h]).remove();
this.helpers = {};
},
refresh: function () {
var obj = this;
var options = this.options;
var selected = $(this.el).data('selected');
var time = (new Date()).getTime();
// enum
if (['list'].indexOf(this.type) != -1) {
$(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow always to appear on the right side
// hide focus and show text
if (obj.helpers.prefix) obj.helpers.prefix.hide();
setTimeout(function () {
if (!obj.helpers.focus) return;
// if empty show no icon
if (!$.isEmptyObject(selected) && options.icon) {
options.prefix = '<span class="w2ui-icon '+ options.icon +'"style="cursor: pointer; font-size: 14px;' +
' display: inline-block; margin-top: -1px; color: #7F98AD;'+ options.iconStyle +'">'+
'</span>';
obj.addPrefix();
} else {
options.prefix = '';
obj.addPrefix();
}
// focus helper
var focus = obj.helpers.focus.find('input');
if ($(focus).val() === '') {
$(focus).css('text-indent', '-9999em').prev().css('opacity', 0);
$(obj.el).val(selected && selected.text != null ? w2utils.lang(selected.text) : '');
} else {
$(focus).css('text-indent', 0).prev().css('opacity', 1);
$(obj.el).val('');
setTimeout(function () {
if (obj.helpers.prefix) obj.helpers.prefix.hide();
var tmp = 'position: absolute; opacity: 0; margin: 4px 0px 0px 2px; background-position: left !important;';
if (options.icon) {
$(focus).css('margin-left', '17px');
$(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 11px !important; opacity: 1; display: block');
} else {
$(focus).css('margin-left', '0px');
$(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 0px !important; opacity: 0; display: none');
}
}, 1);
}
// if readonly or disabled
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) {
setTimeout(function () {
$(obj.helpers.prefix).css('opacity', '0.6');
$(obj.helpers.suffix).css('opacity', '0.6');
}, 1);
} else {
setTimeout(function () {
$(obj.helpers.prefix).css('opacity', '1');
$(obj.helpers.suffix).css('opacity', '1');
}, 1);
}
}, 1);
}
if (['enum', 'file'].indexOf(this.type) != -1) {
var html = '';
if (selected) {
for (var s = 0; s < selected.length; s++) {
var it = selected[s];
var ren = '';
if (typeof options.renderItem == 'function') {
ren = options.renderItem(it, s, '<div class="w2ui-list-remove" title="'+ w2utils.lang('Remove') +'" index="'+ s +'">&#160;&#160;</div>');
} else {
ren = '<div class="w2ui-list-remove" title="'+ w2utils.lang('Remove') +'" index="'+ s +'">&#160;&#160;</div>'+
(obj.type == 'enum' ? it.text : it.name + '<span class="file-size"> - '+ w2utils.formatSize(it.size) +'</span>');
}
html += '<li index="'+ s +'" style="max-width: '+ parseInt(options.maxWidth) + 'px; '+ (it.style ? it.style : '') +'">'+
ren +'</li>';
}
}
var div = obj.helpers.multi;
var ul = div.find('ul');
div.attr('style', div.attr('style') + ';' + options.style);
$(obj.el).css('z-index', '-1');
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) {
setTimeout(function () {
div[0].scrollTop = 0; // scroll to the top
div.addClass('w2ui-readonly')
.find('li').css('opacity', '0.9')
.parent().find('li.nomouse').hide()
.find('input').prop('readonly', true)
.parents('ul')
.find('.w2ui-list-remove').hide();
}, 1);
} else {
setTimeout(function () {
div.removeClass('w2ui-readonly')
.find('li').css('opacity', '1')
.parent().find('li.nomouse').show()
.find('input').prop('readonly', false)
.parents('ul')
.find('.w2ui-list-remove').show();
}, 1);
}
// clean
div.find('.w2ui-enum-placeholder').remove();
ul.find('li').not('li.nomouse').remove();
// add new list
if (html !== '') {
ul.prepend(html);
} else if ($(obj.el).attr('placeholder') != null && div.find('input').val() === '') {
var style =
'padding-top: ' + $(this.el).css('padding-top') + ';'+
'padding-left: ' + $(this.el).css('padding-left') + '; ' +
'box-sizing: ' + $(this.el).css('box-sizing') + '; ' +
'line-height: ' + $(this.el).css('line-height') + '; ' +
'font-size: ' + $(this.el).css('font-size') + '; ' +
'font-family: ' + $(this.el).css('font-family') + '; ';
div.prepend('<div class="w2ui-enum-placeholder" style="'+ style +'">'+ $(obj.el).attr('placeholder') +'</div>');
}
// ITEMS events
div.off('scroll.w2field').on('scroll.w2field', function (event) {
var edata = obj.trigger({ phase: 'before', type: 'scroll', target: obj.el, originalEvent: event });
if (edata.isCancelled === true) return;
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
})
.find('li')
.data('mouse', 'out')
.on('click', function (event) {
var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI'));
var item = selected[$(target).attr('index')];
if ($(target).hasClass('nomouse')) return;
event.stopPropagation();
// default behavior
if ($(event.target).hasClass('w2ui-list-remove')) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
// default behavior
$().w2overlay();
selected.splice($(event.target).attr('index'), 1);
$(obj.el).trigger('change');
$(event.target).parent().fadeOut('fast');
setTimeout(function () {
obj.refresh();
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}, 300);
} else {
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
// if file - show image preview
if (obj.type == 'file') {
var preview = '';
if ((/image/i).test(item.type)) { // image
preview = '<div style="padding: 3px;">'+
' <img src="'+ (item.content ? 'data:'+ item.type +';base64,'+ item.content : '') +'" style="max-width: 300px;" '+
' onload="var w = jQuery(this).width(); var h = jQuery(this).height(); '+
' if (w < 300 & h < 300) return; '+
' if (w >= h && w > 300) jQuery(this).width(300);'+
' if (w < h && h > 300) jQuery(this).height(300);"'+
' onerror="this.style.display = \'none\'"'+
' >'+
'</div>';
}
var td1 = 'style="padding: 3px; text-align: right; color: #777;"';
var td2 = 'style="padding: 3px"';
preview += '<div style="padding: 8px;">'+
' <table cellpadding="2"><tbody>'+
' <tr><td '+ td1 +'>'+ w2utils.lang('Name') +':</td><td '+ td2 +'>'+ item.name +'</td></tr>'+
' <tr><td '+ td1 +'>'+ w2utils.lang('Size') +':</td><td '+ td2 +'>'+ w2utils.formatSize(item.size) +'</td></tr>'+
' <tr><td '+ td1 +'>'+ w2utils.lang('Type') +':</td><td '+ td2 +'>' +
' <span style="width: 200px; display: block-inline; overflow: hidden; text-overflow: ellipsis; white-space: nowrap="nowrap";">'+ item.type +'</span>'+
' </td></tr>'+
' <tr><td '+ td1 +'>'+ w2utils.lang('Modified') +':</td><td '+ td2 +'>'+ w2utils.date(item.modified) +'</td></tr>'+
' </tbody></table>'+
'</div>';
$('#w2ui-overlay').remove();
$(target).w2overlay(preview);
} // event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
})
.on('mouseover', function (event) {
var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI'));
if ($(target).hasClass('nomouse')) return;
if ($(target).data('mouse') == 'out') {
var item = selected[$(event.target).attr('index')];
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
$(target).data('mouse', 'over');
})
.on('mouseout', function (event) {
var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI'));
if ($(target).hasClass('nomouse')) return;
$(target).data('mouse', 'leaving');
setTimeout(function () {
if ($(target).data('mouse') == 'leaving') {
$(target).data('mouse', 'out');
var item = selected[$(event.target).attr('index')];
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'mouseOut', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
}, 0);
});
// adjust height
$(this.el).height('auto');
var cntHeight = $(div).find('> div.w2ui-multi-items').height() + w2utils.getSize(div, '+height') * 2;
if (cntHeight < 26) cntHeight = 26;
if (cntHeight > options.maxHeight) cntHeight = options.maxHeight;
if (div.length > 0) div[0].scrollTop = 1000;
var inpHeight = w2utils.getSize($(this.el), 'height') - 2;
if (inpHeight > cntHeight) cntHeight = inpHeight;
$(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') });
if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0);
$(this.el).css({ 'height' : (cntHeight + 2) + 'px' });
// update size
if (obj.type == 'enum') {
var tmp = obj.helpers.multi.find('input');
tmp.width(((tmp.val().length + 2) * 8) + 'px');
}
}
return (new Date()).getTime() - time;
},
reset: function () {
var type = this.type;
this.clear();
this.type = type;
this.init();
},
// resizing width of list, enum, file controls
resize: function () {
var obj = this;
var new_width = $(obj.el).width();
var new_height = $(obj.el).height();
if (obj.tmp.current_width == new_width && new_height > 0) return;
var focus = this.helpers.focus;
var multi = this.helpers.multi;
var suffix = this.helpers.suffix;
var prefix = this.helpers.prefix;
// resize helpers
if (focus) {
focus.width($(obj.el).width());
}
if (multi) {
var width = (w2utils.getSize(obj.el, 'width')
- parseInt($(obj.el).css('margin-left'), 10)
- parseInt($(obj.el).css('margin-right'), 10));
$(multi).width(width);
}
if (suffix) {
obj.options.suffix = '<div class="arrow-down" style="margin-top: '+ ((parseInt($(obj.el).height()) - 6) / 2) +'px;"></div>';
obj.addSuffix();
}
if (prefix) {
obj.addPrefix();
}
// remember width
obj.tmp.current_width = new_width;
},
clean: function (val) {
//issue #499
if(typeof val == 'number'){
return val;
}
var options = this.options;
val = String(val).trim();
// clean
if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) {
if (typeof val == 'string') {
if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, '');
if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, '');
if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, '');
val = val.replace(/\s+/g, '').replace(w2utils.settings.groupSymbol, '').replace(w2utils.settings.decimalSymbol, '.');
}
if (parseFloat(val) == val) {
if (options.min != null && val < options.min) { val = options.min; $(this.el).val(options.min); }
if (options.max != null && val > options.max) { val = options.max; $(this.el).val(options.max); }
}
if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = '';
}
return val;
},
format: function (val) {
var options = this.options;
// autoformat numbers or money
if (options.autoFormat && val !== '') {
switch (this.type) {
case 'money':
case 'currency':
val = w2utils.formatNumber(val, options.currencyPrecision, options.groupSymbol);
if (val !== '') val = options.currencyPrefix + val + options.currencySuffix;
break;
case 'percent':
val = w2utils.formatNumber(val, options.precision, options.groupSymbol);
if (val !== '') val += '%';
break;
case 'float':
val = w2utils.formatNumber(val, options.precision, options.groupSymbol);
break;
case 'int':
val = w2utils.formatNumber(val, 0, options.groupSymbol);
break;
}
}
return val;
},
change: function (event) {
var obj = this;
var options = obj.options;
// numeric
if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) {
// check max/min
var val = $(this.el).val();
var new_val = this.format(this.clean($(this.el).val()));
// if was modified
if (val !== '' && val != new_val) {
$(this.el).val(new_val).change();
// cancel event
event.stopPropagation();
event.preventDefault();
return false;
}
}
// color
if (this.type == 'color') {
var color = '#' + $(this.el).val();
if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = '';
$(this.el).next().find('div').css('background-color', color);
if ($(obj.el).is(':focus')) this.updateOverlay();
}
// list, enum
if (['list', 'enum', 'file'].indexOf(this.type) != -1) {
obj.refresh();
// need time out to show icon indent properly
setTimeout(function () { obj.refresh(); }, 5);
}
// date, time
if (['date', 'time', 'datetime'].indexOf(this.type) != -1) {
// convert linux timestamps
var tmp = parseInt(obj.el.value);
if (w2utils.isInt(obj.el.value) && tmp > 3000) {
if (this.type == 'time') $(obj.el).val(w2utils.formatTime(new Date(tmp), options.format)).change();
if (this.type == 'date') $(obj.el).val(w2utils.formatDate(new Date(tmp), options.format)).change();
if (this.type == 'datetime') $(obj.el).val(w2utils.formatDateTime(new Date(tmp), options.format)).change();
}
}
},
click: function (event) {
event.stopPropagation();
// lists
if (['list', 'combo', 'enum'].indexOf(this.type) != -1) {
if (!$(this.el).is(':focus')) this.focus(event);
}
// other fields with drops
if (['date', 'time', 'color', 'datetime'].indexOf(this.type) != -1) {
this.updateOverlay();
}
},
focus: function (event) {
var obj = this;
var options = this.options;
// color, date, time
if (['color', 'date', 'time', 'datetime'].indexOf(obj.type) !== -1) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
setTimeout(function () { obj.updateOverlay(); }, 150);
}
// menu
if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
obj.resize();
setTimeout(function () {
if (obj.type == 'list' && $(obj.el).is(':focus')) {
$(obj.helpers.focus).find('input').focus();
return;
}
obj.search();
setTimeout(function () { obj.updateOverlay(); }, 1);
}, 1);
}
// file
if (obj.type == 'file') {
$(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' });
}
},
blur: function (event) {
var obj = this;
var options = obj.options;
var val = $(obj.el).val().trim();
// hide overlay
if (['color', 'date', 'time', 'list', 'combo', 'enum', 'datetime'].indexOf(obj.type) != -1) {
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
}
if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) {
if (val !== '' && !obj.checkType(val)) {
$(obj.el).val('').change();
if (options.silent === false) {
$(obj.el).w2tag('Not a valid number');
setTimeout(function () { $(obj.el).w2tag(''); }, 3000);
}
}
}
// date or time
if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) {
// check if in range
if (val !== '' && !obj.inRange(obj.el.value)) {
$(obj.el).val('').removeData('selected').change();
if (options.silent === false) {
$(obj.el).w2tag('Not in range');
setTimeout(function () { $(obj.el).w2tag(''); }, 3000);
}
} else {
if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) {
$(obj.el).val('').removeData('selected').change();
if (options.silent === false) {
$(obj.el).w2tag('Not a valid date');
setTimeout(function () { $(obj.el).w2tag(''); }, 3000);
}
}
else if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) {
$(obj.el).val('').removeData('selected').change();
if (options.silent === false) {
$(obj.el).w2tag('Not a valid time');
setTimeout(function () { $(obj.el).w2tag(''); }, 3000);
}
}
else if (obj.type == 'datetime' && val !== '' && !w2utils.isDateTime(obj.el.value, options.format)) {
$(obj.el).val('').removeData('selected').change();
if (options.silent === false) {
$(obj.el).w2tag('Not a valid date');
setTimeout(function () { $(obj.el).w2tag(''); }, 3000);
}
}
}
}
// clear search input
if (obj.type == 'enum') {
$(obj.helpers.multi).find('input').val('').width(20);
}
// file
if (obj.type == 'file') {
$(obj.helpers.multi).css({ 'outline': 'none' });
}
},
keyPress: function (event) {
var obj = this;
var options = obj.options;
// ignore wrong pressed key
if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'bin', 'color', 'alphanumeric'].indexOf(obj.type) != -1) {
// keyCode & charCode differ in FireFox
if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return;
var ch = String.fromCharCode(event.charCode);
if (!obj.checkType(ch, true) && event.keyCode != 13) {
event.preventDefault();
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
return false;
}
}
// update date popup
if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) {
if (event.keyCode !== 9) setTimeout(function () { obj.updateOverlay(); }, 1);
}
},
keyDown: function (event, extra) {
var obj = this;
var options = obj.options;
var key = event.keyCode || (extra && extra.keyCode);
// numeric
if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) {
if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var cancel = false;
var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0;
var inc = options.step;
if (event.ctrlKey || event.metaKey) inc = 10;
switch (key) {
case 38: // up
if (event.shiftKey) break; // no action if shift key is pressed
$(obj.el).val((val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max)).change();
cancel = true;
break;
case 40: // down
if (event.shiftKey) break; // no action if shift key is pressed
$(obj.el).val((val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min)).change();
cancel = true;
break;
}
if (cancel) {
event.preventDefault();
setTimeout(function () {
// set cursor to the end
obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length);
}, 0);
}
}
// date
if (obj.type == 'date') {
if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var cancel = false;
var daymil = 24*60*60*1000;
var inc = 1;
if (event.ctrlKey || event.metaKey) inc = 10;
var dt = w2utils.isDate($(obj.el).val(), options.format, true);
if (!dt) { dt = new Date(); daymil = 0; }
switch (key) {
case 38: // up
if (event.shiftKey) break; // no action if shift key is pressed
var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format);
if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format);
$(obj.el).val(newDT).change();
cancel = true;
break;
case 40: // down
if (event.shiftKey) break; // no action if shift key is pressed
var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format);
if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format);
$(obj.el).val(newDT).change();
cancel = true;
break;
}
if (cancel) {
event.preventDefault();
setTimeout(function () {
// set cursor to the end
obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length);
obj.updateOverlay();
}, 0);
}
}
// time
if (obj.type == 'time') {
if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var cancel = false;
var inc = (event.ctrlKey || event.metaKey ? 60 : 1);
var val = $(obj.el).val();
var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1));
switch (key) {
case 38: // up
if (event.shiftKey) break; // no action if shift key is pressed
time += inc;
cancel = true;
break;
case 40: // down
if (event.shiftKey) break; // no action if shift key is pressed
time -= inc;
cancel = true;
break;
}
if (cancel) {
$(obj.el).val(obj.fromMin(time)).change();
event.preventDefault();
setTimeout(function () {
// set cursor to the end
obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length);
}, 0);
}
}
// datetime
if (obj.type == 'datetime') {
if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var cancel = false;
var daymil = 24*60*60*1000;
var inc = 1;
if (event.ctrlKey || event.metaKey) inc = 10;
var str = $(obj.el).val();
var dt = w2utils.isDateTime(str, this.options.format, true);
if (!dt) { dt = new Date(); daymil = 0; }
switch (key) {
case 38: // up
if (event.shiftKey) break; // no action if shift key is pressed
var newDT = w2utils.formatDateTime(dt.getTime() + daymil, options.format);
if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format);
$(obj.el).val(newDT).change();
cancel = true;
break;
case 40: // down
if (event.shiftKey) break; // no action if shift key is pressed
var newDT = w2utils.formatDateTime(dt.getTime() - daymil, options.format);
if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format);
$(obj.el).val(newDT).change();
cancel = true;
break;
}
if (cancel) {
event.preventDefault();
setTimeout(function () {
// set cursor to the end
obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length);
obj.updateOverlay();
}, 0);
}
}
// color
if (obj.type == 'color') {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
// paste
if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) {
$(obj.el).prop('maxlength', 7);
setTimeout(function () {
var val = $(obj).val();
if (val.substr(0, 1) == '#') val = val.substr(1);
if (!w2utils.isHex(val)) val = '';
$(obj).val(val).prop('maxlength', 6).change();
}, 20);
}
if ((event.ctrlKey || event.metaKey) && !event.shiftKey) {
var dir = null;
var newColor = null;
switch (key) {
case 38: // up
dir = 'up';
break;
case 40: // down
dir = 'down';
break;
case 39: // right
dir = 'right';
break;
case 37: // left
dir = 'left';
break;
}
if (obj.el.nav && dir != null) {
newColor = obj.el.nav(dir);
$(obj.el).val(newColor).change();
event.preventDefault();
}
}
}
// list/select/combo
if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var selected = $(obj.el).data('selected');
var focus = $(obj.el);
var indexOnly = false;
if (['list', 'enum'].indexOf(obj.type) != -1) {
if (obj.type == 'list') {
focus = $(obj.helpers.focus).find('input');
}
if (obj.type == 'enum') {
focus = $(obj.helpers.multi).find('input');
}
// not arrows - refresh
if ([37, 38, 39, 40].indexOf(key) == -1) {
setTimeout(function () { obj.refresh(); }, 1);
}
// paste
if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) {
setTimeout(function () {
obj.refresh();
obj.search();
obj.request();
}, 50);
}
}
// apply arrows
switch (key) {
case 27: // escape
if (obj.type == 'list') {
if (focus.val() !== '') focus.val('');
event.stopPropagation(); // escape in field should not close popup
}
break;
case 37: // left
case 39: // right
// indexOnly = true;
break;
case 13: // enter
if ($('#w2ui-overlay').length === 0) break; // no action if overlay not open
var item = options.items[options.index];
if (obj.type == 'enum') {
if (item != null) {
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
item = edata.item; // need to reassign because it could be recreated by user
// default behavior
if (selected.length >= options.max && options.max > 0) selected.pop();
delete item.hidden;
delete obj.tmp.force_open;
selected.push(item);
$(obj.el).change();
focus.val('').width(20);
obj.refresh();
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
} else {
// trigger event
item = { id: focus.val(), text: focus.val() };
var edata = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
item = edata.item; // need to reassign because it could be recreated by user
// default behavior
if (typeof obj.onNew == 'function') {
if (selected.length >= options.max && options.max > 0) selected.pop();
delete obj.tmp.force_open;
selected.push(item);
$(obj.el).change();
focus.val('').width(20);
obj.refresh();
}
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
} else {
if (item) $(obj.el).data('selected', item).val(item.text).change();
if ($(obj.el).val() === '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change();
if (obj.type == 'list') {
focus.val('');
obj.refresh();
}
// hide overlay
obj.tmp.force_hide = true;
}
break;
case 8: // backspace
case 46: // delete
if (obj.type == 'enum' && key == 8) {
if (focus.val() === '' && selected.length > 0) {
var item = selected[selected.length - 1];
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item });
if (edata.isCancelled === true) return;
// default behavior
selected.pop();
$(obj.el).trigger('change');
obj.refresh();
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
}
if (obj.type == 'list' && focus.val() === '') {
$(obj.el).data('selected', {}).change();
obj.refresh();
}
break;
case 38: // up
options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0;
options.index--;
while (options.index > 0 && options.items[options.index].hidden) options.index--;
if (options.index === 0 && options.items[options.index].hidden) {
while (options.items[options.index] && options.items[options.index].hidden) options.index++;
}
indexOnly = true;
break;
case 40: // down
options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1;
options.index++;
while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++;
if (options.index == options.items.length-1 && options.items[options.index].hidden) {
while (options.items[options.index] && options.items[options.index].hidden) options.index--;
}
// show overlay if not shown
if (focus.val() === '' && $('#w2ui-overlay').length === 0) {
obj.tmp.force_open = true;
} else {
indexOnly = true;
}
break;
}
if (indexOnly) {
if (options.index < 0) options.index = 0;
if (options.index >= options.items.length) options.index = options.items.length -1;
obj.updateOverlay(indexOnly);
// cancel event
event.preventDefault();
setTimeout(function () {
// set cursor to the end
if (obj.type == 'enum') {
var tmp = focus.get(0);
tmp.setSelectionRange(tmp.value.length, tmp.value.length);
} else if (obj.type == 'list') {
var tmp = focus.get(0);
tmp.setSelectionRange(tmp.value.length, tmp.value.length);
} else {
obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length);
}
}, 0);
return;
}
// expand input
if (obj.type == 'enum') {
focus.width(((focus.val().length + 2) * 8) + 'px');
}
}
},
keyUp: function (event) {
var obj = this;
if (this.type == 'color') {
if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) {
$(this).prop('maxlength', 6);
}
}
if (['list', 'combo', 'enum'].indexOf(this.type) != -1) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
// need to be here for ipad compa
if ([16, 17, 18, 20, 37, 39, 91].indexOf(event.keyCode) == -1) { // no refreah on crtl, shift, left/right arrows, etc
var input = $(this.helpers.focus).find('input');
if (input.length === 0) input = $(this.el); // for combo list
// trigger event
var edata = this.trigger({ phase: 'before', type: 'search', originalEvent: event, target: input, search: input.val() });
if (edata.isCancelled === true) return;
// regular
if (!this.tmp.force_hide) this.request();
if (input.val().length == 1) this.refresh();
if ($('#w2ui-overlay').length === 0 || [38, 40].indexOf(event.keyCode) == -1) { // no search on arrows
this.search();
}
// event after
this.trigger($.extend(edata, { phase: 'after' }));
}
}
},
clearCache: function () {
var options = this.options;
options.items = [];
this.tmp.xhr_loading = false;
this.tmp.xhr_search = '';
this.tmp.xhr_total = -1;
},
request: function (interval) {
var obj = this;
var options = this.options;
var search = $(obj.el).val() || '';
// if no url - do nothing
if (!options.url) return;
// --
if (obj.type == 'enum') {
var tmp = $(obj.helpers.multi).find('input');
if (tmp.length === 0) search = ''; else search = tmp.val();
}
if (obj.type == 'list') {
var tmp = $(obj.helpers.focus).find('input');
if (tmp.length === 0) search = ''; else search = tmp.val();
}
if (options.minLength !== 0 && search.length < options.minLength) {
options.items = []; // need to empty the list
this.updateOverlay();
return;
}
if (interval == null) interval = options.interval;
if (obj.tmp.xhr_search == null) obj.tmp.xhr_search = '';
if (obj.tmp.xhr_total == null) obj.tmp.xhr_total = -1;
// check if need to search
if (options.url && $(obj.el).prop('readonly') !== true && $(obj.el).prop('disabled') !== true && (
(options.items.length === 0 && obj.tmp.xhr_total !== 0) ||
(obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) ||
(search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) ||
(search.length < obj.tmp.xhr_search.length)
)) {
// empty list
if (obj.tmp.xhr) obj.tmp.xhr.abort();
obj.tmp.xhr_loading = true;
obj.search();
// timeout
clearTimeout(obj.tmp.timeout);
obj.tmp.timeout = setTimeout(function () {
// trigger event
var url = options.url;
var postData = {
search : search,
max : options.cacheMax
};
$.extend(postData, options.postData);
var edata = obj.trigger({ phase: 'before', type: 'request', search: search, target: obj.el, url: url, postData: postData });
if (edata.isCancelled === true) return;
url = edata.url;
postData = edata.postData;
var ajaxOptions = {
type : 'GET',
url : url,
data : postData,
dataType : 'JSON' // expected from server
};
if (options.method) ajaxOptions.type = options.method;
if (w2utils.settings.dataType == 'JSON') {
ajaxOptions.type = 'POST';
ajaxOptions.data = JSON.stringify(ajaxOptions.data);
ajaxOptions.contentType = 'application/json';
}
if (w2utils.settings.dataType == 'HTTPJSON') {
ajaxOptions.data = { request: JSON.stringify(ajaxOptions.data) };
}
if (options.method != null) ajaxOptions.type = options.method;
obj.tmp.xhr = $.ajax(ajaxOptions)
.done(function (data, status, xhr) {
// trigger event
var edata2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr });
if (edata2.isCancelled === true) return;
// default behavior
data = edata2.data;
if (typeof data == 'string') data = JSON.parse(data);
if (data.records == null && data.items != null) {
// needed for backward compatibility
data.records = data.items;
delete data.items;
}
if (data.status != 'success' || !Array.isArray(data.records)) {
console.log('ERROR: server did not return proper structure. It should return', { status: 'success', records: [{ id: 1, text: 'item' }] });
return;
}
// remove all extra items if more then needed for cache
if (data.records.length > options.cacheMax) data.records.splice(options.cacheMax, 100000);
// map id and text
if (options.recId == null && options.recid != null) options.recId = options.recid; // since lower-case recid is used in grid
if (options.recId || options.recText) {
data.records.forEach(function (item) {
if (typeof options.recId == 'string') item.id = item[options.recId];
if (typeof options.recId == 'function') item.id = options.recId(item);
if (typeof options.recText == 'string') item.text = item[options.recText];
if (typeof options.recText == 'function') item.text = options.recText(item);
});
}
// remember stats
obj.tmp.xhr_loading = false;
obj.tmp.xhr_search = search;
obj.tmp.xhr_total = data.records.length;
options.items = obj.normMenu(data.records);
if (search === '' && data.records.length === 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false;
obj.search();
// event after
obj.trigger($.extend(edata2, { phase: 'after' }));
})
.fail(function (xhr, status, error) {
// trigger event
var errorObj = { status: status, error: error, rawResponseText: xhr.responseText };
var edata2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr });
if (edata2.isCancelled === true) return;
// default behavior
if (status != 'abort') {
var data;
try { data = $.parseJSON(xhr.responseText); } catch (e) {}
console.log('ERROR: Server communication failed.',
'\n EXPECTED:', { status: 'success', records: [{ id: 1, text: 'item' }] },
'\n OR:', { status: 'error', message: 'error message' },
'\n RECEIVED:', typeof data == 'object' ? data : xhr.responseText);
}
// reset stats
obj.clearCache();
obj.search();
// event after
obj.trigger($.extend(edata2, { phase: 'after' }));
});
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}, interval);
}
},
search: function () {
var obj = this;
var options = this.options;
var search = $(obj.el).val();
var target = obj.el;
var ids = [];
var selected = $(obj.el).data('selected');
if (obj.type == 'enum') {
target = $(obj.helpers.multi).find('input');
search = target.val();
for (var s in selected) { if (selected[s]) ids.push(selected[s].id); }
}
else if (obj.type == 'list') {
target = $(obj.helpers.focus).find('input');
search = target.val();
for (var s in selected) { if (selected[s]) ids.push(selected[s].id); }
}
if (obj.tmp.xhr_loading !== true) {
var shown = 0;
for (var i = 0; i < options.items.length; i++) {
var item = options.items[i];
if (options.compare != null) {
if (typeof options.compare == 'function') {
item.hidden = (options.compare.call(this, item, search) === false ? true : false);
}
} else {
var prefix = '';
var suffix = '';
if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^';
if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$';
try {
var re = new RegExp(prefix + search + suffix, 'i');
if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true;
} catch (e) {}
}
if (options.filter === false) item.hidden = false;
// do not show selected items
if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true;
if (item.hidden !== true) { shown++; delete item.hidden; }
}
// preselect first item
options.index = -1;
while (options.items[options.index] && options.items[options.index].hidden) options.index++;
if (shown <= 0) options.index = -1;
options.spinner = false;
obj.updateOverlay();
setTimeout(function () {
var html = $('#w2ui-overlay').html() || '';
if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items
$('#w2ui-overlay').w2marker(search);
}
}, 1);
} else {
options.items.splice(0, options.cacheMax);
options.spinner = true;
obj.updateOverlay();
}
},
updateOverlay: function (indexOnly) {
var obj = this;
var options = this.options;
// color
if (this.type == 'color') {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
$(this.el).w2color({ color: $(this.el).val(), transparent: options.transparent }, function (color) {
if (color == null) return;
$(obj.el).val(color).change();
});
}
// date
if (this.type == 'date') {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
if ($('#w2ui-overlay').length === 0) {
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar" onclick="event.stopPropagation();"></div>', {
css: { "background-color": "#f5f5f5" }
});
}
var month, year;
var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true);
if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); }
(function refreshCalendar(month, year) {
$('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year, $(obj.el).val()));
$('#w2ui-overlay .w2ui-calendar-title')
.on('mousedown', function () {
if ($(this).next().hasClass('w2ui-calendar-jump')) {
$(this).next().remove();
} else {
var selYear, selMonth;
$(this).after('<div class="w2ui-calendar-jump" style=""></div>');
$(this).next().hide().html(obj.getYearHTML()).fadeIn(200);
setTimeout(function () {
$('#w2ui-overlay .w2ui-calendar-jump')
.find('.w2ui-jump-month, .w2ui-jump-year')
.on('click', function () {
if ($(this).hasClass('w2ui-jump-month')) {
$(this).parent().find('.w2ui-jump-month').removeClass('selected');
$(this).addClass('selected');
selMonth = $(this).attr('name');
}
if ($(this).hasClass('w2ui-jump-year')) {
$(this).parent().find('.w2ui-jump-year').removeClass('selected');
$(this).addClass('selected');
selYear = $(this).attr('name');
}
if (selYear != null && selMonth != null) {
$('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100);
setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100);
}
});
$('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000);
}, 1);
}
});
$('#w2ui-overlay .w2ui-date')
.on('mousedown', function () {
var day = $(this).attr('date');
$(obj.el).val(day).change();
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
})
.on('mouseup', function () {
setTimeout(function () {
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide();
}, 10);
});
$('#w2ui-overlay .previous').on('mousedown', function () {
var tmp = obj.options.current.split('/');
tmp[0] = parseInt(tmp[0]) - 1;
refreshCalendar(tmp[0], tmp[1]);
});
$('#w2ui-overlay .next').on('mousedown', function () {
var tmp = obj.options.current.split('/');
tmp[0] = parseInt(tmp[0]) + 1;
refreshCalendar(tmp[0], tmp[1]);
});
}) (month, year);
}
// time
if (this.type == 'time') {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
if ($('#w2ui-overlay').length === 0) {
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar-time" onclick="event.stopPropagation();"></div>', {
css: { "background-color": "#fff" }
});
}
var h24 = (this.options.format == 'h24');
$('#w2ui-overlay > div').html(obj.getHourHTML());
$('#w2ui-overlay .w2ui-time')
.on('mousedown', function (event) {
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
var hour = $(this).attr('hour');
$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change();
});
if (this.options.noMinutes == null || this.options.noMinutes === false) {
$('#w2ui-overlay .w2ui-time')
.on('mouseup', function () {
var hour = $(this).attr('hour');
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar-time"></div>', { css: { "background-color": "#fff" } });
$('#w2ui-overlay > div').html(obj.getMinHTML(hour));
$('#w2ui-overlay .w2ui-time')
.on('mousedown', function () {
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
var min = $(this).attr('min');
$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change();
})
.on('mouseup', function () {
setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10);
});
});
} else {
$('#w2ui-overlay .w2ui-time')
.on('mouseup', function () {
setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10);
});
}
}
// datetime
if (this.type == 'datetime') {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
// hide overlay if we are in the time selection
if ($("#w2ui-overlay .w2ui-time").length > 0) $('#w2ui-overlay')[0].hide();
if ($('#w2ui-overlay').length === 0) {
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar" onclick="event.stopPropagation();"></div>', {
css: { "background-color": "#f5f5f5" }
});
}
var month, year;
var dt = w2utils.isDateTime($(obj.el).val(), obj.options.format, true);
if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); }
var selDate = null;
(function refreshCalendar(month, year) {
$('#w2ui-overlay > div > div').html(
obj.getMonthHTML(month, year, $(obj.el).val())
+ (options.btn_now ? '<div class="w2ui-calendar-now now">'+ w2utils.lang('Current Date & Time') + '</div>' : '')
);
$('#w2ui-overlay .w2ui-calendar-title')
.on('mousedown', function () {
if ($(this).next().hasClass('w2ui-calendar-jump')) {
$(this).next().remove();
} else {
var selYear, selMonth;
$(this).after('<div class="w2ui-calendar-jump" style=""></div>');
$(this).next().hide().html(obj.getYearHTML()).fadeIn(200);
setTimeout(function () {
$('#w2ui-overlay .w2ui-calendar-jump')
.find('.w2ui-jump-month, .w2ui-jump-year')
.on('click', function () {
if ($(this).hasClass('w2ui-jump-month')) {
$(this).parent().find('.w2ui-jump-month').removeClass('selected');
$(this).addClass('selected');
selMonth = $(this).attr('name');
}
if ($(this).hasClass('w2ui-jump-year')) {
$(this).parent().find('.w2ui-jump-year').removeClass('selected');
$(this).addClass('selected');
selYear = $(this).attr('name');
}
if (selYear != null && selMonth != null) {
$('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100);
setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100);
}
});
$('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000);
}, 1);
}
});
$('#w2ui-overlay .w2ui-date')
.on('mousedown', function () {
var day = $(this).attr('date');
$(obj.el).val(day).change();
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
selDate = new Date($(this).attr('data-date'));
})
.on('mouseup', function () {
// continue with time picker
var selHour, selMin;
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar-time"></div>', { css: { "background-color": "#fff" } });
$('#w2ui-overlay > div').html(obj.getHourHTML());
$('#w2ui-overlay .w2ui-time')
.on('mousedown', function (event) {
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
selHour = $(this).attr('hour');
selDate.setHours(selHour);
var txt = w2utils.formatDateTime(selDate, obj.options.format);
$(obj.el).val(txt).change();
//$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change();
});
if (obj.options.noMinutes == null || obj.options.noMinutes === false) {
$('#w2ui-overlay .w2ui-time')
.on('mouseup', function () {
var hour = $(this).attr('hour');
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
$(obj.el).w2overlay('<div class="w2ui-reset w2ui-calendar-time"></div>', { css: { "background-color": "#fff" } });
$('#w2ui-overlay > div').html(obj.getMinHTML(hour));
$('#w2ui-overlay .w2ui-time')
.on('mousedown', function () {
$(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' });
selMin = $(this).attr('min');
selDate.setHours(selHour, selMin);
var txt = w2utils.formatDateTime(selDate, obj.options.format);
$(obj.el).val(txt).change();
//$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change();
})
.on('mouseup', function () {
setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10);
});
});
} else {
$('#w2ui-overlay .w2ui-time')
.on('mouseup', function () {
setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10);
});
}
});
$('#w2ui-overlay .previous').on('mousedown', function () {
var tmp = obj.options.current.split('/');
tmp[0] = parseInt(tmp[0]) - 1;
refreshCalendar(tmp[0], tmp[1]);
});
$('#w2ui-overlay .next').on('mousedown', function () {
var tmp = obj.options.current.split('/');
tmp[0] = parseInt(tmp[0]) + 1;
refreshCalendar(tmp[0], tmp[1]);
});
// "now" button
$('#w2ui-overlay .now')
.on('mousedown', function () {
// this currently ignores blocked days or start / end dates!
var tmp = w2utils.formatDateTime(new Date(), obj.options.format);
$(obj.el).val(tmp).change();
return false;
})
.on('mouseup', function () {
setTimeout(function () {
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide();
}, 10);
});
}) (month, year);
}
// list
if (['list', 'combo', 'enum'].indexOf(this.type) != -1) {
var el = this.el;
var input = this.el;
if (this.type == 'enum') {
el = $(this.helpers.multi);
input = $(el).find('input');
}
if (this.type == 'list') {
var sel = $(input).data('selected');
if ($.isPlainObject(sel) && !$.isEmptyObject(sel) && options.index == -1) {
options.items.forEach(function (item, ind) {
if (item.id == sel.id) {
options.index = ind;
}
});
}
input = $(this.helpers.focus).find('input');
}
if ($(input).is(':focus')) {
if (options.openOnFocus === false && $(input).val() === '' && obj.tmp.force_open !== true) {
$().w2overlay();
return;
}
if (obj.tmp.force_hide) {
$().w2overlay();
setTimeout(function () {
delete obj.tmp.force_hide;
}, 1);
return;
}
if ($(input).val() !== '') delete obj.tmp.force_open;
var msgNoItems = w2utils.lang('No matches');
if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...');
if (options.url != null && $(input).val() === '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search...');
if (options.url == null && options.items.length === 0) msgNoItems = w2utils.lang('Empty list');
if (options.msgNoItems != null) msgNoItems = options.msgNoItems;
if (msgNoItems == 'function') msgNoItems = msgNoItems(options);
$(el).w2menu((!indexOnly ? 'refresh' : 'refresh-index'), $.extend(true, {}, options, {
search : false,
render : options.renderDrop,
maxHeight : options.maxDropHeight,
maxWidth : options.maxDropWidth,
msgNoItems : msgNoItems,
// selected with mouse
onSelect: function (event) {
if (obj.type == 'enum') {
var selected = $(obj.el).data('selected');
if (event.item) {
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item });
if (edata.isCancelled === true) return;
// default behavior
if (selected.length >= options.max && options.max > 0) selected.pop();
delete event.item.hidden;
selected.push(event.item);
$(obj.el).data('selected', selected).change();
$(obj.helpers.multi).find('input').val('').width(20);
obj.refresh();
if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide();
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
}
} else {
$(obj.el).data('selected', event.item).val(event.item.text).change();
if (obj.helpers.focus) obj.helpers.focus.find('input').val('');
}
}
}));
}
}
},
inRange: function (str, onlyDate) {
var inRange = false;
if (this.type == 'date') {
var dt = w2utils.isDate(str, this.options.format, true);
if (dt) {
// enable range
if (this.options.start || this.options.end) {
var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val());
var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val());
var start = w2utils.isDate(st, this.options.format, true);
var end = w2utils.isDate(en, this.options.format, true);
var current = new Date(dt);
if (!start) start = current;
if (!end) end = current;
if (current >= start && current <= end) inRange = true;
} else {
inRange = true;
}
// block predefined dates
if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false;
/*
clockWeekDay - type: array or integers. every element - number of week day.
number of weekday (1 - monday, 2 - tuesday, 3 - wensday, 4 - thursday, 5 - friday, 6 - saturday, 0 - sunday)
for block in calendar (for example, block all sundays so user can't choose sunday in calendar)
*/
if (this.options.blockWeekDays != null && this.options.blockWeekDays != undefined
&& this.options.blockWeekDays.length != undefined){
var l = this.options.blockWeekDays.length;
for (var i=0; i<l; i++){
if (dt.getDay() == this.options.blockWeekDays[i]){
inRange = false;
}
}
}
}
} else if (this.type == 'time') {
if (this.options.start || this.options.end) {
var tm = this.toMin(str);
var tm1 = this.toMin(this.options.start);
var tm2 = this.toMin(this.options.end);
if (!tm1) tm1 = tm;
if (!tm2) tm2 = tm;
if (tm >= tm1 && tm <= tm2) inRange = true;
} else {
inRange = true;
}
} else if (this.type == 'datetime') {
var dt = w2utils.isDateTime(str, this.options.format, true);
if (dt) {
// enable range
if (this.options.start || this.options.end) {
var start, end;
if (typeof this.options.start == 'object' && this.options.start instanceof Date) {
start = this.options.start;
} else {
var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val());
if (st.trim() !== '') {
start = w2utils.isDateTime(st, this.options.format, true);
} else {
start = '';
}
}
if (typeof this.options.end == 'object' && this.options.end instanceof Date) {
end = this.options.end;
} else {
var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val());
if (en.trim() !== '') {
end = w2utils.isDateTime(en, this.options.format, true);
} else {
end = '';
}
}
var current = dt; // new Date(dt);
if (!start) start = current;
if (!end) end = current;
if (onlyDate && start instanceof Date) {
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
}
if (current >= start && current <= end) inRange = true;
} else {
inRange = true;
}
// block predefined dates
if (inRange && this.options.blocked) {
for (var i=0; i<this.options.blocked.length; i++) {
var blocked = this.options.blocked[i];
if(typeof blocked == 'string') {
// convert string to Date object
blocked = w2utils.isDateTime(blocked, this.options.format, true);
}
// check for Date object with the same day
if(typeof blocked == 'object' && blocked instanceof Date && (blocked.getFullYear() == dt.getFullYear() && blocked.getMonth() == dt.getMonth() && blocked.getDate() == dt.getDate())) {
inRange = false;
break;
}
}
}
}
}
return inRange;
},
/*
* INTERNAL FUNCTIONS
*/
checkType: function (ch, loose) {
var obj = this;
switch (obj.type) {
case 'int':
if (loose && ['-', obj.options.groupSymbol].indexOf(ch) != -1) return true;
return w2utils.isInt(ch.replace(obj.options.numberRE, ''));
case 'percent':
ch = ch.replace(/%/g, '');
case 'float':
if (loose && ['-', w2utils.settings.decimalSymbol, obj.options.groupSymbol].indexOf(ch) != -1) return true;
return w2utils.isFloat(ch.replace(obj.options.numberRE, ''));
case 'money':
case 'currency':
if (loose && ['-', obj.options.decimalSymbol, obj.options.groupSymbol, obj.options.currencyPrefix, obj.options.currencySuffix].indexOf(ch) != -1) return true;
return w2utils.isFloat(ch.replace(obj.options.moneyRE, ''));
case 'bin':
return w2utils.isBin(ch);
case 'hex':
case 'color':
return w2utils.isHex(ch);
case 'alphanumeric':
return w2utils.isAlphaNumeric(ch);
}
return true;
},
addPrefix: function () {
var obj = this;
setTimeout(function () {
if (obj.type === 'clear') return;
var helper;
var tmp = $(obj.el).data('tmp') || {};
if (tmp['old-padding-left']) $(obj.el).css('padding-left', tmp['old-padding-left']);
tmp['old-padding-left'] = $(obj.el).css('padding-left');
$(obj.el).data('tmp', tmp);
// remove if already displaed
if (obj.helpers.prefix) $(obj.helpers.prefix).remove();
if (obj.options.prefix !== '') {
// add fresh
$(obj.el).before(
'<div class="w2ui-field-helper">'+
obj.options.prefix +
'</div>'
);
helper = $(obj.el).prev();
helper
.css({
'color' : $(obj.el).css('color'),
'font-family' : $(obj.el).css('font-family'),
'font-size' : $(obj.el).css('font-size'),
'padding-top' : $(obj.el).css('padding-top'),
'padding-bottom' : $(obj.el).css('padding-bottom'),
'padding-left' : $(obj.el).css('padding-left'),
'padding-right' : 0,
'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px',
'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px',
'margin-left' : $(obj.el).css('margin-left'),
'margin-right' : 0
})
.on('click', function (event) {
if (obj.options.icon && typeof obj.onIconClick == 'function') {
// event before
var edata = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] });
if (edata.isCancelled === true) return;
// intentionally empty
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
} else {
if (obj.type == 'list') {
$(obj.helpers.focus).find('input').focus();
} else {
$(obj.el).focus();
}
}
});
$(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px');
// remember helper
obj.helpers.prefix = helper;
}
}, 1);
},
addSuffix: function () {
var obj = this;
var helper, pr;
setTimeout(function () {
if (obj.type === 'clear') return;
var tmp = $(obj.el).data('tmp') || {};
if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']);
tmp['old-padding-right'] = $(obj.el).css('padding-right');
$(obj.el).data('tmp', tmp);
pr = parseInt($(obj.el).css('padding-right'), 10);
if (obj.options.arrows) {
// remove if already displayed
if (obj.helpers.arrows) $(obj.helpers.arrows).remove();
// add fresh
$(obj.el).after(
'<div class="w2ui-field-helper" style="border: 1px solid transparent">&#160;'+
' <div class="w2ui-field-up" type="up">'+
' <div class="arrow-up" type="up"></div>'+
' </div>'+
' <div class="w2ui-field-down" type="down">'+
' <div class="arrow-down" type="down"></div>'+
' </div>'+
'</div>');
helper = $(obj.el).next();
helper.css({
'color' : $(obj.el).css('color'),
'font-family' : $(obj.el).css('font-family'),
'font-size' : $(obj.el).css('font-size'),
'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px',
'padding' : 0,
'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px',
'margin-bottom' : 0,
'border-left' : '1px solid silver'
})
.css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px')
.on('mousedown', function (event) {
var body = $('body');
body.on('mouseup', tmp);
body.data('_field_update_timer', setTimeout(update, 700));
update(false);
// timer function
function tmp() {
clearTimeout(body.data('_field_update_timer'));
body.off('mouseup', tmp);
}
// update function
function update(notimer) {
$(obj.el).focus();
obj.keyDown($.Event("keydown"), {
keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40)
});
if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60));
}
});
pr += helper.width() + 12;
$(obj.el).css('padding-right', pr + 'px');
// remember helper
obj.helpers.arrows = helper;
}
if (obj.options.suffix !== '') {
// remove if already displayed
if (obj.helpers.suffix) $(obj.helpers.suffix).remove();
// add fresh
$(obj.el).after(
'<div class="w2ui-field-helper">'+
obj.options.suffix +
'</div>');
helper = $(obj.el).next();
helper
.css({
'color' : $(obj.el).css('color'),
'font-family' : $(obj.el).css('font-family'),
'font-size' : $(obj.el).css('font-size'),
'padding-top' : $(obj.el).css('padding-top'),
'padding-bottom' : $(obj.el).css('padding-bottom'),
'padding-left' : '3px',
'padding-right' : $(obj.el).css('padding-right'),
'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px',
'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px'
})
.on('click', function (event) {
if (obj.type == 'list') {
$(obj.helpers.focus).find('input').focus();
} else {
$(obj.el).focus();
}
});
helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px');
pr += helper.width() + 3;
$(obj.el).css('padding-right', pr + 'px');
// remember helper
obj.helpers.suffix = helper;
}
}, 1);
},
addFocus: function () {
var obj = this;
var options = this.options;
var width = 0; // 11 - show search icon, 0 do not show
var pholder;
// clean up & init
$(obj.helpers.focus).remove();
// remember original tabindex
var tabIndex = $(obj.el).attr('tabIndex');
if (tabIndex && tabIndex != -1) obj.el._tabIndex = tabIndex;
if (obj.el._tabIndex) tabIndex = obj.el._tabIndex;
if (tabIndex == null) tabIndex = -1;
// build helper
var html =
'<div class="w2ui-field-helper">'+
' <div class="w2ui-icon icon-search" style="opacity: 0; display: none"></div>'+
' <input type="text" autocomplete="off" tabIndex="'+ tabIndex +'"/>'+
'</div>';
$(obj.el).attr('tabindex', -1).before(html);
var helper = $(obj.el).prev();
obj.helpers.focus = helper;
helper.css({
width : $(obj.el).width(),
"margin-top" : $(obj.el).css('margin-top'),
"margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px',
"margin-bottom" : $(obj.el).css('margin-bottom'),
"margin-right" : $(obj.el).css('margin-right')
})
.find('input')
.css({
cursor : 'default',
width : '100%',
outline : 'none',
opacity : 1,
margin : 0,
border : '1px solid transparent',
padding : $(obj.el).css('padding-top'),
"padding-left" : 0,
"margin-left" : (width > 0 ? width + 6 : 0),
"background-color" : 'transparent'
});
// INPUT events
helper.find('input')
.on('click', function (event) {
if ($('#w2ui-overlay').length === 0) obj.focus(event);
event.stopPropagation();
})
.on('focus', function (event) {
pholder = $(obj.el).attr('placeholder');
$(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' });
$(this).val('');
$(obj.el).triggerHandler('focus');
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
})
.on('blur', function (event) {
$(obj.el).css('outline', 'none');
$(this).val('');
obj.refresh();
$(obj.el).triggerHandler('blur');
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
if (pholder != null) $(obj.el).attr('placeholder', pholder);
})
.on('keydown', function (event) {
var el = this;
obj.keyDown(event);
setTimeout(function () {
if (el.value === '') $(obj.el).attr('placeholder', pholder); else $(obj.el).attr('placeholder', '');
}, 10);
})
.on('keyup', function (event) { obj.keyUp(event); })
.on('keypress', function (event) { obj.keyPress(event); });
// MAIN div
helper.on('click', function (event) { $(this).find('input').focus(); });
obj.refresh();
},
addMulti: function () {
var obj = this;
var options = this.options;
// clean up & init
$(obj.helpers.multi).remove();
// build helper
var html = '';
var margin =
'margin-top : 0px; ' +
'margin-bottom : 0px; ' +
'margin-left : ' + $(obj.el).css('margin-left') + '; ' +
'margin-right : ' + $(obj.el).css('margin-right') + '; '+
'width : ' + (w2utils.getSize(obj.el, 'width')
- parseInt($(obj.el).css('margin-left'), 10)
- parseInt($(obj.el).css('margin-right'), 10))
+ 'px;';
if (obj.type == 'enum') {
// remember original tabindex
var tabIndex = $(obj.el).attr('tabIndex');
if (tabIndex && tabIndex != -1) obj.el._tabIndex = tabIndex;
if (obj.el._tabIndex) tabIndex = obj.el._tabIndex;
if (tabIndex == null) tabIndex = -1;
html = '<div class="w2ui-field-helper w2ui-list" style="'+ margin + '; box-sizing: border-box">'+
' <div style="padding: 0px; margin: 0px; display: inline-block" class="w2ui-multi-items">'+
' <ul>'+
' <li style="padding-left: 0px; padding-right: 0px" class="nomouse">'+
' <input type="text" style="width: 20px; margin: -3px 0 0; padding: 2px 0; border-color: white" autocomplete="off"' + ($(obj.el).prop('readonly') ? ' readonly="readonly"': '') + ($(obj.el).prop('disabled') ? ' disabled="disabled"': '') + ' tabindex="'+ tabIndex +'"/>'+
' </li>'+
' </ul>'+
' </div>'+
'</div>';
}
if (obj.type == 'file') {
html = '<div class="w2ui-field-helper w2ui-list" style="'+ margin + '; box-sizing: border-box">'+
' <div style="position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px;">'+
' <input class="file-input" type="file" style="width: 100%; height: 100%; opacity: 0;" name="attachment" multiple tabindex="-1"' + ($(obj.el).prop('readonly') ? ' readonly="readonly"': '') + ($(obj.el).prop('disabled') ? ' disabled="disabled"': '') + ($(obj.el).attr('accept') ? ' accept="'+ $(obj.el).attr('accept') +'"': '') + '/>'+
' </div>'+
' <div style="position: absolute; padding: 0px; margin: 0px; display: inline-block" class="w2ui-multi-items">'+
' <ul><li style="padding-left: 0px; padding-right: 0px" class="nomouse"></li></ul>'+
' </div>'+
'</div>';
}
// old bg and border
var tmp = $(obj.el).data('tmp') || {};
tmp['old-background-color'] = $(obj.el).css('background-color');
tmp['old-border-color'] = $(obj.el).css('border-color');
$(obj.el).data('tmp', tmp);
$(obj.el)
.before(html)
.css({
'background-color' : 'transparent',
'border-color' : 'transparent'
});
var div = $(obj.el).prev();
obj.helpers.multi = div;
if (obj.type == 'enum') {
$(obj.el).attr('tabindex', -1);
// INPUT events
div.find('input')
.on('click', function (event) {
if ($('#w2ui-overlay').length === 0) obj.focus(event);
$(obj.el).triggerHandler('click');
})
.on('focus', function (event) {
$(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' });
$(obj.el).triggerHandler('focus');
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
})
.on('blur', function (event) {
$(div).css('outline', 'none');
$(obj.el).triggerHandler('blur');
if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true;
})
.on('keyup', function (event) { obj.keyUp(event); })
.on('keydown', function (event) { obj.keyDown(event); })
.on('keypress', function (event) { obj.keyPress(event); });
// MAIN div
div.on('click', function (event) { $(this).find('input').focus(); });
}
if (obj.type == 'file') {
$(obj.el).css('outline', 'none');
div.on('click', function (event) {
$(obj.el).focus();
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
obj.blur(event);
obj.resize();
setTimeout(function () { div.find('input').click(); }, 10); // needed this when clicked on items div
})
.on('dragenter', function (event) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
$(div).addClass('w2ui-file-dragover');
})
.on('dragleave', function (event) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
var tmp = $(event.target).parents('.w2ui-field-helper');
if (tmp.length === 0) $(div).removeClass('w2ui-file-dragover');
})
.on('drop', function (event) {
if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return;
$(div).removeClass('w2ui-file-dragover');
var files = event.originalEvent.dataTransfer.files;
for (var i = 0, l = files.length; i < l; i++) obj.addFile.call(obj, files[i]);
// cancel to stop browser behaviour
event.preventDefault();
event.stopPropagation();
})
.on('dragover', function (event) {
// cancel to stop browser behaviour
event.preventDefault();
event.stopPropagation();
});
div.find('input')
.on('click', function (event) {
event.stopPropagation();
})
.on('change', function () {
if (typeof this.files !== "undefined") {
for (var i = 0, l = this.files.length; i < l; i++) {
obj.addFile.call(obj, this.files[i]);
}
}
});
}
obj.refresh();
},
addFile: function (file) {
var obj = this;
var options = this.options;
var selected = $(obj.el).data('selected');
var newItem = {
name : file.name,
type : file.type,
modified : file.lastModifiedDate,
size : file.size,
content : null,
file : file
};
var size = 0;
var cnt = 0;
var err;
if (selected) {
for (var s = 0; s < selected.length; s++) {
// check for dups
if (selected[s].name == file.name && selected[s].size == file.size) return;
size += selected[s].size;
cnt++;
}
}
// trigger event
var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, file: newItem, total: cnt, totalSize: size });
if (edata.isCancelled === true) return;
// check params
if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) {
err = 'Maximum file size is '+ w2utils.formatSize(options.maxFileSize);
if (options.silent === false) $(obj.el).w2tag(err);
console.log('ERROR: '+ err);
return;
}
if (options.maxSize !== 0 && size + newItem.size > options.maxSize) {
err = 'Maximum total size is '+ w2utils.formatSize(options.maxSize);
if (options.silent === false) $(obj.el).w2tag(err);
console.log('ERROR: '+ err);
return;
}
if (options.max !== 0 && cnt >= options.max) {
err = 'Maximum number of files is '+ options.max;
if (options.silent === false) $(obj.el).w2tag(err);
console.log('ERROR: '+ err);
return;
}
selected.push(newItem);
// read file as base64
if (typeof FileReader !== "undefined" && options.readContent === true) {
var reader = new FileReader();
// need a closure
reader.onload = (function () {
return function (event) {
var fl = event.target.result;
var ind = fl.indexOf(',');
newItem.content = fl.substr(ind+1);
obj.refresh();
$(obj.el).trigger('change');
// event after
obj.trigger($.extend(edata, { phase: 'after' }));
};
})();
reader.readAsDataURL(file);
} else {
obj.refresh();
$(obj.el).trigger('change');
}
},
normMenu: function (menu) {
if ($.isArray(menu)) {
for (var m = 0; m < menu.length; m++) {
if (typeof menu[m] == 'string') {
menu[m] = { id: menu[m], text: menu[m] };
} else {
if (menu[m].text != null && menu[m].id == null) menu[m].id = menu[m].text;
if (menu[m].text == null && menu[m].id != null) menu[m].text = menu[m].id;
if (menu[m].caption != null) menu[m].text = menu[m].caption;
}
}
return menu;
} else if (typeof menu == 'function') {
return this.normMenu(menu());
} else if (typeof menu == 'object') {
var tmp = [];
for (var m in menu) tmp.push({ id: m, text: menu[m] });
return tmp;
}
},
getMonthHTML: function (month, year, selected) {
var td = new Date();
var months = w2utils.settings.fullmonths;
var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31'];
var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate();
var days = w2utils.settings.fulldays.slice(); // creates copy of the array
var sdays = w2utils.settings.shortdays.slice(); // creates copy of the array
if (w2utils.settings.weekStarts != 'M') {
days.unshift(days.pop());
sdays.unshift(sdays.pop());
}
var options = this.options;
if (options == null) options = {};
// normalize date
year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear();
month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1;
if (month > 12) { month -= 12; year++; }
if (month < 1 || month === 0) { month += 12; year--; }
if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; }
options.current = month + '/' + year;
// start with the required date
td = new Date(year, month-1, 1);
var weekDay = td.getDay();
var dayTitle = '';
for (var i = 0; i < sdays.length; i++) dayTitle += '<td title="'+ days[i] +'">' + sdays[i] + '</td>';
var html =
'<div class="w2ui-calendar-title title">'+
' <div class="w2ui-calendar-previous previous"> <div></div> </div>'+
' <div class="w2ui-calendar-next next"> <div></div> </div> '+
months[month-1] +', '+ year +
'</div>'+
'<table class="w2ui-calendar-days" cellspacing="0"><tbody>'+
' <tr class="w2ui-day-title">' + dayTitle + '</tr>'+
' <tr>';
var day = 1;
if (w2utils.settings.weekStarts != 'M') weekDay++;
if(this.type === 'datetime') {
var dt_sel = w2utils.isDateTime(selected, options.format, true);
selected = w2utils.formatDate(dt_sel, w2utils.settings.dateFormat);
}
for (var ci = 1; ci < 43; ci++) {
if (weekDay === 0 && ci == 1) {
for (var ti = 0; ti < 6; ti++) html += '<td class="w2ui-day-empty">&#160;</td>';
ci += 6;
} else {
if (ci < weekDay || day > daysCount[month-1]) {
html += '<td class="w2ui-day-empty">&#160;</td>';
if ((ci) % 7 === 0) html += '</tr><tr>';
continue;
}
}
var dt = year + '/' + month + '/' + day;
var DT = new Date(dt);
var className = '';
if (DT.getDay() === 6) className = ' w2ui-saturday';
if (DT.getDay() === 0) className = ' w2ui-sunday';
if (dt == today) className += ' w2ui-today';
var dspDay = day;
var col = '';
var bgcol = '';
var tmp_dt, tmp_dt_fmt;
if(this.type === 'datetime') {
// var fm = options.format.split('|')[0].trim();
// tmp_dt = w2utils.formatDate(dt, fm);
tmp_dt = w2utils.formatDateTime(dt, options.format);
tmp_dt_fmt = w2utils.formatDate(dt, w2utils.settings.dateFormat);
} else {
tmp_dt = w2utils.formatDate(dt, options.format);
tmp_dt_fmt = tmp_dt;
}
if (options.colored && options.colored[tmp_dt_fmt] !== undefined) { // if there is predefined colors for dates
var tmp = options.colored[tmp_dt_fmt].split(':');
bgcol = 'background-color: ' + tmp[0] + ';';
col = 'color: ' + tmp[1] + ';';
}
html += '<td class="'+ (this.inRange(tmp_dt, true) ? 'w2ui-date ' + (tmp_dt_fmt == selected ? 'w2ui-date-selected' : '') : 'w2ui-blocked') + className + '" '+
' style="'+ col + bgcol + '" date="'+ tmp_dt +'" data-date="'+ DT +'">'+
dspDay +
'</td>';
if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += '</tr><tr>';
day++;
}
html += '</tr></tbody></table>';
return html;
},
getYearHTML: function () {
var months = w2utils.settings.shortmonths;
var start_year = w2utils.settings.dateStartYear;
var end_year = w2utils.settings.dateEndYear;
var mhtml = '';
var yhtml = '';
for (var m = 0; m < months.length; m++) {
mhtml += '<div class="w2ui-jump-month" name="'+ m +'">'+ months[m] + '</div>';
}
for (var y = start_year; y <= end_year; y++) {
yhtml += '<div class="w2ui-jump-year" name="'+ y +'">'+ y + '</div>';
}
return '<div>'+ mhtml +'</div><div>'+ yhtml +'</div>';
},
getHourHTML: function () {
var tmp = [];
var options = this.options;
if (options == null) options = { format: w2utils.settings.timeFormat };
var h24 = (options.format.indexOf('h24') > -1);
for (var a = 0; a < 24; a++) {
var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : '');
if (a == 12 && !h24) time = '12:00 pm';
if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = '';
var tm1 = this.fromMin(this.toMin(time));
var tm2 = this.fromMin(this.toMin(time) + 59);
if (this.type === 'datetime') {
var dt = w2utils.isDateTime(this.el.value, options.format, true);
var fm = options.format.split('|')[0].trim();
tm1 = w2utils.formatDate(dt, fm) + ' ' + tm1;
tm2 = w2utils.formatDate(dt, fm) + ' ' + tm2;
}
tmp[Math.floor(a/8)] += '<div class="'+ (this.inRange(tm1) || this.inRange(tm2) ? 'w2ui-time ' : 'w2ui-blocked') + '" hour="'+ a +'">'+ time +'</div>';
}
var html =
'<div class="w2ui-calendar">'+
' <div class="w2ui-calendar-title">'+ w2utils.lang('Select Hour') +'</div>'+
' <div class="w2ui-calendar-time"><table><tbody><tr>'+
' <td>'+ tmp[0] +'</td>' +
' <td>'+ tmp[1] +'</td>' +
' <td>'+ tmp[2] +'</td>' +
' </tr></tbody></table></div>'+
'</div>';
return html;
},
getMinHTML: function (hour) {
if (hour == null) hour = 0;
var options = this.options;
if (options == null) options = { format: w2utils.settings.timeFormat };
var h24 = (options.format.indexOf('h24') > -1);
var tmp = [];
for (var a = 0; a < 60; a += 5) {
var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : '');
var tm = time;
var ind = a < 20 ? 0 : (a < 40 ? 1 : 2);
if (!tmp[ind]) tmp[ind] = '';
if (this.type === 'datetime') {
var dt = w2utils.isDateTime(this.el.value, options.format, true);
var fm = options.format.split('|')[0].trim();
tm = w2utils.formatDate(dt, fm) + ' ' + tm;
}
tmp[ind] += '<div class="'+ (this.inRange(tm) ? 'w2ui-time ' : 'w2ui-blocked') + '" min="'+ a +'">'+ time +'</div>';
}
var html =
'<div class="w2ui-calendar">'+
' <div class="w2ui-calendar-title">'+ w2utils.lang('Select Minute') +'</div>'+
' <div class="w2ui-calendar-time"><table><tbody><tr>'+
' <td>'+ tmp[0] +'</td>' +
' <td>'+ tmp[1] +'</td>' +
' <td>'+ tmp[2] +'</td>' +
' </tr></tbody></table></div>'+
'</div>';
return html;
},
toMin: function (str) {
if (typeof str != 'string') return null;
var tmp = str.split(':');
if (tmp.length === 2) {
tmp[0] = parseInt(tmp[0]);
tmp[1] = parseInt(tmp[1]);
if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12;
} else {
return null;
}
return tmp[0] * 60 + tmp[1];
},
fromMin: function (time) {
var ret = '';
if (time >= 24 * 60) time = time % (24 * 60);
if (time < 0) time = 24 * 60 + time;
var hour = Math.floor(time/60);
var min = ((time % 60) < 10 ? '0' : '') + (time % 60);
var options = this.options;
if (options == null) options = { format: w2utils.settings.timeFormat };
if (options.format.indexOf('h24') != -1) {
ret = hour + ':' + min;
} else {
ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am');
}
return ret;
}
};
$.extend(w2field.prototype, w2utils.event);
w2obj.field = w2field;
}) (jQuery);
/************************************************************************
* Library: Web 2.0 UI for jQuery (using prototypical inheritance)
* - Following objects defined
* - w2toolbar - toolbar widget
* - $().w2toolbar - jQuery wrapper
* - Dependencies: jQuery, w2utils, w2field
*
* == NICE TO HAVE ==
* - vertical toolbar
*
************************************************************************/
(function ($) {
var w2toolbar = function (options) {
this.box = null; // DOM Element that holds the element
this.name = null; // unique name for w2ui
this.routeData = {}; // data for dynamic routes
this.items = [];
this.right = ''; // HTML text on the right of toolbar
this.tooltip = 'top|left';// can be top, bottom, left, right
$.extend(true, this, w2obj.toolbar, options);
};
// ====================================================
// -- Registers as a jQuery plugin
$.fn.w2toolbar = function(method) {
if ($.isPlainObject(method)) {
// check name parameter
if (!w2utils.checkName(method, 'w2toolbar')) return;
// extend items
var items = method.items || [];
var object = new w2toolbar(method);
$.extend(object, { items: [], handlers: [] });
for (var i = 0; i < items.length; i++) {
object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]);
// menus
if (object.items[i].type == 'menu-check') {
var item = object.items[i];
if (!Array.isArray(item.selected)) item.selected = [];
if (Array.isArray(item.items)) {
for (var j = 0; j < item.items.length; j++) {
var it = item.items[j];
if (it.checked && item.selected.indexOf(it.id) == -1) item.selected.push(it.id);
if (!it.checked && item.selected.indexOf(it.id) != -1) it.checked = true;
if (it.checked == null) it.checked = false;
}
}
}
else if (object.items[i].type == 'menu-radio') {
var item = object.items[i];
if (Array.isArray(item.items)) {
for (var j = 0; j < item.items.length; j++) {
var it = item.items[j];
if (it.checked && item.selected == null) item.selected = it.id; else it.checked = false;
if (!it.checked && item.selected == it.id) it.checked = true;
if (it.checked == null) it.checked = false;
}
}
}
}
if ($(this).length !== 0) {
object.render($(this)[0]);
}
// register new object
w2ui[object.name] = object;
return object;
} else {
var obj = w2ui[$(this).attr('name')];
if (!obj) return null;
if (arguments.length > 0) {
if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1));
return this;
} else {
return obj;
}
}
};
// ====================================================
// -- Implementation of core functionality
w2toolbar.prototype = {
onClick : null,
onRender : null,
onRefresh : null,
onResize : null,
onDestroy : null,
item: {
id : null, // command to be sent to all event handlers
type : 'button', // button, check, radio, drop, menu, menu-radio, menu-check, break, html, spacer
text : null,
html : '',
tooltip : null, // w2toolbar.tooltip should be
count : null,
hidden : false,
disabled : false,
checked : false, // used for radio buttons
img : null,
icon : null,
route : null, // if not null, it is route to go
arrow : true, // arrow down for drop/menu types
style : null, // extre css style for caption
color : null, // color value - used in color pickers
transparent : null, // transparent t/f - used in color pickers
group : null, // used for radio buttons
items : null, // for type menu* it is an array of items in the menu
selected : null, // used for menu-check, menu-radio
overlay : {},
onClick : null,
onRefresh : null
},
add: function (items) {
this.insert(null, items);
},
insert: function (id, items) {
if (!$.isArray(items)) items = [items];
for (var o = 0; o < items.length; o++) {
// checks
if (items[o].type == null) {
console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.');
return;
}
if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'menu-radio', 'menu-check', 'color', 'text-color', 'break', 'html', 'spacer']) == -1) {
console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+
'in w2toolbar.add() method.');
return;
}
if (items[o].id == null && items[o].type != 'break' && items[o].type != 'spacer') {
console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.');
return;
}
if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return;
// add item
var it = $.extend({}, w2toolbar.prototype.item, items[o]);
if (id == null) {
this.items.push(it);
} else {
var middle = this.get(id, true);
this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle));
}
this.refresh(it.id);
this.resize();
}
},
remove: function () {
var removed = 0;
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it || String(arguments[a]).indexOf(':') != -1) continue;
removed++;
// remove from screen
$(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove();
// remove from array
var ind = this.get(it.id, true);
if (ind != null) this.items.splice(ind, 1);
}
this.resize();
return removed;
},
set: function (id, newOptions) {
var item = this.get(id);
if (item == null) return false;
$.extend(item, newOptions);
this.refresh(String(id).split(':')[0]);
return true;
},
get: function (id, returnIndex) {
if (arguments.length === 0) {
var all = [];
for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id != null) all.push(this.items[i1].id);
return all;
}
var tmp = String(id).split(':');
for (var i2 = 0; i2 < this.items.length; i2++) {
var it = this.items[i2];
// find a menu item
if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1 && tmp.length == 2 && it.id == tmp[0]) {
for (var i = 0; i < it.items.length; i++) {
var item = it.items[i];
if (item.id == tmp[1] || (item.id == null && item.text == tmp[1])) {
if (returnIndex == true) return i; else return item;
}
}
} else if (it.id == tmp[0]) {
if (returnIndex == true) return i2; else return it;
}
}
return null;
},
show: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it) continue;
items++;
it.hidden = false;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) obj.refresh(tmp[t]); obj.resize(); }, 15); // needs timeout
return items;
},
hide: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it) continue;
items++;
it.hidden = true;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) { obj.refresh(tmp[t]); obj.tooltipHide(tmp[t]); } obj.resize(); }, 15); // needs timeout
return items;
},
enable: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it) continue;
items++;
it.disabled = false;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) obj.refresh(tmp[t]); }, 15); // needs timeout
return items;
},
disable: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it) continue;
items++;
it.disabled = true;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) { obj.refresh(tmp[t]); obj.tooltipHide(tmp[t]); } }, 15); // needs timeout
return items;
},
check: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it || String(arguments[a]).indexOf(':') != -1) continue;
items++;
it.checked = true;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) obj.refresh(tmp[t]); }, 15); // needs timeout
return items;
},
uncheck: function () {
var obj = this;
var items = 0;
var tmp = [];
for (var a = 0; a < arguments.length; a++) {
var it = this.get(arguments[a]);
if (!it || String(arguments[a]).indexOf(':') != -1) continue;
// remove overlay
if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1 && it.checked) {
// hide overlay
setTimeout(function () {
var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id));
el.w2overlay({ name: obj.name });
}, 1);
}
items++;
it.checked = false;
tmp.push(String(arguments[a]).split(':')[0]);
}
setTimeout(function () { for (var t=0; t<tmp.length; t++) obj.refresh(tmp[t]); }, 15); // needs timeout
return items;
},
click: function (id, event) {
var obj = this;
// click on menu items
var tmp = String(id).split(':');
var it = this.get(tmp[0]);
if (tmp.length > 1) {
var subItem = this.get(id);
if (subItem && !subItem.disabled) {
obj.menuClick({ name: obj.name, item: it, subItem: subItem, originalEvent: event });
}
return;
}
if (it && !it.disabled) {
// event before
var edata = this.trigger({ phase: 'before', type: 'click', target: (id != null ? id : this.name),
item: it, object: it, originalEvent: event });
if (tmp[0] === 'zoomin' || tmp[0] === 'zoomout') {
return;
}
if (edata.isCancelled === true) return;
var btn = '#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button';
$(btn).removeClass('down'); // need to requery at the moment -- as well as elsewhere in this function
if (it.type == 'radio') {
for (var i = 0; i < this.items.length; i++) {
var itt = this.items[i];
if (itt == null || itt.id == it.id || itt.type !== 'radio') continue;
if (itt.group == it.group && itt.checked) {
itt.checked = false;
this.refresh(itt.id);
}
}
it.checked = true;
$(btn).addClass('checked');
}
if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) {
obj.tooltipHide(id);
if (it.checked) {
// if it was already checked, second click will hide it
setTimeout(function () {
// hide overlay
var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id));
el.w2overlay({ name: obj.name });
// uncheck
it.checked = false;
obj.refresh(it.id);
}, 1);
} else {
// show overlay
setTimeout(function () {
var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id));
if (!$.isPlainObject(it.overlay)) it.overlay = {};
var left = (el.width() - 50) / 2;
if (left > 19) left = 19;
if (it.type == 'drop') {
el.w2overlay(it.html, $.extend({ name: obj.name, left: left, top: 3 }, it.overlay, {
onHide: function (event) {
hideDrop();
}
}));
}
if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1) {
var menuType = 'normal';
if (it.type == 'menu-radio') {
menuType = 'radio';
it.items.forEach(function (item) {
if (it.selected == item.id) item.checked = true; else item.checked = false;
});
}
if (it.type == 'menu-check') {
menuType = 'check';
it.items.forEach(function (item) {
if ($.isArray(it.selected) && it.selected.indexOf(item.id) != -1) item.checked = true; else item.checked = false;
});
}
el.w2menu($.extend({ name: obj.name, items: it.items, left: left, top: 3 }, it.overlay, {
type: menuType,
select: function (event) {
obj.menuClick({ name: obj.name, item: it, subItem: event.item, originalEvent: event.originalEvent, keepOpen: event.keepOpen });
},
onHide: function (event) {
hideDrop();
}
}));
}
if (['color', 'text-color'].indexOf(it.type) != -1) {
if (it.transparent == null) it.transparent = true;
$(el).w2color({ color: it.color, transparent: it.transparent }, function (color, themeData) {
if (color != null) {
obj.colorClick({ name: obj.name, item: it, color: color, themeData: themeData, originalEvent: event.originalEvent });
}
hideDrop();
});
}
function hideDrop(event) {
it.checked = false;
$(btn).removeClass('checked');
}
}, 1);
}
}
if (['check', 'menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) {
it.checked = !it.checked;
if (it.checked) {
$(btn).addClass('checked');
} else {
$(btn).removeClass('checked');
}
}
// route processing
if (it.route) {
var route = String('/'+ it.route).replace(/\/{2,}/g, '/');
var info = w2utils.parseRoute(route);
if (info.keys.length > 0) {
for (var k = 0; k < info.keys.length; k++) {
route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]);
}
}
setTimeout(function () { window.location.hash = route; }, 1);
}
if (event && ['button', 'check', 'radio'].indexOf(it.type) != -1) {
// need to refresh toolbar as it might be dynamic
this.tooltipShow(id, event, true);
}
// event after
this.trigger($.extend(edata, { phase: 'after' }));
}
},
scroll: function (direction) {
var box = $(this.box);
var obj = this;
var scrollBox = box.find('.w2ui-scroll-wrapper');
var scrollLeft = scrollBox.scrollLeft();
var width1, width2, scroll;
switch (direction) {
case 'left':
width1 = scrollBox.outerWidth();
width2 = scrollBox.find(':first').outerWidth();
scroll = scrollLeft - width1 + 50; // 35 is width of both button
if (scroll <= 0) scroll = 0;
scrollBox.animate({ scrollLeft: scroll }, 300);
break;
case 'right':
width1 = scrollBox.outerWidth();
width2 = scrollBox.find(':first').outerWidth();
scroll = scrollLeft + width1 - 50; // 35 is width of both button
if (scroll >= width2 - width1) scroll = width2 - width1;
scrollBox.animate({ scrollLeft: scroll }, 300);
break;
}
setTimeout(function () { obj.resize(); }, 350);
},
render: function (box) {
var time = (new Date()).getTime();
// event before
var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box });
if (edata.isCancelled === true) return;
if (box != null) {
if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) {
$(this.box)
.removeAttr('name')
.removeClass('w2ui-reset w2ui-toolbar')
.html('');
}
this.box = box;
}
if (!this.box) return;
// render all buttons
var html = '<div class="w2ui-scroll-wrapper" onmousedown="var el=w2ui[\''+ this.name +'\']; if (el) el.resize();">'+
'<table cellspacing="0" cellpadding="0" width="100%"><tbody>'+
'<tr>';
for (var i = 0; i < this.items.length; i++) {
var it = this.items[i];
if (it == null) continue;
if (it.id == null) it.id = "item_" + i;
if (it.type == 'spacer') {
html += '<td width="100%" id="tb_'+ this.name +'_item_'+ it.id +'" align="right"></td>';
} else {
html += '<td id="tb_'+ this.name + '_item_'+ it.id +'" style="'+ (it.hidden ? 'display: none' : '') +'" '+
' class="'+ (it.disabled ? 'disabled' : '') +'" valign="middle" title="'+ (it.hint ? it.hint : "") + '">'
'</td>';
}
}
html += '<td width="100%" id="tb_'+ this.name +'_right" align="right">'+ this.right +'</td>';
html += '</tr>'+
'</tbody></table></div>'+
'<div class="w2ui-scroll-left" onmousedown="event.preventDefault()" onclick="var el=w2ui[\''+ this.name +'\']; if (el) el.scroll(\'left\');"></div>'+
'<div class="w2ui-scroll-right" onmousedown="event.preventDefault()" onclick="var el=w2ui[\''+ this.name +'\']; if (el) el.scroll(\'right\');"></div>';
$(this.box)
.attr('name', this.name)
.addClass('w2ui-reset w2ui-toolbar')
.html(html);
if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style;
// refresh all
this.refresh();
this.resize();
// event after
this.trigger($.extend(edata, { phase: 'after' }));
return (new Date()).getTime() - time;
},
refresh: function (id) {
var time = (new Date()).getTime();
// event before
var edata = this.trigger({ phase: 'before', type: 'refresh', target: (id != null ? id : this.name), item: this.get(id) });
if (edata.isCancelled === true) return;
// refresh all
if (id == null) {
for (var i = 0; i < this.items.length; i++) {
var it1 = this.items[i];
if (it1.id == null) it1.id = "item_" + i;
this.refresh(it1.id);
}
return;
}
// create or refresh only one item
var it = this.get(id);
if (it == null) return false;
if (typeof it.onRefresh == 'function') {
var edata2 = this.trigger({ phase: 'before', type: 'refresh', target: id, item: it, object: it });
if (edata2.isCancelled === true) return;
}
var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id));
var html = this.getItemHTML(it);
if (el.length === 0) {
// does not exist - create it
if (it.type == 'spacer') {
html = '<td width="100%" id="tb_'+ this.name +'_item_'+ it.id +'" align="right"></td>';
} else {
html = '<td id="tb_'+ this.name + '_item_'+ it.id +'" style="'+ (it.hidden ? 'display: none' : '') +'" '+
' class="'+ (it.disabled ? 'disabled' : '') +'" valign="middle" title="'+ (it.hint ? it.hint : "") +'">' + html +
'</td>';
}
if (this.get(id, true) == this.items.length-1) {
$(this.box).find('#tb_'+ this.name +'_right').before(html);
} else {
$(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html);
}
} else {
if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1 && it.checked == false) {
if ($('#w2ui-overlay-'+ this.name).length > 0) $('#w2ui-overlay-'+ this.name)[0].hide();
}
// refresh
el.html(html);
if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); }
if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); }
}
// event after
if (typeof it.onRefresh == 'function') {
this.trigger($.extend(edata2, { phase: 'after' }));
}
this.trigger($.extend(edata, { phase: 'after' }));
return (new Date()).getTime() - time;
},
resize: function () {
var time = (new Date()).getTime();
// event before
var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name });
if (edata.isCancelled === true) return;
// show hide overflow buttons
var box = $(this.box);
box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide();
var scrollBox = box.find('.w2ui-scroll-wrapper');
if (scrollBox.find(':first').outerWidth() > scrollBox.outerWidth()) {
// we have overflowed content
if (scrollBox.scrollLeft() > 0) {
box.find('.w2ui-scroll-left').show();
}
// Allow for rounding errors (on mobile, the max scrollLeft we get is 0.5 less than the real max).
if (scrollBox.scrollLeft() < scrollBox.find(':first').outerWidth() - scrollBox.outerWidth() - 1) {
box.find('.w2ui-scroll-right').show();
}
}
if (window.mode.isMobile()) {
$('#toolbar-wrapper.mobile .w2ui-scroll-right, #toolbar-wrapper.mobile .w2ui-scroll-left').hide();
}
// event after
this.trigger($.extend(edata, { phase: 'after' }));
return (new Date()).getTime() - time;
},
destroy: function () {
// event before
var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name });
if (edata.isCancelled === true) return;
// clean up
if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) {
$(this.box)
.removeAttr('name')
.removeClass('w2ui-reset w2ui-toolbar')
.html('');
}
$(this.box).html('');
delete w2ui[this.name];
// event after
this.trigger($.extend(edata, { phase: 'after' }));
},
// ========================================
// --- Internal Functions
getItemHTML: function (item) {
var html = '';
if (item.caption != null && item.text == null) item.text = item.caption; // for backward compatibility
if (item.text == null) item.text = '';
if (item.tooltip == null) item.tooltip = '';
var img = '<td>&#160;</td>';
var text = item.text;
if (typeof text == 'function') text = text.call(this, item);
if (item.img) {
// color indicator container for classic mode
var colorContainer = '<div class="selected-color-classic"></div>';
/**
* @css class="textcolor" used in:
* - Writer, Calc, Impress, Draw
* - as "Font Color"
*
* @css class="backcolor" used in:
* - Writer, Impress, Draw
* - as "Character Highlighting Color"
*
* @css class="backgroundcolor" used in:
* - Calc
* - as "Background Color"
* - (on mobile Calc uses "backcolor")
*
* It would be appropriate to place color indicator to below
* of those classes' container.
*
* We have to filter where to add the color indicator,
* otherwise it will be added to below of each toolbar
* elements.
*/
img = (item.img == 'textcolor' || item.img == 'backcolor' || item.img == 'backgroundcolor') ?
'<td><div class="w2ui-tb-image w2ui-icon '+ item.img +'"></div>' + colorContainer + '</td>' :
'<td><div class="w2ui-tb-image w2ui-icon '+ item.img +'"></div></td>';
}
if (item.icon) img = '<td><div class="w2ui-tb-image"><span class="'+ item.icon +'"></span></div></td>';
if (html === '') switch (item.type) {
case 'color':
case 'text-color':
if (typeof item.color == 'string' && item.color.substr(0,1) == '#') item.color = item.color.substr(1);
/*
if (item.type == 'color') {
text = '<div style="height: 12px; width: 12px; margin-top: 1px; border: 1px solid #8A8A8A; border-radius: 1px; box-shadow: 0px 0px 1px #fff; '+
' background-color: #'+ (item.color != null ? item.color : 'fff') +'; float: left;"></div>'+
(item.text ? '<div style="margin-left: 17px;">' + w2utils.lang(item.text) + '</div>' : '');
}
*/
/*if (item.type == 'text-color') {
text = '<div style="color: #'+ (item.color != null ? item.color : '444') +';">'+
(item.text ? w2utils.lang(item.text) : '<b>Aa</b>') +
'</div>';
}*/
case 'menu':
case 'menu-check':
case 'menu-radio':
case 'button':
case 'check':
case 'radio':
case 'drop':
html += '<table cellpadding="0" cellspacing="0" '+
' class="w2ui-button '+ (item.checked ? 'checked' : '') +'" '+
' onclick = "var el=w2ui[\''+ this.name + '\']; if (el) el.click(\''+ item.id +'\', event);" '+
' onmouseover = "' + (!item.disabled ? "jQuery(this).addClass('over'); w2ui['"+ this.name +"'].tooltipShow('"+ item.id +"', event);" : "") + '"'+
' onmouseout = "' + (!item.disabled ? "jQuery(this).removeClass('over').removeClass('down'); w2ui['"+ this.name +"'].tooltipHide('"+ item.id +"', event);" : "") + '"'+
' onmousedown = "' + (!item.disabled ? "jQuery(this).addClass('down');" : "") + '"'+
' onmouseup = "' + (!item.disabled ? "jQuery(this).removeClass('down');" : "") + '"'+
'><tbody>'+
'<tr><td>'+
' <table cellpadding="1" cellspacing="0"><tbody>'+
' <tr>' +
img +
(text !== ''
? '<td class="w2ui-tb-caption" nowrap="nowrap" style="'+ (item.style ? item.style : '') +'">'+ w2utils.lang(text) +'</td>'
: ''
) +
(item.count != null
? '<td class="w2ui-tb-count" nowrap="nowrap"><span>'+ item.count +'</span></td>'
: ''
) +
(((['menu', 'menu-radio', 'menu-check', 'drop'].indexOf(item.type) != -1) && item.arrow !== false) ?
'<td class="w2ui-tb-down" nowrap="nowrap"><div></div></td>' : '') +
' </tr></tbody></table>'+
'</td></tr></tbody></table>';
break;
case 'break':
html += '<table cellpadding="0" cellspacing="0"><tbody><tr>'+
' <td><div class="w2ui-break">&#160;</div></td>'+
'</tr></tbody></table>';
break;
case 'html':
html += '<table cellpadding="0" cellspacing="0"><tbody><tr>'+
' <td nowrap="nowrap">' + (typeof item.html == 'function' ? item.html.call(this, item) : item.html) + '</td>'+
'</tr></tbody></table>';
break;
}
return '<div>' + html + '</div>';
},
tooltipShow: function (id, event, forceRefresh) {
if (window.mode.isMobile() || window.mode.isTablet()) { return; }
if (window.ThisIsTheiOSApp) return;
if (this.tooltip == null) return;
var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id));
var item = this.get(id);
var pos = this.tooltip;
var txt = item.tooltip;
if (typeof txt == 'function') txt = txt.call(this, item);
$el.prop('_mouse_over', true);
setTimeout(function () {
if ($el.prop('_mouse_over') === true && $el.prop('_mouse_tooltip') !== true) {
$el.prop('_mouse_tooltip', true);
// show tooltip
if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(item.type) != -1 && item.checked == true) return; // not for opened drop downs
$el.w2tag(w2utils.lang(txt), { position: pos });
}
if (forceRefresh == true) {
$el.w2tag(w2utils.lang(txt), { position: pos });
}
}, 1);
},
tooltipHide: function (id, event) {
if (window.ThisIsTheiOSApp) return;
if (this.tooltip == null) return;
var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id));
$el.removeProp('_mouse_over');
setTimeout(function () {
if ($el.prop('_mouse_over') !== true && $el.prop('_mouse_tooltip') === true) {
$el.removeProp('_mouse_tooltip');
// hide tooltip
$el.w2tag();
}
}, 1);
},
menuClick: function (event) {
var obj = this;
if (event.item && !event.item.disabled) {
// event before
var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item,
subItem: event.subItem, originalEvent: event.originalEvent });
if (edata.isCancelled === true) return;
// route processing
var it = event.subItem;
var item = this.get(event.item.id);
if (item.type == 'menu-radio') {
item.selected = it.id;
event.item.items.forEach(function (item) { item.checked = false; });
it.checked = true;
}
if (item.type == 'menu-check') {
if (!$.isArray(item.selected)) item.selected = [];
var ind = item.selected.indexOf(it.id);
if (ind == -1) {
item.selected.push(it.id);
it.checked = true;
} else {
item.selected.splice(ind, 1);
it.checked = false;
}
}
if (typeof it.route == 'string') {
var route = it.route !== '' ? String('/'+ it.route).replace(/\/{2,}/g, '/') : '';
var info = w2utils.parseRoute(route);
if (info.keys.length > 0) {
for (var k = 0; k < info.keys.length; k++) {
if (obj.routeData[info.keys[k].name] == null) continue;
route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]);
}
}
setTimeout(function () { window.location.hash = route; }, 1);
}
this.refresh(event.item.id);
// event after
this.trigger($.extend(edata, { phase: 'after' }));
}
},
colorClick: function (event) {
var obj = this;
if (event.item && !event.item.disabled) {
// event before
var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id, item: event.item,
color: event.color, themeData: event.themeData, originalEvent: event.originalEvent });
if (edata.isCancelled === true) return;
// default behavior
event.item.color = event.color;
obj.refresh(event.item.id);
// event after
this.trigger($.extend(edata, { phase: 'after' }));
}
},
};
$.extend(w2toolbar.prototype, w2utils.event);
w2obj.toolbar = w2toolbar;
})(jQuery);