diff --git a/.gitignore b/.gitignore index 9b51e99..b9746be 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ site www builder jquerytools.github.com +node_modules +bower_modules # patch *.rej diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..ef2e90f --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,73 @@ +module.exports = function( grunt ) { + "use strict"; + + var srcHintOptions = grunt.file.readJSON( "src/.jshintrc" ); + + grunt.initConfig({ + jshint: { + all: { + src: [ + "src/**/*.js", "Gruntfile.js" + ], + options: { + jshintrc: true + } + }, + dist: { + src: "dist/jquery.tools.js", + options: srcHintOptions + } + }, + build: { + all: { + dest: "dist/jquery.tools.js", + src: [ + "src/**/*.js" + ], + } + }, + clean: { + all: { + src: "dist/*.js" + } + }, + uglify: { + all: { + files: { + "dist/jquery.tools.min.js": [ "dist/jquery.tools.js" ] + }, + options: { + preserveComments: false, + sourceMap: "dist/jquery.tools.min.map", + sourceMappingURL: "jquery.tools.min.map", + report: "min", + beautify: { + ascii_only: true + }, + compress: { + hoist_funs: false, + loops: false, + unused: false + } + } + } + } + }); + + grunt.registerMultiTask("clean", "Removed Concatenated source files", function() { + this.filesSrc.forEach(function(filename){ + grunt.file.delete(filename); + }); + }); + + grunt.registerMultiTask("build", "Concatenate source files", function() { + var out = []; + this.filesSrc.forEach(function(filename){ + out.push(grunt.file.read(filename)); + }); + grunt.file.write(this.data.dest, out.join('\n')); + }); + + require( "load-grunt-tasks" )( grunt ); + grunt.registerTask( "default", [ "clean", "build", "jshint", "uglify" ] ); +}; diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..fa2c3ba --- /dev/null +++ b/bower.json @@ -0,0 +1,32 @@ +{ + "name": "jquerytools", + "version": "1.2.8", + "homepage": "http://jquerytools.org", + "description": "The missing UI library for the Web", + "main": "dist/jquery.tools.js", + "license": "None", + "keywords": [ + "jquery", + "javascript", + "library" + ], + "ignore": [ + "**/.*", + "build", + "node_modules", + "bower_components", + "test", + "tests", + "*.md", + "AUTHORS.txt", + "Gruntfile.js", + "package.json", + "bower.json" + ], + "dependencies": { + "jquery": "jQuery#~1.11" + }, + "resolutions": { + "jquery": "~1.11" + } +} diff --git a/dist/jquery.tools.js b/dist/jquery.tools.js new file mode 100644 index 0000000..3157420 --- /dev/null +++ b/dist/jquery.tools.js @@ -0,0 +1,4793 @@ +/** + * @license + * jQuery Tools @VERSION Dateinput - for humans + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/form/dateinput/ + * + * Since: Mar 2010 + * Date: @DATE + */ +(function($, undefined) { + + /* TODO: + preserve today highlighted + */ + + $.tools = $.tools || {version: '@VERSION'}; + + var instances = [], + formatters = {}, + tool, + + // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39 + KEYS = [75, 76, 38, 39, 74, 72, 40, 37], + LABELS = {}; + + tool = $.tools.dateinput = { + + conf: { + format: 'mm/dd/yy', + formatter: 'default', + selectors: false, + yearRange: [-5, 5], + lang: 'en', + offset: [0, 0], + speed: 0, + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + min: undefined, + max: undefined, + trigger: 0, + toggle: 0, + editable: 0, + + css: { + + prefix: 'cal', + input: 'date', + + // ids + root: 0, + head: 0, + title: 0, + prev: 0, + next: 0, + month: 0, + year: 0, + days: 0, + + body: 0, + weeks: 0, + today: 0, + current: 0, + + // classnames + week: 0, + off: 0, + sunday: 0, + focus: 0, + disabled: 0, + trigger: 0 + } + }, + + addFormatter: function(name, fn) { + formatters[name] = fn; + }, + + localize: function(language, labels) { + $.each(labels, function(key, val) { + labels[key] = val.split(","); + }); + LABELS[language] = labels; + } + + }; + + tool.localize("en", { + months: 'January,February,March,April,May,June,July,August,September,October,November,December', + shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec', + days: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday', + shortDays: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat' + }); + + +//{{{ private functions + + + // @return amount of days in certain month + function dayAm(year, month) { + return new Date(year, month + 1, 0).getDate(); + } + + function zeropad(val, len) { + val = '' + val; + len = len || 2; + while (val.length < len) { val = "0" + val; } + return val; + } + + // thanks: http://stevenlevithan.com/assets/misc/date.format.js + var tmpTag = $(""); + + function format(formatter, date, text, lang) { + var d = date.getDate(), + D = date.getDay(), + m = date.getMonth(), + y = date.getFullYear(), + + flags = { + d: d, + dd: zeropad(d), + ddd: LABELS[lang].shortDays[D], + dddd: LABELS[lang].days[D], + m: m + 1, + mm: zeropad(m + 1), + mmm: LABELS[lang].shortMonths[m], + mmmm: LABELS[lang].months[m], + yy: String(y).slice(2), + yyyy: y + }; + + var ret = formatters[formatter](text, date, flags, lang); + + // a small trick to handle special characters + return tmpTag.html(ret).html(); + + } + + tool.addFormatter('default', function(text, date, flags, lang) { + return text.replace(/d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, function ($0) { + return $0 in flags ? flags[$0] : $0; + }); + }); + + tool.addFormatter('prefixed', function(text, date, flags, lang) { + return text.replace(/%(d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*')/g, function ($0, $1) { + return $1 in flags ? flags[$1] : $0; + }); + }); + + function integer(val) { + return parseInt(val, 10); + } + + function isSameDay(d1, d2) { + return d1.getFullYear() === d2.getFullYear() && + d1.getMonth() == d2.getMonth() && + d1.getDate() == d2.getDate(); + } + + function parseDate(val) { + + if (val === undefined) { return; } + if (val.constructor == Date) { return val; } + + if (typeof val == 'string') { + + // rfc3339? + var els = val.split("-"); + if (els.length == 3) { + return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2])); + } + + // invalid offset + if ( !(/^-?\d+$/).test(val) ) { return; } + + // convert to integer + val = integer(val); + } + + var date = new Date(); + date.setDate(date.getDate() + val); + return date; + } + +//}}} + + + function Dateinput(input, conf) { + + // variables + var self = this, + now = new Date(), + yearNow = now.getFullYear(), + css = conf.css, + labels = LABELS[conf.lang], + root = $("#" + css.root), + title = root.find("#" + css.title), + trigger, + pm, nm, + currYear, currMonth, currDay, + monthSelector, yearSelector, + value = input.attr("data-value") || conf.value || input.val(), + min = input.attr("min") || conf.min, + max = input.attr("max") || conf.max, + opened, + original; + + // zero min is not undefined + if (min === 0) { min = "0"; } + + // use sane values for value, min & max + value = parseDate(value) || now; + + min = parseDate(min || new Date(yearNow + conf.yearRange[0], 1, 1)); + max = parseDate(max || new Date( yearNow + conf.yearRange[1]+ 1, 1, -1)); + + + // check that language exists + if (!labels) { throw "Dateinput: invalid language: " + conf.lang; } + + // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser + if (input.attr("type") == 'date') { + original = input.clone(), + def = original.wrap("
").parent().html(), + clone = $(def.replace(/type/i, "type=text data-orig-type")); + + if (conf.value) clone.val(conf.value); // jquery 1.6.2 val(undefined) will clear val() + + input.replaceWith(clone); + input = clone; + } + + input.addClass(css.input); + + var fire = input.add(self); + + // construct layout + if (!root.length) { + + // root + root = $('') + .hide().css({position: 'absolute'}).attr("id", css.root); + + // elements + root.children() + .eq(0).attr("id", css.head).end() + .eq(1).attr("id", css.body).children() + .eq(0).attr("id", css.days).end() + .eq(1).attr("id", css.weeks).end().end().end() + .find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next); + + // title + title = root.find("#" + css.head).find("div").attr("id", css.title); + + // year & month selectors + if (conf.selectors) { + monthSelector = $("").attr("id", css.month); + yearSelector = $("").attr("id", css.year); + title.html(monthSelector.add(yearSelector)); + } + + // day titles + var days = root.find("#" + css.days); + + // days of the week + for (var d = 0; d < 7; d++) { + days.append($("").text(labels.shortDays[(d + conf.firstDay) % 7])); + } + + $("body").append(root); + } + + + // trigger icon + if (conf.trigger) { + trigger = $("").attr("href", "#").addClass(css.trigger).click(function(e) { + conf.toggle ? self.toggle() : self.show(); + return e.preventDefault(); + }).insertAfter(input); + } + + + // layout elements + var weeks = root.find("#" + css.weeks); + yearSelector = root.find("#" + css.year); + monthSelector = root.find("#" + css.month); + + +//{{{ pick + + function select(date, conf, e) { + // If it is readonly, then we'll just close the calendar + if (input.attr('readonly')) { + self.hide(e); + return; + } + + // current value + value = date; + currYear = date.getFullYear(); + currMonth = date.getMonth(); + currDay = date.getDate(); + + e || (e = $.Event("api")); + + // focus the input after selection (doesn't work in IE) + if (e.type == "click" && !/msie/.test(navigator.userAgent.toLowerCase())) { + input.focus(); + } + + // beforeChange + e.type = "beforeChange"; + + fire.trigger(e, [date]); + if (e.isDefaultPrevented()) { return; } + + // formatting + input.val(format(conf.formatter, date, conf.format, conf.lang)); + + // change + e.type = "change"; + fire.trigger(e); + + // store value into input + input.data("date", date); + + self.hide(e); + } +//}}} + + +//{{{ onShow + + function onShow(ev) { + + ev.type = "onShow"; + fire.trigger(ev); + + $(document).on("keydown.d", function(e) { + + if (e.ctrlKey) { return true; } + var key = e.keyCode; + + // backspace or delete clears the value + if (key == 8 || key == 46) { + input.val(""); + return self.hide(e); + } + + // esc or tab key exits + if (key == 27 || key == 9) { return self.hide(e); } + + if ($(KEYS).index(key) >= 0) { + + if (!opened) { + self.show(e); + return e.preventDefault(); + } + + var days = $("#" + css.weeks + " a"), + el = $("." + css.focus), + index = days.index(el); + + el.removeClass(css.focus); + + if (key == 74 || key == 40) { index += 7; } + else if (key == 75 || key == 38) { index -= 7; } + else if (key == 76 || key == 39) { index += 1; } + else if (key == 72 || key == 37) { index -= 1; } + + + if (index > 41) { + self.addMonth(); + el = $("#" + css.weeks + " a:eq(" + (index-42) + ")"); + } else if (index < 0) { + self.addMonth(-1); + el = $("#" + css.weeks + " a:eq(" + (index+42) + ")"); + } else { + el = days.eq(index); + } + + el.addClass(css.focus); + return e.preventDefault(); + + } + + // pageUp / pageDown + if (key == 34) { return self.addMonth(); } + if (key == 33) { return self.addMonth(-1); } + + // home + if (key == 36) { return self.today(); } + + // enter + if (key == 13) { + if (!$(e.target).is("select")) { + $("." + css.focus).click(); + } + } + + return $([16, 17, 18, 9]).index(key) >= 0; + }); + + + // click outside dateinput + $(document).on("click.d", function(e) { + var el = e.target; + + if (!(el.id == css.root || $(el).parents("#" + css.root).length) && el != input[0] && (!trigger || el != trigger[0])) { + self.hide(e); + } + + }); + } +//}}} + + + $.extend(self, { + + + /** + * @public + * Show the calendar + */ + show: function(e) { + + if (input.attr("disabled") || opened) { return; } + + // onBeforeShow + e = e || $.Event(); + e.type = "onBeforeShow"; + fire.trigger(e); + if (e.isDefaultPrevented()) { return; } + + $.each(instances, function() { + this.hide(); + }); + + opened = true; + + // month selector + monthSelector.off("change").change(function() { + self.setValue(integer(yearSelector.val()), integer($(this).val())); + }); + + // year selector + yearSelector.off("change").change(function() { + self.setValue(integer($(this).val()), integer(monthSelector.val())); + }); + + // prev / next month + pm = root.find("#" + css.prev).off("click").click(function(e) { + if (!pm.hasClass(css.disabled)) { + self.addMonth(-1); + } + return false; + }); + + nm = root.find("#" + css.next).off("click").click(function(e) { + if (!nm.hasClass(css.disabled)) { + self.addMonth(); + } + return false; + }); + + // set date + self.setValue(value); + + // show calendar + var pos = input.offset(); + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + pos.top -= $(window).scrollTop(); + } + + root.css({ + top: pos.top + input.outerHeight(true) + conf.offset[0], + left: pos.left + conf.offset[1] + }); + + if (conf.speed) { + root.show(conf.speed, function() { + onShow(e); + }); + } else { + root.show(); + onShow(e); + } + + return self; + }, + + /** + * @public + * + * Set the value of the dateinput + */ + setValue: function(year, month, day) { + + var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day === undefined || isNaN(day) ? 1 : day)) : + year || value; + + if (date < min) { date = min; } + else if (date > max) { date = max; } + + // date given as ISO string + if (typeof year == 'string') { date = parseDate(year); } + + year = date.getFullYear(); + month = date.getMonth(); + day = date.getDate(); + + + // roll year & month + if (month == -1) { + month = 11; + year--; + } else if (month == 12) { + month = 0; + year++; + } + + if (!opened) { + select(date, conf); + return self; + } + + currMonth = month; + currYear = year; + currDay = day; + + // variables + var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(), + days = dayAm(year, month), + prevDays = dayAm(year, month - 1), + week; + + // selectors + if (conf.selectors) { + + // month selector + monthSelector.empty(); + $.each(labels.months, function(i, m) { + if (min < new Date(year, i + 1, 1) && max > new Date(year, i, 0)) { + monthSelector.append($("").html(m).attr("value", i)); + } + }); + + // year selector + yearSelector.empty(); + var yearNow = now.getFullYear(); + + for (var i = yearNow + conf.yearRange[0]; i < yearNow + conf.yearRange[1]; i++) { + if (min < new Date(i + 1, 0, 1) && max > new Date(i, 0, 0)) { + yearSelector.append($("").text(i)); + } + } + + monthSelector.val(month); + yearSelector.val(year); + + // title + } else { + title.html(labels.months[month] + " " + year); + } + + // populate weeks + weeks.empty(); + pm.add(nm).removeClass(css.disabled); + + // !begin === "sunday" + for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) { + + a = $(""); + + if (j % 7 === 0) { + week = $("").addClass(css.week); + weeks.append(week); + } + + if (j < begin) { + a.addClass(css.off); + num = prevDays - begin + j + 1; + date = new Date(year, month-1, num); + + } else if (j >= begin + days) { + a.addClass(css.off); + num = j - days - begin + 1; + date = new Date(year, month+1, num); + + } else { + num = j - begin + 1; + date = new Date(year, month, num); + + // current date + if (isSameDay(value, date)) { + a.attr("id", css.current).addClass(css.focus); + + // today + } else if (isSameDay(now, date)) { + a.attr("id", css.today); + } + } + + // disabled + if (min && date < min) { + a.add(pm).addClass(css.disabled); + } + + if (max && date > max) { + a.add(nm).addClass(css.disabled); + } + + a.attr("href", "#" + num).text(num).data("date", date); + + week.append(a); + } + + // date picking + weeks.find("a").click(function(e) { + var el = $(this); + if (!el.hasClass(css.disabled)) { + $("#" + css.current).removeAttr("id"); + el.attr("id", css.current); + select(el.data("date"), conf, e); + } + return false; + }); + + // sunday + if (css.sunday) { + weeks.find("." + css.week).each(function() { + var beg = conf.firstDay ? 7 - conf.firstDay : 0; + $(this).children().slice(beg, beg + 1).addClass(css.sunday); + }); + } + + return self; + }, + //}}} + + setMin: function(val, fit) { + min = parseDate(val); + if (fit && value < min) { self.setValue(min); } + return self; + }, + + setMax: function(val, fit) { + max = parseDate(val); + if (fit && value > max) { self.setValue(max); } + return self; + }, + + today: function() { + return self.setValue(now); + }, + + addDay: function(amount) { + return this.setValue(currYear, currMonth, currDay + (amount || 1)); + }, + + addMonth: function(amount) { + var targetMonth = currMonth + (amount || 1), + daysInTargetMonth = dayAm(currYear, targetMonth), + targetDay = currDay <= daysInTargetMonth ? currDay : daysInTargetMonth; + + return this.setValue(currYear, targetMonth, targetDay); + }, + + addYear: function(amount) { + return this.setValue(currYear + (amount || 1), currMonth, currDay); + }, + + destroy: function() { + input.add(document).off("click.d keydown.d"); + root.add(trigger).remove(); + input.removeData("dateinput").removeClass(css.input); + if (original) { input.replaceWith(original); } + }, + + hide: function(e) { + + if (opened) { + + // onHide + e = $.Event(); + e.type = "onHide"; + fire.trigger(e); + + // cancelled ? + if (e.isDefaultPrevented()) { return; } + + $(document).off("click.d keydown.d"); + + // do the hide + root.hide(); + opened = false; + } + + return self; + }, + + toggle: function(){ + return self.isOpen() ? self.hide() : self.show(); + }, + + getConf: function() { + return conf; + }, + + getInput: function() { + return input; + }, + + getCalendar: function() { + return root; + }, + + getValue: function(dateFormat) { + return dateFormat ? format(conf.formatter, value, dateFormat, conf.lang) : value; + }, + + isOpen: function() { + return opened; + } + + }); + + // callbacks + $.each(['onBeforeShow','onShow','change','onHide'], function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API methods + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + if (!conf.editable) { + + // show dateinput & assign keyboard shortcuts + input.on("focus.d click.d", self.show).keydown(function(e) { + + var key = e.keyCode; + + // open dateinput with navigation keyw + if (!opened && $(KEYS).index(key) >= 0) { + self.show(e); + return e.preventDefault(); + + // clear value on backspace or delete + } else if (key == 8 || key == 46) { + input.val(""); + } + + // allow tab + return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault(); + + }); + } + + // initial value + if (parseDate(input.val())) { + select(value, conf); + } + + } + + $.expr[':'].date = function(el) { + var type = el.getAttribute("type"); + return type && type == 'date' || !!$(el).data("dateinput"); + }; + + + $.fn.dateinput = function(conf) { + + // already instantiated + if (this.data("dateinput")) { return this; } + + // configuration + conf = $.extend(true, {}, tool.conf, conf); + + // CSS prefix + $.each(conf.css, function(key, val) { + if (!val && key != 'prefix') { + conf.css[key] = (conf.css.prefix || '') + (val || key); + } + }); + + var els; + + this.each(function() { + var el = new Dateinput($(this), conf); + instances.push(el); + var input = el.getInput().data("dateinput", el); + els = els ? els.add(input) : input; + }); + + return els ? els : this; + }; + + +}) (jQuery); + + + +/** + * @license + * jQuery Tools @VERSION / Overlay Apple effect. + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/overlay/apple.html + * + * Since: July 2009 + * Date: @DATE + */ +(function($) { + + // version number + var t = $.tools.overlay, + w = $(window); + + // extend global configuragion with effect specific defaults + $.extend(t.conf, { + start: { + top: null, + left: null + }, + + fadeInSpeed: 'fast', + zIndex: 9999 + }); + + // utility function + function getPosition(el) { + var p = el.offset(); + return { + top: p.top + el.height() / 2, + left: p.left + el.width() / 2 + }; + } + +//{{{ load + + var loadEffect = function(pos, onLoad) { + + var overlay = this.getOverlay(), + conf = this.getConf(), + trigger = this.getTrigger(), + self = this, + oWidth = overlay.outerWidth(true), + img = overlay.data("img"), + position = conf.fixed ? 'fixed' : 'absolute'; + + + // growing image is required. + if (!img) { + var bg = overlay.css("backgroundImage"); + + if (!bg) { + throw "background-image CSS property not set for overlay"; + } + + // url("bg.jpg") --> bg.jpg + bg = bg.slice(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, ""); + overlay.css("backgroundImage", "none"); + + img = $('Click here to download latest version
" : + "Download latest version from here
"); + + if (root.tagName == 'A') { + root.onclick = function() { + location.href = URL; + }; + } + } + + // onFail + if (opts.onFail) { + var ret = opts.onFail.call(this); + if (typeof ret == 'string') { root.innerHTML = ret; } + } + } + + // http://flowplayer.org/forum/8/18186#post-18593 + if (IE) { + window[opts.id] = document.getElementById(opts.id); + } + + // API methods for callback + extend(this, { + + getRoot: function() { + return root; + }, + + getOptions: function() { + return opts; + }, + + + getConf: function() { + return conf; + }, + + getApi: function() { + return root.firstChild; + } + + }); + } + + // setup jquery support + if (JQUERY) { + + // tools version number + jQuery.tools = jQuery.tools || {version: '@VERSION'}; + + jQuery.tools.flashembed = { + conf: GLOBAL_OPTS + }; + + jQuery.fn.flashembed = function(opts, conf) { + return this.each(function() { + jQuery(this).data("flashembed", flashembed(this, opts, conf)); + }); + }; + } + +})(); + + +/** + * @license + * jQuery Tools @VERSION History "Back button for AJAX apps" + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/toolbox/history.html + * + * Since: Mar 2010 + * Date: @DATE + */ +(function($) { + + var hash, iframe, links, inited; + + $.tools = $.tools || {version: '@VERSION'}; + + $.tools.history = { + + init: function(els) { + + if (inited) { return; } + + // IE + if ($.browser.msie && $.browser.version < '8') { + + // create iframe that is constantly checked for hash changes + if (!iframe) { + iframe = $("").attr("src", "javascript:false;").hide().get(0); + $("body").append(iframe); + + setInterval(function() { + var idoc = iframe.contentWindow.document, + h = idoc.location.hash; + + if (hash !== h) { + $(window).trigger("hash", h); + } + }, 100); + + setIframeLocation(location.hash || '#'); + } + + + // other browsers scans for location.hash changes directly without iframe hack + } else { + setInterval(function() { + var h = location.hash; + if (h !== hash) { + $(window).trigger("hash", h); + } + }, 100); + } + + links = !links ? els : links.add(els); + + els.click(function(e) { + var href = $(this).attr("href"); + if (iframe) { setIframeLocation(href); } + + // handle non-anchor links + if (href.slice(0, 1) != "#") { + location.href = "#" + href; + return e.preventDefault(); + } + + }); + + inited = true; + } + }; + + + function setIframeLocation(h) { + if (h) { + var doc = iframe.contentWindow.document; + doc.open().close(); + doc.location.hash = h; + } + } + + // global histroy change listener + $(window).on("hash", function(e, h) { + if (h) { + links.filter(function() { + var href = $(this).attr("href"); + return href == h || href == h.replace("#", ""); + }).trigger("history", [h]); + } else { + links.eq(0).trigger("history", [h]); + } + + hash = h; + + }); + + + // jQuery plugin implementation + $.fn.history = function(fn) { + + $.tools.history.init(this); + + // return jQuery + return this.on("history", fn); + }; + +})(jQuery); + + +/** + * @license + * jQuery Tools @VERSION Mousewheel + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/toolbox/mousewheel.html + * + * based on jquery.event.wheel.js ~ rev 1 ~ + * Copyright (c) 2008, Three Dub Media + * http://threedubmedia.com + * + * Since: Mar 2010 + * Date: @DATE + */ +(function($) { + + $.fn.mousewheel = function( fn ){ + return this[ fn ? "on" : "trigger" ]( "wheel", fn ); + }; + + // special event config + $.event.special.wheel = { + setup: function() { + $.event.add( this, wheelEvents, wheelHandler, {} ); + }, + teardown: function(){ + $.event.remove( this, wheelEvents, wheelHandler ); + } + }; + + // events to bind ( browser sniffed... ) + var wheelEvents = !$.browser.mozilla ? "mousewheel" : // IE, opera, safari + "DOMMouseScroll"+( $.browser.version<"1.9" ? " mousemove" : "" ); // firefox + + // shared event handler + function wheelHandler( event ) { + + switch ( event.type ) { + + // FF2 has incorrect event positions + case "mousemove": + return $.extend( event.data, { // store the correct properties + clientX: event.clientX, clientY: event.clientY, + pageX: event.pageX, pageY: event.pageY + }); + + // firefox + case "DOMMouseScroll": + $.extend( event, event.data ); // fix event properties in FF2 + event.delta = -event.detail / 3; // normalize delta + break; + + // IE, opera, safari + case "mousewheel": + event.delta = event.wheelDelta / 120; + break; + } + + event.type = "wheel"; // hijack the event + return $.event.handle.call( this, event, event.delta ); + } + +})(jQuery); + + +/** + * @license + * jQuery Tools @VERSION / Tooltip Dynamic Positioning + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/tooltip/dynamic.html + * + * Since: July 2009 + * Date: @DATE + */ +(function($) { + + // version number + var t = $.tools.tooltip; + + t.dynamic = { + conf: { + classNames: "top right bottom left" + } + }; + + /* + * See if element is on the viewport. Returns an boolean array specifying which + * edges are hidden. Edges are in following order: + * + * [top, right, bottom, left] + * + * For example following return value means that top and right edges are hidden + * + * [true, true, false, false] + * + */ + function getCropping(el) { + + var w = $(window); + var right = w.width() + w.scrollLeft(); + var bottom = w.height() + w.scrollTop(); + + return [ + el.offset().top <= w.scrollTop(), // top + right <= el.offset().left + el.width(), // right + bottom <= el.offset().top + el.height(), // bottom + w.scrollLeft() >= el.offset().left // left + ]; + } + + /* + Returns true if all edges of an element are on viewport. false if not + + @param crop the cropping array returned by getCropping function + */ + function isVisible(crop) { + var i = crop.length; + while (i--) { + if (crop[i]) { return false; } + } + return true; + } + + // dynamic plugin + $.fn.dynamic = function(conf) { + + if (typeof conf == 'number') { conf = {speed: conf}; } + + conf = $.extend({}, t.dynamic.conf, conf); + + var confOrigin = $.extend(true,{},conf), + cls = conf.classNames.split(/\s/), + orig, ret; + + this.each(function() { + + var api = $(this).tooltip().onBeforeShow(function(e, pos) { + + // get nessessary variables + var tip = this.getTip(), tipConf = this.getConf(); + + /* + We store the original configuration and use it to restore back to the original state. + */ + if (!orig) { + orig = [ + tipConf.position[0], + tipConf.position[1], + tipConf.offset[0], + tipConf.offset[1], + $.extend({}, tipConf) + ]; + } + + /* + display tip in it's default position and by setting visibility to hidden. + this way we can check whether it will be on the viewport + */ + $.extend(tipConf, orig[4]); + tipConf.position = [orig[0], orig[1]]; + tipConf.offset = [orig[2], orig[3]]; + + tip.css({ + visibility: 'hidden', + position: 'absolute', + top: pos.top, + left: pos.left + }).show(); + + var conf = $.extend(true,{},confOrigin), + + // now let's see for hidden edges + crop = getCropping(tip); + + // possibly alter the configuration + if (!isVisible(crop)) { + + // change the position and add class + if (crop[2]) { $.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); } + if (crop[3]) { $.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); } + if (crop[0]) { $.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); } + if (crop[1]) { $.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); } + + // vertical offset + if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; } + + // horizontal offset + if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; } + } + + tip.css({visibility: 'visible'}).hide(); + + }); + + // restore positioning as soon as possible + api.onBeforeShow(function() { + var c = this.getConf(), tip = this.getTip(); + setTimeout(function() { + c.position = [orig[0], orig[1]]; + c.offset = [orig[2], orig[3]]; + }, 0); + }); + + // remove custom class names and restore original effect + api.onHide(function() { + var tip = this.getTip(); + tip.removeClass(conf.classNames); + }); + + ret = api; + + }); + + return conf.api ? ret : this; + }; + +}) (jQuery); + +/** + * @license + * jQuery Tools @VERSION Tooltip - UI essentials + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/tooltip/ + * + * Since: November 2008 + * Date: @DATE + */ +(function($) { + // static constructs + $.tools = $.tools || {version: '@VERSION'}; + + $.tools.tooltip = { + + conf: { + + // default effect variables + effect: 'toggle', + fadeOutSpeed: "fast", + predelay: 0, + delay: 30, + opacity: 1, + tip: 0, + fadeIE: false, // enables fade effect in IE + + // 'top', 'bottom', 'right', 'left', 'center' + position: ['top', 'center'], + offset: [0, 0], + relative: false, + cancelDefault: true, + + // type to event mapping + events: { + def: "mouseenter,mouseleave", + input: "focus,blur", + widget: "focus mouseenter,blur mouseleave", + tooltip: "mouseenter,mouseleave" + }, + + // 1.2 + layout: '', + tipClass: 'tooltip' + }, + + addEffect: function(name, loadFn, hideFn) { + effects[name] = [loadFn, hideFn]; + } + }; + + + var effects = { + toggle: [ + function(done) { + var conf = this.getConf(), tip = this.getTip(), o = conf.opacity; + if (o < 1) { tip.css({opacity: o}); } + tip.show(); + done.call(); + }, + + function(done) { + this.getTip().hide(); + done.call(); + } + ], + + fade: [ + function(done) { + var conf = this.getConf(); + if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { + this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done); + } + else { + this.getTip().show(); + done(); + } + }, + function(done) { + var conf = this.getConf(); + if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { + this.getTip().fadeOut(conf.fadeOutSpeed, done); + } + else { + this.getTip().hide(); + done(); + } + } + ] + }; + + + /* calculate tip position relative to the trigger */ + function getPosition(trigger, tip, conf) { + + + // get origin top/left position + var top = conf.relative ? trigger.position().top : trigger.offset().top, + left = conf.relative ? trigger.position().left : trigger.offset().left, + pos = conf.position[0]; + + top -= tip.outerHeight() - conf.offset[0]; + left += trigger.outerWidth() + conf.offset[1]; + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + top -= $(window).scrollTop(); + } + + // adjust Y + var height = tip.outerHeight() + trigger.outerHeight(); + if (pos == 'center') { top += height / 2; } + if (pos == 'bottom') { top += height; } + + + // adjust X + pos = conf.position[1]; + var width = tip.outerWidth() + trigger.outerWidth(); + if (pos == 'center') { left -= width / 2; } + if (pos == 'left') { left -= width; } + + return {top: top, left: left}; + } + + + + function Tooltip(trigger, conf) { + + var self = this, + fire = trigger.add(self), + tip, + timer = 0, + pretimer = 0, + title = trigger.attr("title"), + tipAttr = trigger.attr("data-tooltip"), + effect = effects[conf.effect], + shown, + + // get show/hide configuration + isInput = trigger.is(":input"), + isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"), + type = trigger.attr("type"), + evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def']; + + + // check that configuration is sane + if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; } + + evt = evt.split(/,\s*/); + if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; } + + + // trigger --> show + trigger.on(evt[0], function(e) { + + clearTimeout(timer); + if (conf.predelay) { + pretimer = setTimeout(function() { self.show(e); }, conf.predelay); + + } else { + self.show(e); + } + + // trigger --> hide + }).on(evt[1], function(e) { + clearTimeout(pretimer); + if (conf.delay) { + timer = setTimeout(function() { self.hide(e); }, conf.delay); + + } else { + self.hide(e); + } + + }); + + + // remove default title + if (title && conf.cancelDefault) { + trigger.removeAttr("title"); + trigger.data("title", title); + } + + $.extend(self, { + + show: function(e) { + + // tip not initialized yet + if (!tip) { + + // data-tooltip + if (tipAttr) { + tip = $(tipAttr); + + // single tip element for all + } else if (conf.tip) { + tip = $(conf.tip).eq(0); + + // autogenerated tooltip + } else if (title) { + tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body) + .hide().append(title); + + // manual tooltip + } else { + tip = trigger.find('.' + conf.tipClass); + if (!tip.length) { tip = trigger.next(); } + if (!tip.length) { tip = trigger.parent().next(); } + } + + if (!tip.length) { throw "Cannot find tooltip for " + trigger; } + } + + if (self.isShown()) { return self; } + + // stop previous animation + tip.stop(true, true); + + // get position + var pos = getPosition(trigger, tip, conf); + + // restore title for single tooltip element + if (conf.tip) { + tip.html(trigger.data("title")); + } + + // onBeforeShow + e = $.Event(); + e.type = "onBeforeShow"; + fire.trigger(e, [pos]); + if (e.isDefaultPrevented()) { return self; } + + + // onBeforeShow may have altered the configuration + pos = getPosition(trigger, tip, conf); + + // set position + tip.css({position:'absolute', top: pos.top, left: pos.left}); + + shown = true; + + // invoke effect + effect[0].call(self, function() { + e.type = "onShow"; + shown = 'full'; + fire.trigger(e); + }); + + + // tooltip events + var event = conf.events.tooltip.split(/,\s*/); + + if (!tip.data("__set")) { + + tip.off(event[0]).on(event[0], function() { + clearTimeout(timer); + clearTimeout(pretimer); + }); + + if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) { + tip.off(event[1]).on(event[1], function(e) { + + // being moved to the trigger element + if (e.relatedTarget != trigger[0]) { + trigger.trigger(evt[1].split(" ")[0]); + } + }); + } + + // bind agein for if same tip element + if (!conf.tip) { + tip.data("__set", true); + } + } + + return self; + }, + + hide: function(e) { + + if (!tip || !self.isShown()) { return self; } + + // onBeforeHide + e = $.Event(); + e.type = "onBeforeHide"; + fire.trigger(e); + if (e.isDefaultPrevented()) { return; } + + shown = false; + + effects[conf.effect][1].call(self, function() { + e.type = "onHide"; + fire.trigger(e); + }); + + return self; + }, + + isShown: function(fully) { + return fully ? shown == 'full' : shown; + }, + + getConf: function() { + return conf; + }, + + getTip: function() { + return tip; + }, + + getTrigger: function() { + return trigger; + } + + }); + + // callbacks + $.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + } + + + // jQuery plugin implementation + $.fn.tooltip = function(conf) { + var api; + conf = $.extend(true, {}, $.tools.tooltip.conf, conf); + + // position can also be given as string + if (typeof conf.position == 'string') { + conf.position = conf.position.split(/,?\s/); + } + + // install tooltip for each entry in jQuery object + // that is not an existing instance + this.each(function() { + if ( $(this).data("tooltip")===null){ + api = new Tooltip($(this), conf); + $(this).data("tooltip", api); + } + }); + + return conf.api ? api: this; + }; + +}) (jQuery); + + + + +/** + * @license + * jQuery Tools @VERSION / Tooltip Slide Effect + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/tooltip/slide.html + * + * Since: September 2009 + * Date: @DATE + */ +(function($) { + + // version number + var t = $.tools.tooltip; + + // extend global configuragion with effect specific defaults + $.extend(t.conf, { + direction: 'up', // down, left, right + bounce: false, + slideOffset: 10, + slideInSpeed: 200, + slideOutSpeed: 200, + slideFade: !/msie/.test(navigator.userAgent.toLowerCase()) + }); + + // directions for slide effect + var dirs = { + up: ['-', 'top'], + down: ['+', 'top'], + left: ['-', 'left'], + right: ['+', 'left'] + }; + + /* default effect: "slide" */ + t.addEffect("slide", + + // show effect + function(done) { + + // variables + var conf = this.getConf(), + tip = this.getTip(), + params = conf.slideFade ? {opacity: conf.opacity} : {}, + dir = dirs[conf.direction] || dirs.up; + + // direction + params[dir[1]] = dir[0] +'='+ conf.slideOffset; + + // perform animation + if (conf.slideFade) { tip.css({opacity:0}); } + tip.show().animate(params, conf.slideInSpeed, done); + }, + + // hide effect + function(done) { + + // variables + var conf = this.getConf(), + offset = conf.slideOffset, + params = conf.slideFade ? {opacity: 0} : {}, + dir = dirs[conf.direction] || dirs.up; + + // direction + var sign = "" + dir[0]; + if (conf.bounce) { sign = sign == '+' ? '-' : '+'; } + params[dir[1]] = sign +'='+ offset; + + // perform animation + this.getTip().animate(params, conf.slideOutSpeed, function() { + $(this).hide(); + done.call(); + }); + } + ); + +})(jQuery); + + +/** + * @license + * jQuery Tools Validator @VERSION - HTML5 is here. Now use it. + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/form/validator/ + * + * Since: Mar 2010 + * Date: @DATE + */ +/*jslint evil: true */ +(function($) { + + $.tools = $.tools || {version: '@VERSION'}; + + // globals + var typeRe = /\[type=([a-z]+)\]/, + numRe = /^-?[0-9]*(\.[0-9]+)?$/, + dateInput = $.tools.dateinput, + + // http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/ + emailRe = /^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i, + urlRe = /^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i, + v; + + v = $.tools.validator = { + + conf: { + grouped: false, // show all error messages at once inside the container + effect: 'default', // show/hide effect for error message. only 'default' is built-in + errorClass: 'invalid', // input field class name in case of validation error + + // when to check for validity? + inputEvent: null, // change, blur, keyup, null + errorInputEvent: 'keyup', // change, blur, keyup, null + formEvent: 'submit', // submit, null + + lang: 'en', // default language for error messages + message: '', + messageAttr: 'data-message', // name of the attribute for overridden error message + messageClass: 'error', // error message element's class name + offset: [0, 0], + position: 'center right', + singleError: false, // validate all inputs at once + speed: 'normal' // message's fade-in speed + }, + + + /* The Error Messages */ + messages: { + "*": { en: "Please correct this value" } + }, + + localize: function(lang, messages) { + $.each(messages, function(key, msg) { + v.messages[key] = v.messages[key] || {}; + v.messages[key][lang] = msg; + }); + }, + + localizeFn: function(key, messages) { + v.messages[key] = v.messages[key] || {}; + $.extend(v.messages[key], messages); + }, + + /** + * Adds a new validator + */ + fn: function(matcher, msg, fn) { + + // no message supplied + if ($.isFunction(msg)) { + fn = msg; + + // message(s) on second argument + } else { + if (typeof msg == 'string') { msg = {en: msg}; } + this.messages[matcher.key || matcher] = msg; + } + + // check for "[type=xxx]" (not supported by jQuery) + var test = typeRe.exec(matcher); + if (test) { matcher = isType(test[1]); } + + // add validator to the arsenal + fns.push([matcher, fn]); + }, + + /* Add new show/hide effect */ + addEffect: function(name, showFn, closeFn) { + effects[name] = [showFn, closeFn]; + } + + }; + + /* calculate error message position relative to the input */ + function getPosition(trigger, el, conf) { + + // Get the first element in the selector set + el = $(el).first() || el; + + // get origin top/left position + var top = trigger.offset().top, + left = trigger.offset().left, + pos = conf.position.split(/,?\s+/), + y = pos[0], + x = pos[1]; + + top -= el.outerHeight() - conf.offset[0]; + left += trigger.outerWidth() + conf.offset[1]; + + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + top -= $(window).scrollTop(); + } + + // adjust Y + var height = el.outerHeight() + trigger.outerHeight(); + if (y == 'center') { top += height / 2; } + if (y == 'bottom') { top += height; } + + // adjust X + var width = trigger.outerWidth(); + if (x == 'center') { left -= (width + el.outerWidth()) / 2; } + if (x == 'left') { left -= width; } + + return {top: top, left: left}; + } + + + + // $.is("[type=xxx]") or $.filter("[type=xxx]") not working in jQuery 1.3.2 or 1.4.2 + function isType(type) { + function fn() { + return this.getAttribute("type") == type; + } + fn.key = "[type=\"" + type + "\"]"; + return fn; + } + + + var fns = [], effects = { + + 'default' : [ + + // show errors function + function(errs) { + + var conf = this.getConf(); + + // loop errors + $.each(errs, function(i, err) { + + // add error class + var input = err.input; + input.addClass(conf.errorClass); + + // get handle to the error container + var msg = input.data("msg.el"); + + // create it if not present + if (!msg) { + msg = $(conf.message).addClass(conf.messageClass).appendTo(document.body); + input.data("msg.el", msg); + } + + // clear the container + msg.css({visibility: 'hidden'}).find("p").remove(); + + // populate messages + $.each(err.messages, function(i, m) { + $("").html(m).appendTo(msg); + }); + + // make sure the width is not full body width so it can be positioned correctly + if (msg.outerWidth() == msg.parent().width()) { + msg.add(msg.find("p")).css({display: 'inline'}); + } + + // insert into correct position (relative to the field) + var pos = getPosition(input, msg, conf); + + msg.css({ visibility: 'visible', position: 'absolute', top: pos.top, left: pos.left }) + .fadeIn(conf.speed); + }); + + + // hide errors function + }, function(inputs) { + + var conf = this.getConf(); + inputs.removeClass(conf.errorClass).each(function() { + var msg = $(this).data("msg.el"); + if (msg) { msg.css({visibility: 'hidden'}); } + }); + } + ] + }; + + + /* sperial selectors */ + $.each("email,url,number".split(","), function(i, key) { + $.expr[':'][key] = function(el) { + return el.getAttribute("type") === key; + }; + }); + + + /* + oninvalid() jQuery plugin. + Usage: $("input:eq(2)").oninvalid(function() { ... }); + */ + $.fn.oninvalid = function( fn ){ + return this[fn ? "on" : "trigger"]("OI", fn); + }; + + + /******* built-in HTML5 standard validators *********/ + + v.fn(":email", "Please enter a valid email address", function(el, v) { + return !v || emailRe.test(v); + }); + + v.fn(":url", "Please enter a valid URL", function(el, v) { + return !v || urlRe.test(v); + }); + + v.fn(":number", "Please enter a numeric value.", function(el, v) { + return numRe.test(v); + }); + + v.fn("[max]", "Please enter a value no larger than $1", function(el, v) { + + // skip empty values and dateinputs + if (v === '' || dateInput && el.is(":date")) { return true; } + + var max = el.attr("max"); + return parseFloat(v) <= parseFloat(max) ? true : [max]; + }); + + v.fn("[min]", "Please enter a value of at least $1", function(el, v) { + + // skip empty values and dateinputs + if (v === '' || dateInput && el.is(":date")) { return true; } + + var min = el.attr("min"); + return parseFloat(v) >= parseFloat(min) ? true : [min]; + }); + + v.fn("[required]", "Please complete this mandatory field.", function(el, v) { + if (el.is(":checkbox")) { return el.is(":checked"); } + return !!v; + }); + + v.fn("[pattern]", function(el, v) { + return v === '' || new RegExp("^" + el.attr("pattern") + "$").test(v); + }); + + v.fn(":radio[required]", "Please select an option.", function(el) { + var checked = false; + var els = $("[name='" + el.attr("name") + "']").each(function(i, el) { + if ($(el).is(":checked") || checked) { + checked = true; + } + }); + return (checked) ? true : false; + }); + + function Validator(inputs, form, conf) { + + // private variables + var self = this, + fire = form.add(self); + + // make sure there are input fields available + inputs = inputs.not(":button, :image, :reset, :submit"); + + // Prevent default Firefox validation + form.attr("novalidate", "novalidate"); + + // utility function + function pushMessage(to, matcher, returnValue) { + + // only one message allowed + if (!conf.grouped && to.length) { return; } + + // the error message + var msg; + + // substitutions are returned + if (returnValue === false || $.isArray(returnValue)) { + msg = v.messages[matcher.key || matcher] || v.messages["*"]; + msg = msg[conf.lang] || v.messages["*"].en; + + // substitution + var matches = msg.match(/\$\d/g); + + if (matches && $.isArray(returnValue)) { + $.each(matches, function(i) { + msg = msg.replace(this, returnValue[i]); + }); + } + + // error message is returned directly + } else { + msg = returnValue[conf.lang] || returnValue; + } + + to.push(msg); + } + + + // API methods + $.extend(self, { + + getConf: function() { + return conf; + }, + + getForm: function() { + return form; + }, + + getInputs: function() { + return inputs; + }, + + reflow: function() { + inputs.each(function() { + var input = $(this), + msg = input.data("msg.el"); + + if (msg) { + var pos = getPosition(input, msg, conf); + msg.css({ top: pos.top, left: pos.left }); + } + }); + return self; + }, + + /* @param e - for internal use only */ + invalidate: function(errs, e) { + + // errors are given manually: { fieldName1: 'message1', fieldName2: 'message2' } + if (!e) { + var errors = []; + $.each(errs, function(key, val) { + var input = inputs.filter("[name='" + key + "']"); + if (input.length) { + + // trigger HTML5 ininvalid event + input.trigger("OI", [val]); + + errors.push({ input: input, messages: [val]}); + } + }); + + errs = errors; + e = $.Event(); + } + + // onFail callback + e.type = "onFail"; + fire.trigger(e, [errs]); + + // call the effect + if (!e.isDefaultPrevented()) { + effects[conf.effect][0].call(self, errs, e); + } + + return self; + }, + + reset: function(els) { + els = els || inputs; + els.removeClass(conf.errorClass).each(function() { + var msg = $(this).data("msg.el"); + if (msg) { + msg.remove(); + $(this).data("msg.el", null); + } + }).off(conf.errorInputEvent + '.v' || ''); + return self; + }, + + destroy: function() { + form.off(conf.formEvent + ".V reset.V"); + inputs.off(conf.inputEvent + ".V change.V"); + return self.reset(); + }, + + +//{{{ checkValidity() - flesh and bone of this tool + + /* @returns boolean */ + checkValidity: function(els, e) { + + els = els || inputs; + els = els.not(":disabled"); + + // filter duplicate elements by name + var names = {}; + els = els.filter(function(){ + var name = $(this).attr("name"); + if (!names[name]) { + names[name] = true; + return $(this); + } + }); + + if (!els.length) { return true; } + + e = e || $.Event(); + + // onBeforeValidate + e.type = "onBeforeValidate"; + fire.trigger(e, [els]); + if (e.isDefaultPrevented()) { return e.result; } + + // container for errors + var errs = []; + + // loop trough the inputs + els.each(function() { + + // field and it's error message container + var msgs = [], + el = $(this).data("messages", msgs), + event = dateInput && el.is(":date") ? "onHide.v" : conf.errorInputEvent + ".v"; + + // cleanup previous validation event + el.off(event); + + + // loop all validator functions + $.each(fns, function() { + var fn = this, match = fn[0]; + + // match found + if (el.filter(match).length) { + + // execute a validator function + var returnValue = fn[1].call(self, el, el.val()); + + + // validation failed. multiple substitutions can be returned with an array + if (returnValue !== true) { + + // onBeforeFail + e.type = "onBeforeFail"; + fire.trigger(e, [el, match]); + if (e.isDefaultPrevented()) { return false; } + + // overridden custom message + var msg = el.attr(conf.messageAttr); + if (msg) { + msgs = [msg]; + return false; + } else { + pushMessage(msgs, match, returnValue); + } + } + } + }); + + if (msgs.length) { + + errs.push({input: el, messages: msgs}); + + // trigger HTML5 ininvalid event + el.trigger("OI", [msgs]); + + // begin validating upon error event type (such as keyup) + if (conf.errorInputEvent) { + el.on(event, function(e) { + self.checkValidity(el, e); + }); + } + } + + if (conf.singleError && errs.length) { return false; } + + }); + + + // validation done. now check that we have a proper effect at hand + var eff = effects[conf.effect]; + if (!eff) { throw "Validator: cannot find effect \"" + conf.effect + "\""; } + + // errors found + if (errs.length) { + self.invalidate(errs, e); + return false; + + // no errors + } else { + + // call the effect + eff[1].call(self, els, e); + + // onSuccess callback + e.type = "onSuccess"; + fire.trigger(e, [els]); + + els.off(conf.errorInputEvent + ".v"); + } + + return true; + } +//}}} + + }); + + // callbacks + $.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","), function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API methods + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + + // form validation + if (conf.formEvent) { + form.on(conf.formEvent + ".V", function(e) { + if (!self.checkValidity(null, e)) { + return e.preventDefault(); + } + // Reset event type and target + e.target = form; + e.type = conf.formEvent; + }); + } + + // form reset + form.on("reset.V", function() { + self.reset(); + }); + + // disable browser's default validation mechanism + if (inputs[0] && inputs[0].validity) { + inputs.each(function() { + this.oninvalid = function() { + return false; + }; + }); + } + + // Web Forms 2.0 compatibility + if (form[0]) { + form[0].checkValidity = self.checkValidity; + } + + // input validation + if (conf.inputEvent) { + inputs.on(conf.inputEvent + ".V", function(e) { + self.checkValidity($(this), e); + }); + } + + // checkboxes and selects are checked separately + inputs.filter(":checkbox, select").filter("[required]").on("change.V", function(e) { + var el = $(this); + if (this.checked || (el.is("select") && $(this).val())) { + effects[conf.effect][1].call(self, el, e); + } + }); + + // get radio groups by name + inputs.filter(":radio[required]").on("change.V", function(e) { + var els = $("[name='" + $(e.srcElement).attr("name") + "']"); + if ((els !== null) && (els.length !== 0)) { + self.checkValidity(els, e); + } + }); + + // reposition tooltips when window is resized + $(window).resize(function() { + self.reflow(); + }); + + } + + + // jQuery plugin initialization + $.fn.validator = function(conf) { + + var instance = this.data("validator"); + + // destroy existing instance + if (instance) { + instance.destroy(); + this.removeData("validator"); + } + + // configuration + conf = $.extend(true, {}, v.conf, conf); + + // selector is a form + if (this.is("form")) { + return this.each(function() { + var form = $(this); + instance = new Validator(form.find(":input"), form, conf); + form.data("validator", instance); + }); + + } else { + instance = new Validator(this, this.eq(0).closest("form"), conf); + return this.data("validator", instance); + } + + }; + +})(jQuery); diff --git a/dist/jquery.tools.min.js b/dist/jquery.tools.min.js new file mode 100644 index 0000000..40140d8 --- /dev/null +++ b/dist/jquery.tools.min.js @@ -0,0 +1,3 @@ +!function(a,b){a.tools=a.tools||{version:"@VERSION"};var c=[],d={},e,f=[75,76,38,39,74,72,40,37],g={};e=a.tools.dateinput={conf:{format:"mm/dd/yy",formatter:"default",selectors:!1,yearRange:[-5,5],lang:"en",offset:[0,0],speed:0,firstDay:0,min:b,max:b,trigger:0,toggle:0,editable:0,css:{prefix:"cal",input:"date",root:0,head:0,title:0,prev:0,next:0,month:0,year:0,days:0,body:0,weeks:0,today:0,current:0,week:0,off:0,sunday:0,focus:0,disabled:0,trigger:0}},addFormatter:function(a,b){d[a]=b},localize:function(b,c){a.each(c,function(a,b){c[a]=b.split(",")}),g[b]=c}},e.localize("en",{months:"January,February,March,April,May,June,July,August,September,October,November,December",shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",days:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",shortDays:"Sun,Mon,Tue,Wed,Thu,Fri,Sat"});function h(a,b){return new Date(a,b+1,0).getDate()}function i(a,b){a=""+a,b=b||2;while(a.length");function k(a,b,c,e){var f=b.getDate(),h=b.getDay(),k=b.getMonth(),l=b.getFullYear(),m={d:f,dd:i(f),ddd:g[e].shortDays[h],dddd:g[e].days[h],m:k+1,mm:i(k+1),mmm:g[e].shortMonths[k],mmmm:g[e].months[k],yy:String(l).slice(2),yyyy:l},n=d[a](c,b,m,e);return j.html(n).html()}e.addFormatter("default",function(a,b,c,d){return a.replace(/d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g,function(a){return a in c?c[a]:a})}),e.addFormatter("prefixed",function(a,b,c,d){return a.replace(/%(d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*')/g,function(a,b){return b in c?c[b]:a})});function l(a){return parseInt(a,10)}function m(a,b){return a.getFullYear()===b.getFullYear()&&a.getMonth()==b.getMonth()&&a.getDate()==b.getDate()}function n(a){if(a!==b){if(a.constructor==Date)return a;if("string"==typeof a){var c=a.split("-");if(3==c.length)return new Date(l(c[0]),l(c[1])-1,l(c[2]));if(!/^-?\d+$/.test(a))return;a=l(a)}var d=new Date;return d.setDate(d.getDate()+a),d}}function o(d,e){var i=this,j=new Date,o=j.getFullYear(),p=e.css,q=g[e.lang],r=a("#"+p.root),s=r.find("#"+p.title),t,u,v,w,x,y,z,A,B=d.attr("data-value")||e.value||d.val(),C=d.attr("min")||e.min,D=d.attr("max")||e.max,E,F;if(0===C&&(C="0"),B=n(B)||j,C=n(C||new Date(o+e.yearRange[0],1,1)),D=n(D||new Date(o+e.yearRange[1]+1,1,-1)),!q)throw"Dateinput: invalid language: "+e.lang;"date"==d.attr("type")&&(F=d.clone(),def=F.wrap("").parent().html(),clone=a(def.replace(/type/i,"type=text data-orig-type")),e.value&&clone.val(e.value),d.replaceWith(clone),d=clone),d.addClass(p.input);var G=d.add(i);if(!r.length){r=a("").hide().css({position:"absolute"}).attr("id",p.root),r.children().eq(0).attr("id",p.head).end().eq(1).attr("id",p.body).children().eq(0).attr("id",p.days).end().eq(1).attr("id",p.weeks).end().end().end().find("a").eq(0).attr("id",p.prev).end().eq(1).attr("id",p.next),s=r.find("#"+p.head).find("div").attr("id",p.title),e.selectors&&(z=a("").attr("id",p.month),A=a("").attr("id",p.year),s.html(z.add(A)));for(var H=r.find("#"+p.days),I=0;7>I;I++)H.append(a("").text(q.shortDays[(I+e.firstDay)%7]));a("body").append(r)}e.trigger&&(t=a("").attr("href","#").addClass(p.trigger).click(function(a){return e.toggle?i.toggle():i.show(),a.preventDefault()}).insertAfter(d));var J=r.find("#"+p.weeks);A=r.find("#"+p.year),z=r.find("#"+p.month);function K(b,c,e){return d.attr("readonly")?(i.hide(e),void 0):(B=b,w=b.getFullYear(),x=b.getMonth(),y=b.getDate(),e||(e=a.Event("api")),"click"!=e.type||/msie/.test(navigator.userAgent.toLowerCase())||d.focus(),e.type="beforeChange",G.trigger(e,[b]),e.isDefaultPrevented()||(d.val(k(c.formatter,b,c.format,c.lang)),e.type="change",G.trigger(e),d.data("date",b),i.hide(e)),void 0)}function L(b){b.type="onShow",G.trigger(b),a(document).on("keydown.d",function(b){if(b.ctrlKey)return!0;var c=b.keyCode;if(8==c||46==c)return d.val(""),i.hide(b);if(27==c||9==c)return i.hide(b);if(a(f).index(c)>=0){if(!E)return i.show(b),b.preventDefault();var e=a("#"+p.weeks+" a"),g=a("."+p.focus),h=e.index(g);return g.removeClass(p.focus),74==c||40==c?h+=7:75==c||38==c?h-=7:76==c||39==c?h+=1:(72==c||37==c)&&(h-=1),h>41?(i.addMonth(),g=a("#"+p.weeks+" a:eq("+(h-42)+")")):0>h?(i.addMonth(-1),g=a("#"+p.weeks+" a:eq("+(h+42)+")")):g=e.eq(h),g.addClass(p.focus),b.preventDefault()}return 34==c?i.addMonth():33==c?i.addMonth(-1):36==c?i.today():(13==c&&(a(b.target).is("select")||a("."+p.focus).click()),a([16,17,18,9]).index(c)>=0)}),a(document).on("click.d",function(b){var c=b.target;c.id==p.root||a(c).parents("#"+p.root).length||c==d[0]||t&&c==t[0]||i.hide(b)})}a.extend(i,{show:function(b){if(!d.attr("disabled")&&!E&&(b=b||a.Event(),b.type="onBeforeShow",G.trigger(b),!b.isDefaultPrevented())){a.each(c,function(){this.hide()}),E=!0,z.off("change").change(function(){i.setValue(l(A.val()),l(a(this).val()))}),A.off("change").change(function(){i.setValue(l(a(this).val()),l(z.val()))}),u=r.find("#"+p.prev).off("click").click(function(a){return u.hasClass(p.disabled)||i.addMonth(-1),!1}),v=r.find("#"+p.next).off("click").click(function(a){return v.hasClass(p.disabled)||i.addMonth(),!1}),i.setValue(B);var f=d.offset();return/iPad/i.test(navigator.userAgent)&&(f.top-=a(window).scrollTop()),r.css({top:f.top+d.outerHeight(!0)+e.offset[0],left:f.left+e.offset[1]}),e.speed?r.show(e.speed,function(){L(b)}):(r.show(),L(b)),i}},setValue:function(c,d,f){var g=l(d)>=-1?new Date(l(c),l(d),l(f===b||isNaN(f)?1:f)):c||B;if(C>g?g=C:g>D&&(g=D),"string"==typeof c&&(g=n(c)),c=g.getFullYear(),d=g.getMonth(),f=g.getDate(),-1==d?(d=11,c--):12==d&&(d=0,c++),!E)return K(g,e),i;x=d,w=c,y=f;var k=new Date(c,d,1-e.firstDay),o=k.getDay(),r=h(c,d),t=h(c,d-1),F;if(e.selectors){z.empty(),a.each(q.months,function(b,d){CClick here to download latest version
":"Download latest version from here
"),"A"==c.tagName&&(c.onclick=function(){location.href=b})),d.onFail){var g=d.onFail.call(this);"string"==typeof g&&(c.innerHTML=g)}a&&(window[d.id]=document.getElementById(d.id)),f(this,{getRoot:function(){return c},getOptions:function(){return d},getConf:function(){return e},getApi:function(){return c.firstChild}})}c&&(jQuery.tools=jQuery.tools||{version:"@VERSION"},jQuery.tools.flashembed={conf:e},jQuery.fn.flashembed=function(a,b){return this.each(function(){jQuery(this).data("flashembed",flashembed(this,a,b))})})}(),function(a){var b,c,d,e;a.tools=a.tools||{version:"@VERSION"},a.tools.history={init:function(g){e||(a.browser.msie&&a.browser.version<"8"?c||(c=a("").attr("src","javascript:false;").hide().get(0),a("body").append(c),setInterval(function(){var d=c.contentWindow.document,e=d.location.hash;b!==e&&a(window).trigger("hash",e)},100),f(location.hash||"#")):setInterval(function(){var c=location.hash;c!==b&&a(window).trigger("hash",c)},100),d=d?d.add(g):g,g.click(function(b){var d=a(this).attr("href");return c&&f(d),"#"!=d.slice(0,1)?(location.href="#"+d,b.preventDefault()):void 0}),e=!0)}};function f(a){if(a){var b=c.contentWindow.document;b.open().close(),b.location.hash=a}}a(window).on("hash",function(c,e){e?d.filter(function(){var b=a(this).attr("href");return b==e||b==e.replace("#","")}).trigger("history",[e]):d.eq(0).trigger("history",[e]),b=e}),a.fn.history=function(b){return a.tools.history.init(this),this.on("history",b)}}(jQuery),function(a){a.fn.mousewheel=function(a){return this[a?"on":"trigger"]("wheel",a)},a.event.special.wheel={setup:function(){a.event.add(this,b,c,{})},teardown:function(){a.event.remove(this,b,c)}};var b=a.browser.mozilla?"DOMMouseScroll"+(a.browser.version<"1.9"?" mousemove":""):"mousewheel";function c(b){switch(b.type){case"mousemove":return a.extend(b.data,{clientX:b.clientX,clientY:b.clientY,pageX:b.pageX,pageY:b.pageY});case"DOMMouseScroll":a.extend(b,b.data),b.delta=-b.detail/3;break;case"mousewheel":b.delta=b.wheelDelta/120}return b.type="wheel",a.event.handle.call(this,b,b.delta)}}(jQuery),function(a){var b=a.tools.tooltip;b.dynamic={conf:{classNames:"top right bottom left"}};function c(b){var c=a(window),d=c.width()+c.scrollLeft(),e=c.height()+c.scrollTop();return[b.offset().top<=c.scrollTop(),d<=b.offset().left+b.width(),e<=b.offset().top+b.height(),c.scrollLeft()>=b.offset().left]}function d(a){var b=a.length;while(b--)if(a[b])return!1;return!0}a.fn.dynamic=function(e){"number"==typeof e&&(e={speed:e}),e=a.extend({},b.dynamic.conf,e);var f=a.extend(!0,{},e),g=e.classNames.split(/\s/),h,i;return this.each(function(){var b=a(this).tooltip().onBeforeShow(function(b,e){var i=this.getTip(),j=this.getConf();h||(h=[j.position[0],j.position[1],j.offset[0],j.offset[1],a.extend({},j)]),a.extend(j,h[4]),j.position=[h[0],h[1]],j.offset=[h[2],h[3]],i.css({visibility:"hidden",position:"absolute",top:e.top,left:e.left}).show();var k=a.extend(!0,{},f),l=c(i);d(l)||(l[2]&&(a.extend(j,k.top),j.position[0]="top",i.addClass(g[0])),l[3]&&(a.extend(j,k.right),j.position[1]="right",i.addClass(g[1])),l[0]&&(a.extend(j,k.bottom),j.position[0]="bottom",i.addClass(g[2])),l[1]&&(a.extend(j,k.left),j.position[1]="left",i.addClass(g[3])),(l[0]||l[2])&&(j.offset[0]*=-1),(l[1]||l[3])&&(j.offset[1]*=-1)),i.css({visibility:"visible"}).hide()});b.onBeforeShow(function(){var a=this.getConf(),b=this.getTip();setTimeout(function(){a.position=[h[0],h[1]],a.offset=[h[2],h[3]]},0)}),b.onHide(function(){var a=this.getTip();a.removeClass(e.classNames)}),i=b}),e.api?i:this}}(jQuery),function(a){a.tools=a.tools||{version:"@VERSION"},a.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,fadeIE:!1,position:["top","center"],offset:[0,0],relative:!1,cancelDefault:!0,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave",tooltip:"mouseenter,mouseleave"},layout:"",tipClass:"tooltip"},addEffect:function(a,c,d){b[a]=[c,d]}};var b={toggle:[function(a){var b=this.getConf(),c=this.getTip(),d=b.opacity;1>d&&c.css({opacity:d}),c.show(),a.call()},function(a){this.getTip().hide(),a.call()}],fade:[function(a){var b=this.getConf();!/msie/.test(navigator.userAgent.toLowerCase())||b.fadeIE?this.getTip().fadeTo(b.fadeInSpeed,b.opacity,a):(this.getTip().show(),a())},function(a){var b=this.getConf();!/msie/.test(navigator.userAgent.toLowerCase())||b.fadeIE?this.getTip().fadeOut(b.fadeOutSpeed,a):(this.getTip().hide(),a())}]};function c(b,c,d){var e=d.relative?b.position().top:b.offset().top,f=d.relative?b.position().left:b.offset().left,g=d.position[0];e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());var h=c.outerHeight()+b.outerHeight();"center"==g&&(e+=h/2),"bottom"==g&&(e+=h),g=d.position[1];var i=c.outerWidth()+b.outerWidth();return"center"==g&&(f-=i/2),"left"==g&&(f-=i),{top:e,left:f}}function d(d,e){var f=this,g=d.add(f),h,i=0,j=0,k=d.attr("title"),l=d.attr("data-tooltip"),m=b[e.effect],n,o=d.is(":input"),p=o&&d.is(":checkbox, :radio, select, :button, :submit"),q=d.attr("type"),r=e.events[q]||e.events[o?p?"widget":"input":"def"];if(!m)throw'Nonexistent effect "'+e.effect+'"';if(r=r.split(/,\s*/),2!=r.length)throw"Tooltip: bad events configuration for "+q;d.on(r[0],function(a){clearTimeout(i),e.predelay?j=setTimeout(function(){f.show(a)},e.predelay):f.show(a)}).on(r[1],function(a){clearTimeout(j),e.delay?i=setTimeout(function(){f.hide(a)},e.delay):f.hide(a)}),k&&e.cancelDefault&&(d.removeAttr("title"),d.data("title",k)),a.extend(f,{show:function(b){if(!h&&(l?h=a(l):e.tip?h=a(e.tip).eq(0):k?h=a(e.layout).addClass(e.tipClass).appendTo(document.body).hide().append(k):(h=d.find("."+e.tipClass),h.length||(h=d.next()),h.length||(h=d.parent().next())),!h.length))throw"Cannot find tooltip for "+d;if(f.isShown())return f;h.stop(!0,!0);var o=c(d,h,e);if(e.tip&&h.html(d.data("title")),b=a.Event(),b.type="onBeforeShow",g.trigger(b,[o]),b.isDefaultPrevented())return f;o=c(d,h,e),h.css({position:"absolute",top:o.top,left:o.left}),n=!0,m[0].call(f,function(){b.type="onShow",n="full",g.trigger(b)});var p=e.events.tooltip.split(/,\s*/);return h.data("__set")||(h.off(p[0]).on(p[0],function(){clearTimeout(i),clearTimeout(j)}),p[1]&&!d.is("input:not(:checkbox, :radio), textarea")&&h.off(p[1]).on(p[1],function(a){a.relatedTarget!=d[0]&&d.trigger(r[1].split(" ")[0])}),e.tip||h.data("__set",!0)),f},hide:function(c){return h&&f.isShown()?(c=a.Event(),c.type="onBeforeHide",g.trigger(c),c.isDefaultPrevented()?void 0:(n=!1,b[e.effect][1].call(f,function(){c.type="onHide",g.trigger(c)}),f)):f},isShown:function(a){return a?"full"==n:n},getConf:function(){return e},getTip:function(){return h},getTrigger:function(){return d}}),a.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(b,c){a.isFunction(e[c])&&a(f).on(c,e[c]),f[c]=function(b){return b&&a(f).on(c,b),f}})}a.fn.tooltip=function(b){var c;return b=a.extend(!0,{},a.tools.tooltip.conf,b),"string"==typeof b.position&&(b.position=b.position.split(/,?\s/)),this.each(function(){null===a(this).data("tooltip")&&(c=new d(a(this),b),a(this).data("tooltip",c))}),b.api?c:this}}(jQuery),function(a){var b=a.tools.tooltip;a.extend(b.conf,{direction:"up",bounce:!1,slideOffset:10,slideInSpeed:200,slideOutSpeed:200,slideFade:!/msie/.test(navigator.userAgent.toLowerCase())});var c={up:["-","top"],down:["+","top"],left:["-","left"],right:["+","left"]};b.addEffect("slide",function(a){var b=this.getConf(),d=this.getTip(),e=b.slideFade?{opacity:b.opacity}:{},f=c[b.direction]||c.up;e[f[1]]=f[0]+"="+b.slideOffset,b.slideFade&&d.css({opacity:0}),d.show().animate(e,b.slideInSpeed,a)},function(b){var d=this.getConf(),e=d.slideOffset,f=d.slideFade?{opacity:0}:{},g=c[d.direction]||c.up,h=""+g[0];d.bounce&&(h="+"==h?"-":"+"),f[g[1]]=h+"="+e,this.getTip().animate(f,d.slideOutSpeed,function(){a(this).hide(),b.call()})})}(jQuery),function(a){a.tools=a.tools||{version:"@VERSION"};var b=/\[type=([a-z]+)\]/,c=/^-?[0-9]*(\.[0-9]+)?$/,d=a.tools.dateinput,e=/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i,f=/^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i,g;g=a.tools.validator={conf:{grouped:!1,effect:"default",errorClass:"invalid",inputEvent:null,errorInputEvent:"keyup",formEvent:"submit",lang:"en",message:"",messageAttr:"data-message",messageClass:"error",offset:[0,0],position:"center right",singleError:!1,speed:"normal"},messages:{"*":{en:"Please correct this value"}},localize:function(b,c){a.each(c,function(a,c){g.messages[a]=g.messages[a]||{},g.messages[a][b]=c})},localizeFn:function(b,c){g.messages[b]=g.messages[b]||{},a.extend(g.messages[b],c)},fn:function(c,d,e){a.isFunction(d)?e=d:("string"==typeof d&&(d={en:d}),this.messages[c.key||c]=d);var f=b.exec(c);f&&(c=i(f[1])),j.push([c,e])},addEffect:function(a,b,c){k[a]=[b,c]}};function h(b,c,d){c=a(c).first()||c;var e=b.offset().top,f=b.offset().left,g=d.position.split(/,?\s+/),h=g[0],i=g[1];e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());var j=c.outerHeight()+b.outerHeight();"center"==h&&(e+=j/2),"bottom"==h&&(e+=j);var k=b.outerWidth();return"center"==i&&(f-=(k+c.outerWidth())/2),"left"==i&&(f-=k),{top:e,left:f}}function i(a){function b(){return this.getAttribute("type")==a}return b.key='[type="'+a+'"]',b}var j=[],k={"default":[function(b){var c=this.getConf();a.each(b,function(b,d){var e=d.input;e.addClass(c.errorClass);var f=e.data("msg.el");f||(f=a(c.message).addClass(c.messageClass).appendTo(document.body),e.data("msg.el",f)),f.css({visibility:"hidden"}).find("p").remove(),a.each(d.messages,function(b,c){a("").html(c).appendTo(f)}),f.outerWidth()==f.parent().width()&&f.add(f.find("p")).css({display:"inline"});var g=h(e,f,c);f.css({visibility:"visible",position:"absolute",top:g.top,left:g.left}).fadeIn(c.speed)})},function(b){var c=this.getConf();b.removeClass(c.errorClass).each(function(){var b=a(this).data("msg.el");b&&b.css({visibility:"hidden"})})}]};a.each("email,url,number".split(","),function(b,c){a.expr[":"][c]=function(a){return a.getAttribute("type")===c}}),a.fn.oninvalid=function(a){return this[a?"on":"trigger"]("OI",a)},g.fn(":email","Please enter a valid email address",function(a,b){return!b||e.test(b)}),g.fn(":url","Please enter a valid URL",function(a,b){return!b||f.test(b)}),g.fn(":number","Please enter a numeric value.",function(a,b){return c.test(b)}),g.fn("[max]","Please enter a value no larger than $1",function(a,b){if(""===b||d&&a.is(":date"))return!0;var c=a.attr("max");return parseFloat(b)<=parseFloat(c)?!0:[c]}),g.fn("[min]","Please enter a value of at least $1",function(a,b){if(""===b||d&&a.is(":date"))return!0;var c=a.attr("min");return parseFloat(b)>=parseFloat(c)?!0:[c]}),g.fn("[required]","Please complete this mandatory field.",function(a,b){return a.is(":checkbox")?a.is(":checked"):!!b}),g.fn("[pattern]",function(a,b){return""===b||new RegExp("^"+a.attr("pattern")+"$").test(b)}),g.fn(":radio[required]","Please select an option.",function(b){var c=!1,d=a("[name='"+b.attr("name")+"']").each(function(b,d){(a(d).is(":checked")||c)&&(c=!0)});return c?!0:!1});function l(b,c,e){var f=this,i=c.add(f);b=b.not(":button, :image, :reset, :submit"),c.attr("novalidate","novalidate");function l(b,c,d){if(e.grouped||!b.length){var f;if(d===!1||a.isArray(d)){f=g.messages[c.key||c]||g.messages["*"],f=f[e.lang]||g.messages["*"].en;var h=f.match(/\$\d/g);h&&a.isArray(d)&&a.each(h,function(a){f=f.replace(this,d[a])})}else f=d[e.lang]||d;b.push(f)}}a.extend(f,{getConf:function(){return e},getForm:function(){return c},getInputs:function(){return b},reflow:function(){return b.each(function(){var b=a(this),c=b.data("msg.el");if(c){var d=h(b,c,e);c.css({top:d.top,left:d.left})}}),f},invalidate:function(c,d){if(!d){var g=[];a.each(c,function(a,c){var d=b.filter("[name='"+a+"']");d.length&&(d.trigger("OI",[c]),g.push({input:d,messages:[c]}))}),c=g,d=a.Event()}return d.type="onFail",i.trigger(d,[c]),d.isDefaultPrevented()||k[e.effect][0].call(f,c,d),f},reset:function(c){return c=c||b,c.removeClass(e.errorClass).each(function(){var b=a(this).data("msg.el");b&&(b.remove(),a(this).data("msg.el",null))}).off(e.errorInputEvent+".v"||""),f},destroy:function(){return c.off(e.formEvent+".V reset.V"),b.off(e.inputEvent+".V change.V"),f.reset()},checkValidity:function(c,g){c=c||b,c=c.not(":disabled");var h={};if(c=c.filter(function(){var b=a(this).attr("name");return h[b]?void 0:(h[b]=!0,a(this))}),!c.length)return!0;if(g=g||a.Event(),g.type="onBeforeValidate",i.trigger(g,[c]),g.isDefaultPrevented())return g.result;var m=[];c.each(function(){var b=[],c=a(this).data("messages",b),h=d&&c.is(":date")?"onHide.v":e.errorInputEvent+".v";return c.off(h),a.each(j,function(){var a=this,d=a[0];if(c.filter(d).length){var h=a[1].call(f,c,c.val());if(h!==!0){if(g.type="onBeforeFail",i.trigger(g,[c,d]),g.isDefaultPrevented())return!1;var j=c.attr(e.messageAttr);if(j)return b=[j],!1;l(b,d,h)}}}),b.length&&(m.push({input:c,messages:b}),c.trigger("OI",[b]),e.errorInputEvent&&c.on(h,function(a){f.checkValidity(c,a)})),e.singleError&&m.length?!1:void 0});var n=k[e.effect];if(!n)throw'Validator: cannot find effect "'+e.effect+'"';return m.length?(f.invalidate(m,g),!1):(n[1].call(f,c,g),g.type="onSuccess",i.trigger(g,[c]),c.off(e.errorInputEvent+".v"),!0)}}),a.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","),function(b,c){a.isFunction(e[c])&&a(f).on(c,e[c]),f[c]=function(b){return b&&a(f).on(c,b),f}}),e.formEvent&&c.on(e.formEvent+".V",function(a){return f.checkValidity(null,a)?(a.target=c,a.type=e.formEvent,void 0):a.preventDefault()}),c.on("reset.V",function(){f.reset()}),b[0]&&b[0].validity&&b.each(function(){this.oninvalid=function(){return!1}}),c[0]&&(c[0].checkValidity=f.checkValidity),e.inputEvent&&b.on(e.inputEvent+".V",function(b){f.checkValidity(a(this),b)}),b.filter(":checkbox, select").filter("[required]").on("change.V",function(b){var c=a(this);(this.checked||c.is("select")&&a(this).val())&&k[e.effect][1].call(f,c,b)}),b.filter(":radio[required]").on("change.V",function(b){var c=a("[name='"+a(b.srcElement).attr("name")+"']");null!==c&&0!==c.length&&f.checkValidity(c,b)}),a(window).resize(function(){f.reflow()})}a.fn.validator=function(b){var c=this.data("validator");return c&&(c.destroy(),this.removeData("validator")),b=a.extend(!0,{},g.conf,b),this.is("form")?this.each(function(){var d=a(this);c=new l(d.find(":input"),d,b),d.data("validator",c)}):(c=new l(this,this.eq(0).closest("form"),b),this.data("validator",c))}}(jQuery); +//# sourceMappingURL=jquery.tools.min.map \ No newline at end of file diff --git a/dist/jquery.tools.min.map b/dist/jquery.tools.min.map new file mode 100644 index 0000000..555a02d --- /dev/null +++ b/dist/jquery.tools.min.map @@ -0,0 +1 @@ +{"version":3,"file":"dist/jquery.tools.min.js","sources":["dist/jquery.tools.js"],"names":["$","undefined","tools","version","instances","formatters","tool","KEYS","LABELS","dateinput","conf","format","formatter","selectors","yearRange","lang","offset","speed","firstDay","min","max","trigger","toggle","editable","css","prefix","input","root","head","title","prev","next","month","year","days","body","weeks","today","current","week","off","sunday","focus","disabled","addFormatter","name","fn","localize","language","labels","each","key","val","split","months","shortMonths","shortDays","dayAm","Date","getDate","zeropad","len","length","tmpTag","date","text","d","D","getDay","m","getMonth","y","getFullYear","flags","dd","ddd","dddd","mm","mmm","mmmm","yy","String","slice","yyyy","ret","html","replace","$0","$1","integer","parseInt","isSameDay","d1","d2","parseDate","constructor","els","test","setDate","Dateinput","self","this","now","yearNow","find","pm","nm","currYear","currMonth","currDay","monthSelector","yearSelector","value","attr","opened","original","clone","def","wrap","parent","replaceWith","addClass","fire","add","hide","position","children","eq","end","append","click","e","show","preventDefault","insertAfter","select","Event","type","navigator","userAgent","toLowerCase","isDefaultPrevented","data","onShow","ev","document","on","ctrlKey","keyCode","index","el","removeClass","addMonth","target","is","id","parents","extend","change","setValue","hasClass","pos","top","window","scrollTop","outerHeight","left","day","isNaN","tmp","begin","prevDays","empty","i","j","a","num","removeAttr","beg","setMin","fit","setMax","addDay","amount","targetMonth","daysInTargetMonth","targetDay","addYear","destroy","remove","removeData","isOpen","getConf","getInput","getCalendar","getValue","dateFormat","isFunction","keydown","shiftKey","altKey","expr","getAttribute","push","jQuery","t","overlay","w","start","fadeInSpeed","zIndex","getPosition","p","height","width","loadEffect","onLoad","getOverlay","getTrigger","oWidth","outerWidth","img","fixed","bg","indexOf","border","display","itop","Math","round","ileft","scrollLeft","animate","fadeIn","isOpened","call","closeEffect","onClose","closeSpeed","addEffect","loadFn","closeFn","effects","close","closeOnClick","closeOnEsc","effect","appVersion","load","mask","oneInstance","fadeOut","Overlay","closers","maskConf","expose","uid","random","toString","color","jq","eff","oHeight","getMask","one","getClosers","prepend","onBeforeLoad","api","oldFnData","evt","elem","arguments","_data","apply","rangeinput","step","steps","precision","vertical","keyboard","progress","slider","handle","doc","draggable","drag","ondragstart","x","x0","pageX","y0","pageY","props","n","pow","dim","v","s","currentStyle","hasEvent","onSlide","RangeInput","origo","before","parseFloat","range","fireOnSlide","slide","isSetValue","isClick","callback","init","getProgress","getHandle","am","stepUp","stepDown","fix","up","down","blur","filter","scrollable","autoscroll","autoplay","interval","autopause","opts","getRoot","timer","stopped","scroll","clearTimeout","setTimeout","play","pause","resume","stop","getNaviButtons","hover","activeClass","circular","clonedClass","disabledClass","easing","initialIndex","item","items","mousewheel","size","touch","wheelSpeed","query","Scrollable","itemWrap","getIndex","getSize","getItems","getItemWrap","not","move","time","seekTo","addItem","last","first","jquery","cloned1","prependTo","cloned2","appendTo","onBeforeSeek","hidden_parents","stopPropagation","toggleClass","delta","ontouchstart","touches","clientX","clientY","ontouchmove","deltaX","deltaY","metaKey","navi","naviItem","indexed","idPrefix","history","buttons","cls","hashed","pushState","originalEvent","state","doClick","onAddItem","tabs","onBeforeClick","onClick","initialEffect","event","rotate","slideUpSpeed","slideDownSpeed","default","done","getPanes","fade","fadeOutSpeed","panes","slideUp","slideDown","ajax","getTabs","animating","nextPane","currentPane","getCurrentPane","complete","Tabs","paneSelector","tab","firstRender","getCurrentTab","location","hash","slideshow","clickable","Slideshow","nextButton","prevButton","maskId","loadSpeed","opacity","startOpacity","viewport","innerWidth","documentElement","clientWidth","exposed","loaded","config","overlayIndex","fadeTo","onBeforeClose","isLoaded","fully","getExposed","IE","all","URL","JQUERY","RE","GLOBAL_OPTS","allowfullscreen","allowscriptaccess","quality","onFail","expressInstall","w3c","cachebusting","attachEvent","__flash_unloadHandler","__flash_savedUnloadHandler","to","from","hasOwnProperty","map","arr","func","newArr","flashembed","getElementById","src","Flash","f","getVersion","fo","ver","plugins","description","ActiveXObject","GetVariable","err","err2","exec","asString","obj","RegExp","join","str","prop","getHTML","vars","k","encodeURIComponent","isSupported","VERSION","innerHTML","MMredirectURL","href","MMplayerType","MMdoctitle","tagName","onclick","getOptions","getApi","firstChild","iframe","links","inited","browser","msie","get","setInterval","idoc","contentWindow","h","setIframeLocation","open","special","wheel","setup","wheelEvents","wheelHandler","teardown","mozilla","detail","wheelDelta","tooltip","dynamic","classNames","getCropping","right","bottom","isVisible","crop","confOrigin","orig","onBeforeShow","tip","getTip","tipConf","visibility","c","onHide","predelay","delay","fadeIE","relative","cancelDefault","events","widget","layout","tipClass","hideFn","o","Tooltip","pretimer","tipAttr","shown","isInput","isWidget","isShown","relatedTarget","direction","bounce","slideOffset","slideInSpeed","slideOutSpeed","slideFade","dirs","params","dir","sign","typeRe","numRe","dateInput","emailRe","urlRe","validator","grouped","errorClass","inputEvent","errorInputEvent","formEvent","message","messageAttr","messageClass","singleError","messages","*","en","msg","localizeFn","matcher","isType","fns","showFn","errs","inputs","oninvalid","checked","Validator","form","pushMessage","returnValue","isArray","matches","match","getForm","getInputs","reflow","invalidate","errors","reset","checkValidity","names","result","msgs","validity","srcElement","resize","instance","closest"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..993b3d5 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "jquery.tools", + "title": "jQuery Tools", + "description": "The missing UI library for the Web", + "version": "1.11.0-beta3", + "main": "dist/jquery.tools.js", + "homepage": "http://jquerytools.org", + "repository": { + "type": "git", + "url": "https://github.com/jquerytools/jquerytools.git" + }, + "keywords": [ + "jquery", + "javascript", + "library" + ], + "bugs": { + "url": "https://github.com/jquerytools/jquerytools/issues" + }, + "dependencies": {}, + "devDependencies": { + "load-grunt-tasks": "0.2.0", + "requirejs": "2.1.9", + "shelljs": "0.2.6", + "grunt": "0.4.2", + "grunt-cli": "0.1.11", + "grunt-contrib-jshint": "0.7.2", + "grunt-contrib-uglify": "0.2.7", + "grunt-contrib-watch": "0.5.3", + "grunt-bowercopy": "0.4.1", + "grunt-compare-size": "0.4.0", + "grunt-git-authors": "1.2.0", + "grunt-jscs-checker": "0.2.6", + "grunt-jsonlint": "1.0.4" + }, + "scripts": { + "build": "npm install && grunt", + "start": "grunt watch", + "test": "grunt" + } +} diff --git a/src/.jshintrc b/src/.jshintrc new file mode 100644 index 0000000..849298d --- /dev/null +++ b/src/.jshintrc @@ -0,0 +1,28 @@ +{ + "boss": true, + "curly": false, + "eqeqeq": false, + "eqnull": true, + "expr": true, + "immed": true, + "noarg": true, + "onevar": false, + "smarttabs": true, + "trailing": true, + "undef": false, + "unused": false, + "scripturl":true, + + "evil": true, + "sub": true, + + "es3": true, + "browser": true, + "wsh": true, + + "globals": { + "jQuery": true, + "define": true, + "module": true + } +} diff --git a/src/dateinput/dateinput.js b/src/dateinput/dateinput.js index 1c78d58..2873a39 100644 --- a/src/dateinput/dateinput.js +++ b/src/dateinput/dateinput.js @@ -1,444 +1,445 @@ /** - * @license + * @license * jQuery Tools @VERSION Dateinput - for humans - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/form/dateinput/ * * Since: Mar 2010 - * Date: @DATE + * Date: @DATE */ -(function($, undefined) { - - /* TODO: - preserve today highlighted - */ - - $.tools = $.tools || {version: '@VERSION'}; - - var instances = [], - formatters = {}, - tool, - - // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39 - KEYS = [75, 76, 38, 39, 74, 72, 40, 37], - LABELS = {}; - - tool = $.tools.dateinput = { - - conf: { - format: 'mm/dd/yy', - formatter: 'default', - selectors: false, - yearRange: [-5, 5], - lang: 'en', - offset: [0, 0], - speed: 0, - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - min: undefined, - max: undefined, - trigger: 0, - toggle: 0, - editable: 0, - - css: { - - prefix: 'cal', - input: 'date', - - // ids - root: 0, - head: 0, - title: 0, - prev: 0, - next: 0, - month: 0, - year: 0, - days: 0, - - body: 0, - weeks: 0, - today: 0, - current: 0, - - // classnames - week: 0, - off: 0, - sunday: 0, - focus: 0, - disabled: 0, - trigger: 0 - } - }, - - addFormatter: function(name, fn) { - formatters[name] = fn; - }, - - localize: function(language, labels) { - $.each(labels, function(key, val) { - labels[key] = val.split(","); - }); - LABELS[language] = labels; - } - - }; - - tool.localize("en", { - months: 'January,February,March,April,May,June,July,August,September,October,November,December', - shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec', - days: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday', - shortDays: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat' - }); - - +(function($, undefined) { + + /* TODO: + preserve today highlighted + */ + + $.tools = $.tools || {version: '@VERSION'}; + + var instances = [], + formatters = {}, + tool, + + // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39 + KEYS = [75, 76, 38, 39, 74, 72, 40, 37], + LABELS = {}; + + tool = $.tools.dateinput = { + + conf: { + format: 'mm/dd/yy', + formatter: 'default', + selectors: false, + yearRange: [-5, 5], + lang: 'en', + offset: [0, 0], + speed: 0, + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + min: undefined, + max: undefined, + trigger: 0, + toggle: 0, + editable: 0, + + css: { + + prefix: 'cal', + input: 'date', + + // ids + root: 0, + head: 0, + title: 0, + prev: 0, + next: 0, + month: 0, + year: 0, + days: 0, + + body: 0, + weeks: 0, + today: 0, + current: 0, + + // classnames + week: 0, + off: 0, + sunday: 0, + focus: 0, + disabled: 0, + trigger: 0 + } + }, + + addFormatter: function(name, fn) { + formatters[name] = fn; + }, + + localize: function(language, labels) { + $.each(labels, function(key, val) { + labels[key] = val.split(","); + }); + LABELS[language] = labels; + } + + }; + + tool.localize("en", { + months: 'January,February,March,April,May,June,July,August,September,October,November,December', + shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec', + days: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday', + shortDays: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat' + }); + + //{{{ private functions - - - // @return amount of days in certain month - function dayAm(year, month) { - return new Date(year, month + 1, 0).getDate(); - } - - function zeropad(val, len) { - val = '' + val; - len = len || 2; - while (val.length < len) { val = "0" + val; } - return val; - } - - // thanks: http://stevenlevithan.com/assets/misc/date.format.js - var tmpTag = $(""); - - function format(formatter, date, text, lang) { - var d = date.getDate(), - D = date.getDay(), - m = date.getMonth(), - y = date.getFullYear(), - - flags = { - d: d, - dd: zeropad(d), - ddd: LABELS[lang].shortDays[D], - dddd: LABELS[lang].days[D], - m: m + 1, - mm: zeropad(m + 1), - mmm: LABELS[lang].shortMonths[m], - mmmm: LABELS[lang].months[m], - yy: String(y).slice(2), - yyyy: y - }; - - var ret = formatters[formatter](text, date, flags, lang); - - // a small trick to handle special characters - return tmpTag.html(ret).html(); - - } - - tool.addFormatter('default', function(text, date, flags, lang) { - return text.replace(/d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, function ($0) { - return $0 in flags ? flags[$0] : $0; - }); - }); - - tool.addFormatter('prefixed', function(text, date, flags, lang) { - return text.replace(/%(d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*')/g, function ($0, $1) { - return $1 in flags ? flags[$1] : $0; - }); - }); - - function integer(val) { - return parseInt(val, 10); - } - - function isSameDay(d1, d2) { - return d1.getFullYear() === d2.getFullYear() && - d1.getMonth() == d2.getMonth() && - d1.getDate() == d2.getDate(); - } - - function parseDate(val) { - - if (val === undefined) { return; } - if (val.constructor == Date) { return val; } - - if (typeof val == 'string') { - - // rfc3339? - var els = val.split("-"); - if (els.length == 3) { - return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2])); - } - - // invalid offset - if ( !(/^-?\d+$/).test(val) ) { return; } - - // convert to integer - val = integer(val); - } - - var date = new Date; - date.setDate(date.getDate() + val); - return date; - } - + + + // @return amount of days in certain month + function dayAm(year, month) { + return new Date(year, month + 1, 0).getDate(); + } + + function zeropad(val, len) { + val = '' + val; + len = len || 2; + while (val.length < len) { val = "0" + val; } + return val; + } + + // thanks: http://stevenlevithan.com/assets/misc/date.format.js + var tmpTag = $(""); + + function format(formatter, date, text, lang) { + var d = date.getDate(), + D = date.getDay(), + m = date.getMonth(), + y = date.getFullYear(), + + flags = { + d: d, + dd: zeropad(d), + ddd: LABELS[lang].shortDays[D], + dddd: LABELS[lang].days[D], + m: m + 1, + mm: zeropad(m + 1), + mmm: LABELS[lang].shortMonths[m], + mmmm: LABELS[lang].months[m], + yy: String(y).slice(2), + yyyy: y + }; + + var ret = formatters[formatter](text, date, flags, lang); + + // a small trick to handle special characters + return tmpTag.html(ret).html(); + + } + + tool.addFormatter('default', function(text, date, flags, lang) { + return text.replace(/d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, function ($0) { + return $0 in flags ? flags[$0] : $0; + }); + }); + + tool.addFormatter('prefixed', function(text, date, flags, lang) { + return text.replace(/%(d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*')/g, function ($0, $1) { + return $1 in flags ? flags[$1] : $0; + }); + }); + + function integer(val) { + return parseInt(val, 10); + } + + function isSameDay(d1, d2) { + return d1.getFullYear() === d2.getFullYear() && + d1.getMonth() == d2.getMonth() && + d1.getDate() == d2.getDate(); + } + + function parseDate(val) { + + if (val === undefined) { return; } + if (val.constructor == Date) { return val; } + + if (typeof val == 'string') { + + // rfc3339? + var els = val.split("-"); + if (els.length == 3) { + return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2])); + } + + // invalid offset + if ( !(/^-?\d+$/).test(val) ) { return; } + + // convert to integer + val = integer(val); + } + + var date = new Date(); + date.setDate(date.getDate() + val); + return date; + } + //}}} - - - function Dateinput(input, conf) { - - // variables - var self = this, - now = new Date, - yearNow = now.getFullYear(), - css = conf.css, - labels = LABELS[conf.lang], - root = $("#" + css.root), - title = root.find("#" + css.title), - trigger, - pm, nm, - currYear, currMonth, currDay, - value = input.attr("data-value") || conf.value || input.val(), - min = input.attr("min") || conf.min, - max = input.attr("max") || conf.max, - opened, - original; - - // zero min is not undefined - if (min === 0) { min = "0"; } - - // use sane values for value, min & max - value = parseDate(value) || now; - - min = parseDate(min || new Date(yearNow + conf.yearRange[0], 1, 1)); - max = parseDate(max || new Date( yearNow + conf.yearRange[1]+ 1, 1, -1)); - - - // check that language exists - if (!labels) { throw "Dateinput: invalid language: " + conf.lang; } - - // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser - if (input.attr("type") == 'date') { - var original = input.clone(), + + + function Dateinput(input, conf) { + + // variables + var self = this, + now = new Date(), + yearNow = now.getFullYear(), + css = conf.css, + labels = LABELS[conf.lang], + root = $("#" + css.root), + title = root.find("#" + css.title), + trigger, + pm, nm, + currYear, currMonth, currDay, + monthSelector, yearSelector, + value = input.attr("data-value") || conf.value || input.val(), + min = input.attr("min") || conf.min, + max = input.attr("max") || conf.max, + opened, + original; + + // zero min is not undefined + if (min === 0) { min = "0"; } + + // use sane values for value, min & max + value = parseDate(value) || now; + + min = parseDate(min || new Date(yearNow + conf.yearRange[0], 1, 1)); + max = parseDate(max || new Date( yearNow + conf.yearRange[1]+ 1, 1, -1)); + + + // check that language exists + if (!labels) { throw "Dateinput: invalid language: " + conf.lang; } + + // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser + if (input.attr("type") == 'date') { + original = input.clone(), def = original.wrap("").parent().html(), clone = $(def.replace(/type/i, "type=text data-orig-type")); - - if (conf.value) clone.val(conf.value); // jquery 1.6.2 val(undefined) will clear val() - - input.replaceWith(clone); - input = clone; - } - - input.addClass(css.input); - - var fire = input.add(self); - - // construct layout - if (!root.length) { - - // root - root = $('') - .hide().css({position: 'absolute'}).attr("id", css.root); - - // elements - root.children() - .eq(0).attr("id", css.head).end() - .eq(1).attr("id", css.body).children() - .eq(0).attr("id", css.days).end() - .eq(1).attr("id", css.weeks).end().end().end() - .find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next); - - // title - title = root.find("#" + css.head).find("div").attr("id", css.title); - - // year & month selectors - if (conf.selectors) { - var monthSelector = $("").attr("id", css.month), - yearSelector = $("").attr("id", css.year); - title.html(monthSelector.add(yearSelector)); - } - - // day titles - var days = root.find("#" + css.days); - - // days of the week - for (var d = 0; d < 7; d++) { - days.append($("").text(labels.shortDays[(d + conf.firstDay) % 7])); - } - - $("body").append(root); - } - - - // trigger icon - if (conf.trigger) { - trigger = $("").attr("href", "#").addClass(css.trigger).click(function(e) { - conf.toggle ? self.toggle() : self.show(); - return e.preventDefault(); - }).insertAfter(input); - } - - - // layout elements - var weeks = root.find("#" + css.weeks); - yearSelector = root.find("#" + css.year); - monthSelector = root.find("#" + css.month); - - + + if (conf.value) clone.val(conf.value); // jquery 1.6.2 val(undefined) will clear val() + + input.replaceWith(clone); + input = clone; + } + + input.addClass(css.input); + + var fire = input.add(self); + + // construct layout + if (!root.length) { + + // root + root = $('') + .hide().css({position: 'absolute'}).attr("id", css.root); + + // elements + root.children() + .eq(0).attr("id", css.head).end() + .eq(1).attr("id", css.body).children() + .eq(0).attr("id", css.days).end() + .eq(1).attr("id", css.weeks).end().end().end() + .find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next); + + // title + title = root.find("#" + css.head).find("div").attr("id", css.title); + + // year & month selectors + if (conf.selectors) { + monthSelector = $("").attr("id", css.month); + yearSelector = $("").attr("id", css.year); + title.html(monthSelector.add(yearSelector)); + } + + // day titles + var days = root.find("#" + css.days); + + // days of the week + for (var d = 0; d < 7; d++) { + days.append($("").text(labels.shortDays[(d + conf.firstDay) % 7])); + } + + $("body").append(root); + } + + + // trigger icon + if (conf.trigger) { + trigger = $("").attr("href", "#").addClass(css.trigger).click(function(e) { + conf.toggle ? self.toggle() : self.show(); + return e.preventDefault(); + }).insertAfter(input); + } + + + // layout elements + var weeks = root.find("#" + css.weeks); + yearSelector = root.find("#" + css.year); + monthSelector = root.find("#" + css.month); + + //{{{ pick - - function select(date, conf, e) { - // If it is readonly, then we'll just close the calendar - if (input.attr('readonly')) { - self.hide(e); - return; - } - - // current value - value = date; - currYear = date.getFullYear(); - currMonth = date.getMonth(); - currDay = date.getDate(); - - e || (e = $.Event("api")); - - // focus the input after selection (doesn't work in IE) - if (e.type == "click" && !/msie/.test(navigator.userAgent.toLowerCase())) { - input.focus(); - } - - // beforeChange - e.type = "beforeChange"; - - fire.trigger(e, [date]); - if (e.isDefaultPrevented()) { return; } - - // formatting - input.val(format(conf.formatter, date, conf.format, conf.lang)); - + + function select(date, conf, e) { + // If it is readonly, then we'll just close the calendar + if (input.attr('readonly')) { + self.hide(e); + return; + } + + // current value + value = date; + currYear = date.getFullYear(); + currMonth = date.getMonth(); + currDay = date.getDate(); + + e || (e = $.Event("api")); + + // focus the input after selection (doesn't work in IE) + if (e.type == "click" && !/msie/.test(navigator.userAgent.toLowerCase())) { + input.focus(); + } + + // beforeChange + e.type = "beforeChange"; + + fire.trigger(e, [date]); + if (e.isDefaultPrevented()) { return; } + + // formatting + input.val(format(conf.formatter, date, conf.format, conf.lang)); + // change - e.type = "change"; - fire.trigger(e); - - // store value into input - input.data("date", date); - - self.hide(e); - } + e.type = "change"; + fire.trigger(e); + + // store value into input + input.data("date", date); + + self.hide(e); + } //}}} - - + + //{{{ onShow - function onShow(ev) { - - ev.type = "onShow"; - fire.trigger(ev); - - $(document).on("keydown.d", function(e) { - - if (e.ctrlKey) { return true; } - var key = e.keyCode; - - // backspace or delete clears the value - if (key == 8 || key == 46) { - input.val(""); - return self.hide(e); - } - - // esc or tab key exits - if (key == 27 || key == 9) { return self.hide(e); } - - if ($(KEYS).index(key) >= 0) { - - if (!opened) { - self.show(e); - return e.preventDefault(); - } - - var days = $("#" + css.weeks + " a"), - el = $("." + css.focus), - index = days.index(el); - - el.removeClass(css.focus); - - if (key == 74 || key == 40) { index += 7; } - else if (key == 75 || key == 38) { index -= 7; } - else if (key == 76 || key == 39) { index += 1; } - else if (key == 72 || key == 37) { index -= 1; } - - - if (index > 41) { - self.addMonth(); - el = $("#" + css.weeks + " a:eq(" + (index-42) + ")"); - } else if (index < 0) { - self.addMonth(-1); - el = $("#" + css.weeks + " a:eq(" + (index+42) + ")"); - } else { - el = days.eq(index); - } - - el.addClass(css.focus); - return e.preventDefault(); - - } - - // pageUp / pageDown - if (key == 34) { return self.addMonth(); } - if (key == 33) { return self.addMonth(-1); } - - // home - if (key == 36) { return self.today(); } - - // enter - if (key == 13) { - if (!$(e.target).is("select")) { - $("." + css.focus).click(); - } - } - - return $([16, 17, 18, 9]).index(key) >= 0; - }); - - - // click outside dateinput - $(document).on("click.d", function(e) { - var el = e.target; - - if (!(el.id == css.root || $(el).parents("#" + css.root).length) && el != input[0] && (!trigger || el != trigger[0])) { - self.hide(e); - } - - }); - } + function onShow(ev) { + + ev.type = "onShow"; + fire.trigger(ev); + + $(document).on("keydown.d", function(e) { + + if (e.ctrlKey) { return true; } + var key = e.keyCode; + + // backspace or delete clears the value + if (key == 8 || key == 46) { + input.val(""); + return self.hide(e); + } + + // esc or tab key exits + if (key == 27 || key == 9) { return self.hide(e); } + + if ($(KEYS).index(key) >= 0) { + + if (!opened) { + self.show(e); + return e.preventDefault(); + } + + var days = $("#" + css.weeks + " a"), + el = $("." + css.focus), + index = days.index(el); + + el.removeClass(css.focus); + + if (key == 74 || key == 40) { index += 7; } + else if (key == 75 || key == 38) { index -= 7; } + else if (key == 76 || key == 39) { index += 1; } + else if (key == 72 || key == 37) { index -= 1; } + + + if (index > 41) { + self.addMonth(); + el = $("#" + css.weeks + " a:eq(" + (index-42) + ")"); + } else if (index < 0) { + self.addMonth(-1); + el = $("#" + css.weeks + " a:eq(" + (index+42) + ")"); + } else { + el = days.eq(index); + } + + el.addClass(css.focus); + return e.preventDefault(); + + } + + // pageUp / pageDown + if (key == 34) { return self.addMonth(); } + if (key == 33) { return self.addMonth(-1); } + + // home + if (key == 36) { return self.today(); } + + // enter + if (key == 13) { + if (!$(e.target).is("select")) { + $("." + css.focus).click(); + } + } + + return $([16, 17, 18, 9]).index(key) >= 0; + }); + + + // click outside dateinput + $(document).on("click.d", function(e) { + var el = e.target; + + if (!(el.id == css.root || $(el).parents("#" + css.root).length) && el != input[0] && (!trigger || el != trigger[0])) { + self.hide(e); + } + + }); + } //}}} - $.extend(self, { - - - /** - * @public - * Show the calendar - */ - show: function(e) { - - if (input.attr("disabled") || opened) { return; } - - // onBeforeShow - e = e || $.Event(); - e.type = "onBeforeShow"; - fire.trigger(e); - if (e.isDefaultPrevented()) { return; } - - $.each(instances, function() { - this.hide(); - }); - - opened = true; - + $.extend(self, { + + + /** + * @public + * Show the calendar + */ + show: function(e) { + + if (input.attr("disabled") || opened) { return; } + + // onBeforeShow + e = e || $.Event(); + e.type = "onBeforeShow"; + fire.trigger(e); + if (e.isDefaultPrevented()) { return; } + + $.each(instances, function() { + this.hide(); + }); + + opened = true; + // month selector monthSelector.off("change").change(function() { self.setValue(integer(yearSelector.val()), integer($(this).val())); @@ -448,365 +449,365 @@ yearSelector.off("change").change(function() { self.setValue(integer($(this).val()), integer(monthSelector.val())); }); - - // prev / next month - pm = root.find("#" + css.prev).off("click").click(function(e) { - if (!pm.hasClass(css.disabled)) { - self.addMonth(-1); - } - return false; - }); - - nm = root.find("#" + css.next).off("click").click(function(e) { - if (!nm.hasClass(css.disabled)) { - self.addMonth(); - } - return false; - }); - - // set date - self.setValue(value); - - // show calendar - var pos = input.offset(); - - // iPad position fix - if (/iPad/i.test(navigator.userAgent)) { - pos.top -= $(window).scrollTop(); - } - - root.css({ - top: pos.top + input.outerHeight(true) + conf.offset[0], - left: pos.left + conf.offset[1] - }); - - if (conf.speed) { - root.show(conf.speed, function() { - onShow(e); - }); - } else { - root.show(); - onShow(e); - } - - return self; - }, + + // prev / next month + pm = root.find("#" + css.prev).off("click").click(function(e) { + if (!pm.hasClass(css.disabled)) { + self.addMonth(-1); + } + return false; + }); + + nm = root.find("#" + css.next).off("click").click(function(e) { + if (!nm.hasClass(css.disabled)) { + self.addMonth(); + } + return false; + }); + + // set date + self.setValue(value); + + // show calendar + var pos = input.offset(); + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + pos.top -= $(window).scrollTop(); + } + + root.css({ + top: pos.top + input.outerHeight(true) + conf.offset[0], + left: pos.left + conf.offset[1] + }); + + if (conf.speed) { + root.show(conf.speed, function() { + onShow(e); + }); + } else { + root.show(); + onShow(e); + } + + return self; + }, /** * @public * * Set the value of the dateinput */ - setValue: function(year, month, day) { - - var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day == undefined || isNaN(day) ? 1 : day)) : - year || value; - - if (date < min) { date = min; } - else if (date > max) { date = max; } - - // date given as ISO string - if (typeof year == 'string') { date = parseDate(year); } - - year = date.getFullYear(); - month = date.getMonth(); - day = date.getDate(); - - - // roll year & month - if (month == -1) { - month = 11; - year--; - } else if (month == 12) { - month = 0; - year++; - } - - if (!opened) { - select(date, conf); - return self; - } - - currMonth = month; - currYear = year; - currDay = day; - - // variables - var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(), - days = dayAm(year, month), - prevDays = dayAm(year, month - 1), - week; - - // selectors - if (conf.selectors) { - - // month selector - monthSelector.empty(); - $.each(labels.months, function(i, m) { - if (min < new Date(year, i + 1, 1) && max > new Date(year, i, 0)) { - monthSelector.append($("").html(m).attr("value", i)); - } - }); - - // year selector - yearSelector.empty(); - var yearNow = now.getFullYear(); - - for (var i = yearNow + conf.yearRange[0]; i < yearNow + conf.yearRange[1]; i++) { - if (min < new Date(i + 1, 0, 1) && max > new Date(i, 0, 0)) { - yearSelector.append($("").text(i)); - } - } - - monthSelector.val(month); - yearSelector.val(year); - - // title - } else { - title.html(labels.months[month] + " " + year); - } - - // populate weeks - weeks.empty(); - pm.add(nm).removeClass(css.disabled); - - // !begin === "sunday" - for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) { - - a = $(""); - - if (j % 7 === 0) { - week = $("").addClass(css.week); - weeks.append(week); - } - - if (j < begin) { - a.addClass(css.off); - num = prevDays - begin + j + 1; - date = new Date(year, month-1, num); - - } else if (j >= begin + days) { - a.addClass(css.off); - num = j - days - begin + 1; - date = new Date(year, month+1, num); - - } else { - num = j - begin + 1; - date = new Date(year, month, num); - - // current date - if (isSameDay(value, date)) { - a.attr("id", css.current).addClass(css.focus); - - // today - } else if (isSameDay(now, date)) { - a.attr("id", css.today); - } - } - - // disabled - if (min && date < min) { - a.add(pm).addClass(css.disabled); - } - - if (max && date > max) { - a.add(nm).addClass(css.disabled); - } - - a.attr("href", "#" + num).text(num).data("date", date); - - week.append(a); - } - - // date picking - weeks.find("a").click(function(e) { - var el = $(this); - if (!el.hasClass(css.disabled)) { - $("#" + css.current).removeAttr("id"); - el.attr("id", css.current); - select(el.data("date"), conf, e); - } - return false; - }); - - // sunday - if (css.sunday) { - weeks.find("." + css.week).each(function() { - var beg = conf.firstDay ? 7 - conf.firstDay : 0; - $(this).children().slice(beg, beg + 1).addClass(css.sunday); - }); - } - - return self; - }, - //}}} - - setMin: function(val, fit) { - min = parseDate(val); - if (fit && value < min) { self.setValue(min); } - return self; - }, - - setMax: function(val, fit) { - max = parseDate(val); - if (fit && value > max) { self.setValue(max); } - return self; - }, - - today: function() { - return self.setValue(now); - }, - - addDay: function(amount) { - return this.setValue(currYear, currMonth, currDay + (amount || 1)); - }, - - addMonth: function(amount) { - var targetMonth = currMonth + (amount || 1), + setValue: function(year, month, day) { + + var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day === undefined || isNaN(day) ? 1 : day)) : + year || value; + + if (date < min) { date = min; } + else if (date > max) { date = max; } + + // date given as ISO string + if (typeof year == 'string') { date = parseDate(year); } + + year = date.getFullYear(); + month = date.getMonth(); + day = date.getDate(); + + + // roll year & month + if (month == -1) { + month = 11; + year--; + } else if (month == 12) { + month = 0; + year++; + } + + if (!opened) { + select(date, conf); + return self; + } + + currMonth = month; + currYear = year; + currDay = day; + + // variables + var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(), + days = dayAm(year, month), + prevDays = dayAm(year, month - 1), + week; + + // selectors + if (conf.selectors) { + + // month selector + monthSelector.empty(); + $.each(labels.months, function(i, m) { + if (min < new Date(year, i + 1, 1) && max > new Date(year, i, 0)) { + monthSelector.append($("").html(m).attr("value", i)); + } + }); + + // year selector + yearSelector.empty(); + var yearNow = now.getFullYear(); + + for (var i = yearNow + conf.yearRange[0]; i < yearNow + conf.yearRange[1]; i++) { + if (min < new Date(i + 1, 0, 1) && max > new Date(i, 0, 0)) { + yearSelector.append($("").text(i)); + } + } + + monthSelector.val(month); + yearSelector.val(year); + + // title + } else { + title.html(labels.months[month] + " " + year); + } + + // populate weeks + weeks.empty(); + pm.add(nm).removeClass(css.disabled); + + // !begin === "sunday" + for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) { + + a = $(""); + + if (j % 7 === 0) { + week = $("").addClass(css.week); + weeks.append(week); + } + + if (j < begin) { + a.addClass(css.off); + num = prevDays - begin + j + 1; + date = new Date(year, month-1, num); + + } else if (j >= begin + days) { + a.addClass(css.off); + num = j - days - begin + 1; + date = new Date(year, month+1, num); + + } else { + num = j - begin + 1; + date = new Date(year, month, num); + + // current date + if (isSameDay(value, date)) { + a.attr("id", css.current).addClass(css.focus); + + // today + } else if (isSameDay(now, date)) { + a.attr("id", css.today); + } + } + + // disabled + if (min && date < min) { + a.add(pm).addClass(css.disabled); + } + + if (max && date > max) { + a.add(nm).addClass(css.disabled); + } + + a.attr("href", "#" + num).text(num).data("date", date); + + week.append(a); + } + + // date picking + weeks.find("a").click(function(e) { + var el = $(this); + if (!el.hasClass(css.disabled)) { + $("#" + css.current).removeAttr("id"); + el.attr("id", css.current); + select(el.data("date"), conf, e); + } + return false; + }); + + // sunday + if (css.sunday) { + weeks.find("." + css.week).each(function() { + var beg = conf.firstDay ? 7 - conf.firstDay : 0; + $(this).children().slice(beg, beg + 1).addClass(css.sunday); + }); + } + + return self; + }, + //}}} + + setMin: function(val, fit) { + min = parseDate(val); + if (fit && value < min) { self.setValue(min); } + return self; + }, + + setMax: function(val, fit) { + max = parseDate(val); + if (fit && value > max) { self.setValue(max); } + return self; + }, + + today: function() { + return self.setValue(now); + }, + + addDay: function(amount) { + return this.setValue(currYear, currMonth, currDay + (amount || 1)); + }, + + addMonth: function(amount) { + var targetMonth = currMonth + (amount || 1), daysInTargetMonth = dayAm(currYear, targetMonth), targetDay = currDay <= daysInTargetMonth ? currDay : daysInTargetMonth; - + return this.setValue(currYear, targetMonth, targetDay); - }, - - addYear: function(amount) { - return this.setValue(currYear + (amount || 1), currMonth, currDay); - }, - - destroy: function() { - input.add(document).off("click.d keydown.d"); - root.add(trigger).remove(); - input.removeData("dateinput").removeClass(css.input); - if (original) { input.replaceWith(original); } - }, - - hide: function(e) { - - if (opened) { - - // onHide - e = $.Event(); - e.type = "onHide"; - fire.trigger(e); - - // cancelled ? - if (e.isDefaultPrevented()) { return; } - - $(document).off("click.d keydown.d"); - - // do the hide - root.hide(); - opened = false; - } - - return self; - }, - - toggle: function(){ - return self.isOpen() ? self.hide() : self.show(); - }, - - getConf: function() { - return conf; - }, - - getInput: function() { - return input; - }, - - getCalendar: function() { - return root; - }, - - getValue: function(dateFormat) { - return dateFormat ? format(conf.formatter, value, dateFormat, conf.lang) : value; - }, - - isOpen: function() { - return opened; - } - - }); - - // callbacks - $.each(['onBeforeShow','onShow','change','onHide'], function(i, name) { - - // configuration - if ($.isFunction(conf[name])) { - $(self).on(name, conf[name]); - } - - // API methods - self[name] = function(fn) { - if (fn) { $(self).on(name, fn); } - return self; - }; - }); - - if (!conf.editable) { - - // show dateinput & assign keyboard shortcuts - input.on("focus.d click.d", self.show).keydown(function(e) { - - var key = e.keyCode; - - // open dateinput with navigation keyw - if (!opened && $(KEYS).index(key) >= 0) { - self.show(e); - return e.preventDefault(); - - // clear value on backspace or delete - } else if (key == 8 || key == 46) { - input.val(""); - } - - // allow tab - return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault(); - - }); - } - - // initial value - if (parseDate(input.val())) { - select(value, conf); - } - - } - - $.expr[':'].date = function(el) { - var type = el.getAttribute("type"); - return type && type == 'date' || !!$(el).data("dateinput"); - }; - - - $.fn.dateinput = function(conf) { - - // already instantiated - if (this.data("dateinput")) { return this; } - - // configuration - conf = $.extend(true, {}, tool.conf, conf); - - // CSS prefix - $.each(conf.css, function(key, val) { - if (!val && key != 'prefix') { - conf.css[key] = (conf.css.prefix || '') + (val || key); - } - }); - - var els; - - this.each(function() { - var el = new Dateinput($(this), conf); - instances.push(el); - var input = el.getInput().data("dateinput", el); - els = els ? els.add(input) : input; - }); - - return els ? els : this; - }; - - + }, + + addYear: function(amount) { + return this.setValue(currYear + (amount || 1), currMonth, currDay); + }, + + destroy: function() { + input.add(document).off("click.d keydown.d"); + root.add(trigger).remove(); + input.removeData("dateinput").removeClass(css.input); + if (original) { input.replaceWith(original); } + }, + + hide: function(e) { + + if (opened) { + + // onHide + e = $.Event(); + e.type = "onHide"; + fire.trigger(e); + + // cancelled ? + if (e.isDefaultPrevented()) { return; } + + $(document).off("click.d keydown.d"); + + // do the hide + root.hide(); + opened = false; + } + + return self; + }, + + toggle: function(){ + return self.isOpen() ? self.hide() : self.show(); + }, + + getConf: function() { + return conf; + }, + + getInput: function() { + return input; + }, + + getCalendar: function() { + return root; + }, + + getValue: function(dateFormat) { + return dateFormat ? format(conf.formatter, value, dateFormat, conf.lang) : value; + }, + + isOpen: function() { + return opened; + } + + }); + + // callbacks + $.each(['onBeforeShow','onShow','change','onHide'], function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API methods + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + if (!conf.editable) { + + // show dateinput & assign keyboard shortcuts + input.on("focus.d click.d", self.show).keydown(function(e) { + + var key = e.keyCode; + + // open dateinput with navigation keyw + if (!opened && $(KEYS).index(key) >= 0) { + self.show(e); + return e.preventDefault(); + + // clear value on backspace or delete + } else if (key == 8 || key == 46) { + input.val(""); + } + + // allow tab + return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault(); + + }); + } + + // initial value + if (parseDate(input.val())) { + select(value, conf); + } + + } + + $.expr[':'].date = function(el) { + var type = el.getAttribute("type"); + return type && type == 'date' || !!$(el).data("dateinput"); + }; + + + $.fn.dateinput = function(conf) { + + // already instantiated + if (this.data("dateinput")) { return this; } + + // configuration + conf = $.extend(true, {}, tool.conf, conf); + + // CSS prefix + $.each(conf.css, function(key, val) { + if (!val && key != 'prefix') { + conf.css[key] = (conf.css.prefix || '') + (val || key); + } + }); + + var els; + + this.each(function() { + var el = new Dateinput($(this), conf); + instances.push(el); + var input = el.getInput().data("dateinput", el); + els = els ? els.add(input) : input; + }); + + return els ? els : this; + }; + + }) (jQuery); - - + + diff --git a/src/overlay/overlay.apple.js b/src/overlay/overlay.apple.js index fb0b669..52dcb38 100644 --- a/src/overlay/overlay.apple.js +++ b/src/overlay/overlay.apple.js @@ -1,155 +1,155 @@ /** - * @license - * jQuery Tools @VERSION / Overlay Apple effect. - * + * @license + * jQuery Tools @VERSION / Overlay Apple effect. + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/overlay/apple.html * * Since: July 2009 - * Date: @DATE + * Date: @DATE */ -(function($) { - - // version number - var t = $.tools.overlay, - w = $(window); - - // extend global configuragion with effect specific defaults - $.extend(t.conf, { - start: { - top: null, - left: null - }, - - fadeInSpeed: 'fast', - zIndex: 9999 - }); - - // utility function - function getPosition(el) { - var p = el.offset(); - return { - top: p.top + el.height() / 2, - left: p.left + el.width() / 2 - }; - } - -//{{{ load - - var loadEffect = function(pos, onLoad) { - - var overlay = this.getOverlay(), - conf = this.getConf(), - trigger = this.getTrigger(), - self = this, - oWidth = overlay.outerWidth({true}), - img = overlay.data("img"), - position = conf.fixed ? 'fixed' : 'absolute'; - - - // growing image is required. - if (!img) { - var bg = overlay.css("backgroundImage"); - - if (!bg) { - throw "background-image CSS property not set for overlay"; - } - - // url("bg.jpg") --> bg.jpg - bg = bg.slice(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, ""); - overlay.css("backgroundImage", "none"); - - img = $('Click here to download latest version
" : - "Download latest version from here
"); - - if (root.tagName == 'A') { - root.onclick = function() { - location.href = URL; - }; - } - } - - // onFail - if (opts.onFail) { - var ret = opts.onFail.call(this); - if (typeof ret == 'string') { root.innerHTML = ret; } - } - } - - // http://flowplayer.org/forum/8/18186#post-18593 - if (IE) { - window[opts.id] = document.getElementById(opts.id); - } - - // API methods for callback - extend(this, { - - getRoot: function() { - return root; - }, - - getOptions: function() { - return opts; - }, - - - getConf: function() { - return conf; - }, - - getApi: function() { - return root.firstChild; - } - - }); - } - - // setup jquery support - if (JQUERY) { - - // tools version number - jQuery.tools = jQuery.tools || {version: '@VERSION'}; - - jQuery.tools.flashembed = { - conf: GLOBAL_OPTS - }; - - jQuery.fn.flashembed = function(opts, conf) { - return this.each(function() { - jQuery(this).data("flashembed", flashembed(this, opts, conf)); - }); - }; - } + case 'function': + return '"function()"'; + + case 'object': + var str = []; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + str.push('"'+prop+'":'+ f.asString(obj[prop])); + } + } + return '{'+str.join(',')+'}'; + } + + // replace ' --> " and remove spaces + return String(obj).replace(/\s/g, " ").replace(/\'/g, "\""); + }, + + getHTML: function(opts, conf) { + + opts = extend({}, opts); + + /******* OBJECT tag and it's attributes *******/ + var html = '"; + + return html; + }, + + isSupported: function(ver) { + return VERSION[0] > ver[0] || VERSION[0] == ver[0] && VERSION[1] >= ver[1]; + } + + }); + + var VERSION = f.getVersion(); + + function Flash(root, opts, conf) { + + // version is ok + if (f.isSupported(opts.version)) { + root.innerHTML = f.getHTML(opts, conf); + + // express install + } else if (opts.expressInstall && f.isSupported([6, 65])) { + root.innerHTML = f.getHTML(extend(opts, {src: opts.expressInstall}), { + MMredirectURL: location.href, + MMplayerType: 'PlugIn', + MMdoctitle: document.title + }); + + } else { + + // fail #2.1 custom content inside container + if (!root.innerHTML.replace(/\s/g, '')) { + root.innerHTML = + "Click here to download latest version
" : + "Download latest version from here
"); + + if (root.tagName == 'A') { + root.onclick = function() { + location.href = URL; + }; + } + } + + // onFail + if (opts.onFail) { + var ret = opts.onFail.call(this); + if (typeof ret == 'string') { root.innerHTML = ret; } + } + } + + // http://flowplayer.org/forum/8/18186#post-18593 + if (IE) { + window[opts.id] = document.getElementById(opts.id); + } + + // API methods for callback + extend(this, { + + getRoot: function() { + return root; + }, + + getOptions: function() { + return opts; + }, + + + getConf: function() { + return conf; + }, + + getApi: function() { + return root.firstChild; + } + + }); + } + + // setup jquery support + if (JQUERY) { + + // tools version number + jQuery.tools = jQuery.tools || {version: '@VERSION'}; + + jQuery.tools.flashembed = { + conf: GLOBAL_OPTS + }; + + jQuery.fn.flashembed = function(opts, conf) { + return this.each(function() { + jQuery(this).data("flashembed", flashembed(this, opts, conf)); + }); + }; + } })(); diff --git a/src/toolbox/toolbox.history.js b/src/toolbox/toolbox.history.js index 49af9d7..d3309b8 100644 --- a/src/toolbox/toolbox.history.js +++ b/src/toolbox/toolbox.history.js @@ -1,108 +1,108 @@ /** - * @license + * @license * jQuery Tools @VERSION History "Back button for AJAX apps" - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/toolbox/history.html - * + * * Since: Mar 2010 - * Date: @DATE + * Date: @DATE */ (function($) { - - var hash, iframe, links, inited; - - $.tools = $.tools || {version: '@VERSION'}; - - $.tools.history = { - - init: function(els) { - - if (inited) { return; } - - // IE - if ($.browser.msie && $.browser.version < '8') { - - // create iframe that is constantly checked for hash changes - if (!iframe) { - iframe = $("").attr("src", "javascript:false;").hide().get(0); - $("body").append(iframe); - - setInterval(function() { - var idoc = iframe.contentWindow.document, - h = idoc.location.hash; - - if (hash !== h) { - $(window).trigger("hash", h); - } - }, 100); - - setIframeLocation(location.hash || '#'); - } - - - // other browsers scans for location.hash changes directly without iframe hack - } else { - setInterval(function() { - var h = location.hash; - if (h !== hash) { - $(window).trigger("hash", h); - } - }, 100); - } - - links = !links ? els : links.add(els); - - els.click(function(e) { - var href = $(this).attr("href"); - if (iframe) { setIframeLocation(href); } - - // handle non-anchor links - if (href.slice(0, 1) != "#") { - location.href = "#" + href; - return e.preventDefault(); - } - - }); - - inited = true; - } - }; - - - function setIframeLocation(h) { - if (h) { - var doc = iframe.contentWindow.document; - doc.open().close(); - doc.location.hash = h; - } - } - - // global histroy change listener - $(window).on("hash", function(e, h) { - if (h) { - links.filter(function() { - var href = $(this).attr("href"); - return href == h || href == h.replace("#", ""); - }).trigger("history", [h]); - } else { - links.eq(0).trigger("history", [h]); - } - - hash = h; - - }); - - - // jQuery plugin implementation - $.fn.history = function(fn) { - - $.tools.history.init(this); - - // return jQuery - return this.on("history", fn); - }; - -})(jQuery); + + var hash, iframe, links, inited; + + $.tools = $.tools || {version: '@VERSION'}; + + $.tools.history = { + + init: function(els) { + + if (inited) { return; } + + // IE + if ($.browser.msie && $.browser.version < '8') { + + // create iframe that is constantly checked for hash changes + if (!iframe) { + iframe = $("").attr("src", "javascript:false;").hide().get(0); + $("body").append(iframe); + + setInterval(function() { + var idoc = iframe.contentWindow.document, + h = idoc.location.hash; + + if (hash !== h) { + $(window).trigger("hash", h); + } + }, 100); + + setIframeLocation(location.hash || '#'); + } + + + // other browsers scans for location.hash changes directly without iframe hack + } else { + setInterval(function() { + var h = location.hash; + if (h !== hash) { + $(window).trigger("hash", h); + } + }, 100); + } + + links = !links ? els : links.add(els); + + els.click(function(e) { + var href = $(this).attr("href"); + if (iframe) { setIframeLocation(href); } + + // handle non-anchor links + if (href.slice(0, 1) != "#") { + location.href = "#" + href; + return e.preventDefault(); + } + + }); + + inited = true; + } + }; + + + function setIframeLocation(h) { + if (h) { + var doc = iframe.contentWindow.document; + doc.open().close(); + doc.location.hash = h; + } + } + + // global histroy change listener + $(window).on("hash", function(e, h) { + if (h) { + links.filter(function() { + var href = $(this).attr("href"); + return href == h || href == h.replace("#", ""); + }).trigger("history", [h]); + } else { + links.eq(0).trigger("history", [h]); + } + + hash = h; + + }); + + + // jQuery plugin implementation + $.fn.history = function(fn) { + + $.tools.history.init(this); + + // return jQuery + return this.on("history", fn); + }; + +})(jQuery); diff --git a/src/toolbox/toolbox.mousewheel.js b/src/toolbox/toolbox.mousewheel.js index aebac69..ffc93d7 100644 --- a/src/toolbox/toolbox.mousewheel.js +++ b/src/toolbox/toolbox.mousewheel.js @@ -1,65 +1,65 @@ /** - * @license + * @license * jQuery Tools @VERSION Mousewheel - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/toolbox/mousewheel.html - * - * based on jquery.event.wheel.js ~ rev 1 ~ + * + * based on jquery.event.wheel.js ~ rev 1 ~ * Copyright (c) 2008, Three Dub Media - * http://threedubmedia.com + * http://threedubmedia.com * * Since: Mar 2010 - * Date: @DATE + * Date: @DATE */ -(function($) { - - $.fn.mousewheel = function( fn ){ - return this[ fn ? "on" : "trigger" ]( "wheel", fn ); - }; +(function($) { + + $.fn.mousewheel = function( fn ){ + return this[ fn ? "on" : "trigger" ]( "wheel", fn ); + }; + + // special event config + $.event.special.wheel = { + setup: function() { + $.event.add( this, wheelEvents, wheelHandler, {} ); + }, + teardown: function(){ + $.event.remove( this, wheelEvents, wheelHandler ); + } + }; + + // events to bind ( browser sniffed... ) + var wheelEvents = !$.browser.mozilla ? "mousewheel" : // IE, opera, safari + "DOMMouseScroll"+( $.browser.version<"1.9" ? " mousemove" : "" ); // firefox + + // shared event handler + function wheelHandler( event ) { + + switch ( event.type ) { + + // FF2 has incorrect event positions + case "mousemove": + return $.extend( event.data, { // store the correct properties + clientX: event.clientX, clientY: event.clientY, + pageX: event.pageX, pageY: event.pageY + }); + + // firefox + case "DOMMouseScroll": + $.extend( event, event.data ); // fix event properties in FF2 + event.delta = -event.detail / 3; // normalize delta + break; - // special event config - $.event.special.wheel = { - setup: function() { - $.event.add( this, wheelEvents, wheelHandler, {} ); - }, - teardown: function(){ - $.event.remove( this, wheelEvents, wheelHandler ); - } - }; + // IE, opera, safari + case "mousewheel": + event.delta = event.wheelDelta / 120; + break; + } - // events to bind ( browser sniffed... ) - var wheelEvents = !$.browser.mozilla ? "mousewheel" : // IE, opera, safari - "DOMMouseScroll"+( $.browser.version<"1.9" ? " mousemove" : "" ); // firefox + event.type = "wheel"; // hijack the event + return $.event.handle.call( this, event, event.delta ); + } - // shared event handler - function wheelHandler( event ) { - - switch ( event.type ) { - - // FF2 has incorrect event positions - case "mousemove": - return $.extend( event.data, { // store the correct properties - clientX: event.clientX, clientY: event.clientY, - pageX: event.pageX, pageY: event.pageY - }); - - // firefox - case "DOMMouseScroll": - $.extend( event, event.data ); // fix event properties in FF2 - event.delta = -event.detail / 3; // normalize delta - break; - - // IE, opera, safari - case "mousewheel": - event.delta = event.wheelDelta / 120; - break; - } - - event.type = "wheel"; // hijack the event - return $.event.handle.call( this, event, event.delta ); - } - -})(jQuery); +})(jQuery); diff --git a/src/tooltip/tooltip.dynamic.js b/src/tooltip/tooltip.dynamic.js index b0bf6b4..4866a7e 100644 --- a/src/tooltip/tooltip.dynamic.js +++ b/src/tooltip/tooltip.dynamic.js @@ -1,154 +1,154 @@ /** - * @license + * @license * jQuery Tools @VERSION / Tooltip Dynamic Positioning - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/tooltip/dynamic.html * * Since: July 2009 - * Date: @DATE + * Date: @DATE */ -(function($) { - - // version number - var t = $.tools.tooltip; - - t.dynamic = { - conf: { - classNames: "top right bottom left" - } - }; - - /* - * See if element is on the viewport. Returns an boolean array specifying which - * edges are hidden. Edges are in following order: - * - * [top, right, bottom, left] - * - * For example following return value means that top and right edges are hidden - * - * [true, true, false, false] - * - */ - function getCropping(el) { - - var w = $(window); - var right = w.width() + w.scrollLeft(); - var bottom = w.height() + w.scrollTop(); - - return [ - el.offset().top <= w.scrollTop(), // top - right <= el.offset().left + el.width(), // right - bottom <= el.offset().top + el.height(), // bottom - w.scrollLeft() >= el.offset().left // left - ]; - } - - /* - Returns true if all edges of an element are on viewport. false if not - - @param crop the cropping array returned by getCropping function - */ - function isVisible(crop) { - var i = crop.length; - while (i--) { - if (crop[i]) { return false; } - } - return true; - } - - // dynamic plugin - $.fn.dynamic = function(conf) { - - if (typeof conf == 'number') { conf = {speed: conf}; } - - conf = $.extend({}, t.dynamic.conf, conf); - - var confOrigin = $.extend(true,{},conf), - cls = conf.classNames.split(/\s/), - orig, ret; - - this.each(function() { - - var api = $(this).tooltip().onBeforeShow(function(e, pos) { - - // get nessessary variables - var tip = this.getTip(), tipConf = this.getConf(); - - /* - We store the original configuration and use it to restore back to the original state. - */ - if (!orig) { - orig = [ - tipConf.position[0], - tipConf.position[1], - tipConf.offset[0], - tipConf.offset[1], - $.extend({}, tipConf) - ]; - } - - /* - display tip in it's default position and by setting visibility to hidden. - this way we can check whether it will be on the viewport - */ - $.extend(tipConf, orig[4]); - tipConf.position = [orig[0], orig[1]]; - tipConf.offset = [orig[2], orig[3]]; - - tip.css({ - visibility: 'hidden', - position: 'absolute', - top: pos.top, - left: pos.left - }).show(); - - var conf = $.extend(true,{},confOrigin), - - // now let's see for hidden edges - crop = getCropping(tip); - - // possibly alter the configuration - if (!isVisible(crop)) { - - // change the position and add class - if (crop[2]) { $.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); } - if (crop[3]) { $.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); } - if (crop[0]) { $.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); } - if (crop[1]) { $.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); } - - // vertical offset - if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; } - - // horizontal offset - if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; } - } - - tip.css({visibility: 'visible'}).hide(); - - }); - - // restore positioning as soon as possible - api.onBeforeShow(function() { - var c = this.getConf(), tip = this.getTip(); - setTimeout(function() { - c.position = [orig[0], orig[1]]; - c.offset = [orig[2], orig[3]]; - }, 0); - }); - - // remove custom class names and restore original effect - api.onHide(function() { - var tip = this.getTip(); - tip.removeClass(conf.classNames); - }); - - ret = api; - - }); - - return conf.api ? ret : this; - }; - +(function($) { + + // version number + var t = $.tools.tooltip; + + t.dynamic = { + conf: { + classNames: "top right bottom left" + } + }; + + /* + * See if element is on the viewport. Returns an boolean array specifying which + * edges are hidden. Edges are in following order: + * + * [top, right, bottom, left] + * + * For example following return value means that top and right edges are hidden + * + * [true, true, false, false] + * + */ + function getCropping(el) { + + var w = $(window); + var right = w.width() + w.scrollLeft(); + var bottom = w.height() + w.scrollTop(); + + return [ + el.offset().top <= w.scrollTop(), // top + right <= el.offset().left + el.width(), // right + bottom <= el.offset().top + el.height(), // bottom + w.scrollLeft() >= el.offset().left // left + ]; + } + + /* + Returns true if all edges of an element are on viewport. false if not + + @param crop the cropping array returned by getCropping function + */ + function isVisible(crop) { + var i = crop.length; + while (i--) { + if (crop[i]) { return false; } + } + return true; + } + + // dynamic plugin + $.fn.dynamic = function(conf) { + + if (typeof conf == 'number') { conf = {speed: conf}; } + + conf = $.extend({}, t.dynamic.conf, conf); + + var confOrigin = $.extend(true,{},conf), + cls = conf.classNames.split(/\s/), + orig, ret; + + this.each(function() { + + var api = $(this).tooltip().onBeforeShow(function(e, pos) { + + // get nessessary variables + var tip = this.getTip(), tipConf = this.getConf(); + + /* + We store the original configuration and use it to restore back to the original state. + */ + if (!orig) { + orig = [ + tipConf.position[0], + tipConf.position[1], + tipConf.offset[0], + tipConf.offset[1], + $.extend({}, tipConf) + ]; + } + + /* + display tip in it's default position and by setting visibility to hidden. + this way we can check whether it will be on the viewport + */ + $.extend(tipConf, orig[4]); + tipConf.position = [orig[0], orig[1]]; + tipConf.offset = [orig[2], orig[3]]; + + tip.css({ + visibility: 'hidden', + position: 'absolute', + top: pos.top, + left: pos.left + }).show(); + + var conf = $.extend(true,{},confOrigin), + + // now let's see for hidden edges + crop = getCropping(tip); + + // possibly alter the configuration + if (!isVisible(crop)) { + + // change the position and add class + if (crop[2]) { $.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); } + if (crop[3]) { $.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); } + if (crop[0]) { $.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); } + if (crop[1]) { $.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); } + + // vertical offset + if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; } + + // horizontal offset + if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; } + } + + tip.css({visibility: 'visible'}).hide(); + + }); + + // restore positioning as soon as possible + api.onBeforeShow(function() { + var c = this.getConf(), tip = this.getTip(); + setTimeout(function() { + c.position = [orig[0], orig[1]]; + c.offset = [orig[2], orig[3]]; + }, 0); + }); + + // remove custom class names and restore original effect + api.onHide(function() { + var tip = this.getTip(); + tip.removeClass(conf.classNames); + }); + + ret = api; + + }); + + return conf.api ? ret : this; + }; + }) (jQuery); diff --git a/src/tooltip/tooltip.js b/src/tooltip/tooltip.js index d888cf8..8fd27bc 100644 --- a/src/tooltip/tooltip.js +++ b/src/tooltip/tooltip.js @@ -1,358 +1,360 @@ /** - * @license + * @license * jQuery Tools @VERSION Tooltip - UI essentials - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/tooltip/ * * Since: November 2008 - * Date: @DATE + * Date: @DATE */ -(function($) { - // static constructs - $.tools = $.tools || {version: '@VERSION'}; - - $.tools.tooltip = { - - conf: { - - // default effect variables - effect: 'toggle', - fadeOutSpeed: "fast", - predelay: 0, - delay: 30, - opacity: 1, - tip: 0, +(function($) { + // static constructs + $.tools = $.tools || {version: '@VERSION'}; + + $.tools.tooltip = { + + conf: { + + // default effect variables + effect: 'toggle', + fadeOutSpeed: "fast", + predelay: 0, + delay: 30, + opacity: 1, + tip: 0, fadeIE: false, // enables fade effect in IE - - // 'top', 'bottom', 'right', 'left', 'center' - position: ['top', 'center'], - offset: [0, 0], - relative: false, - cancelDefault: true, - - // type to event mapping - events: { - def: "mouseenter,mouseleave", - input: "focus,blur", - widget: "focus mouseenter,blur mouseleave", - tooltip: "mouseenter,mouseleave" - }, - - // 1.2 - layout: '', - tipClass: 'tooltip' - }, - - addEffect: function(name, loadFn, hideFn) { - effects[name] = [loadFn, hideFn]; - } - }; - - - var effects = { - toggle: [ - function(done) { - var conf = this.getConf(), tip = this.getTip(), o = conf.opacity; - if (o < 1) { tip.css({opacity: o}); } - tip.show(); - done.call(); - }, - - function(done) { - this.getTip().hide(); - done.call(); - } - ], - - fade: [ - function(done) { - var conf = this.getConf(); - if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { - this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done); - } - else { - this.getTip().show(); - done(); - } - }, - function(done) { - var conf = this.getConf(); - if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { - this.getTip().fadeOut(conf.fadeOutSpeed, done); - } - else { - this.getTip().hide(); - done(); - } - } - ] - }; - - - /* calculate tip position relative to the trigger */ - function getPosition(trigger, tip, conf) { - - - // get origin top/left position - var top = conf.relative ? trigger.position().top : trigger.offset().top, - left = conf.relative ? trigger.position().left : trigger.offset().left, - pos = conf.position[0]; - - top -= tip.outerHeight() - conf.offset[0]; - left += trigger.outerWidth() + conf.offset[1]; - - // iPad position fix - if (/iPad/i.test(navigator.userAgent)) { - top -= $(window).scrollTop(); - } - - // adjust Y - var height = tip.outerHeight() + trigger.outerHeight(); - if (pos == 'center') { top += height / 2; } - if (pos == 'bottom') { top += height; } - - - // adjust X - pos = conf.position[1]; - var width = tip.outerWidth() + trigger.outerWidth(); - if (pos == 'center') { left -= width / 2; } - if (pos == 'left') { left -= width; } - - return {top: top, left: left}; - } - - - - function Tooltip(trigger, conf) { - - var self = this, - fire = trigger.add(self), - tip, - timer = 0, - pretimer = 0, - title = trigger.attr("title"), - tipAttr = trigger.attr("data-tooltip"), - effect = effects[conf.effect], - shown, - - // get show/hide configuration - isInput = trigger.is(":input"), - isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"), - type = trigger.attr("type"), - evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def']; - - - // check that configuration is sane - if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; } - - evt = evt.split(/,\s*/); - if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; } - - - // trigger --> show - trigger.on(evt[0], function(e) { - - clearTimeout(timer); - if (conf.predelay) { - pretimer = setTimeout(function() { self.show(e); }, conf.predelay); - - } else { - self.show(e); - } - - // trigger --> hide - }).on(evt[1], function(e) { - clearTimeout(pretimer); - if (conf.delay) { - timer = setTimeout(function() { self.hide(e); }, conf.delay); - - } else { - self.hide(e); - } - - }); - - - // remove default title - if (title && conf.cancelDefault) { - trigger.removeAttr("title"); - trigger.data("title", title); - } - - $.extend(self, { - - show: function(e) { - - // tip not initialized yet - if (!tip) { - - // data-tooltip - if (tipAttr) { - tip = $(tipAttr); - - // single tip element for all - } else if (conf.tip) { - tip = $(conf.tip).eq(0); - - // autogenerated tooltip - } else if (title) { - tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body) - .hide().append(title); - - // manual tooltip - } else { - tip = trigger.find('.' + conf.tipClass); - if (!tip.length) { tip = trigger.next(); } - if (!tip.length) { tip = trigger.parent().next(); } - } - - if (!tip.length) { throw "Cannot find tooltip for " + trigger; } - } - - if (self.isShown()) { return self; } - - // stop previous animation - tip.stop(true, true); - - // get position - var pos = getPosition(trigger, tip, conf); - - // restore title for single tooltip element - if (conf.tip) { - tip.html(trigger.data("title")); - } - - // onBeforeShow - e = $.Event(); - e.type = "onBeforeShow"; - fire.trigger(e, [pos]); - if (e.isDefaultPrevented()) { return self; } - - - // onBeforeShow may have altered the configuration - pos = getPosition(trigger, tip, conf); - - // set position - tip.css({position:'absolute', top: pos.top, left: pos.left}); - - shown = true; - - // invoke effect - effect[0].call(self, function() { - e.type = "onShow"; - shown = 'full'; - fire.trigger(e); - }); - - - // tooltip events - var event = conf.events.tooltip.split(/,\s*/); - - if (!tip.data("__set")) { - - tip.off(event[0]).on(event[0], function() { - clearTimeout(timer); - clearTimeout(pretimer); - }); - - if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) { - tip.off(event[1]).on(event[1], function(e) { - - // being moved to the trigger element - if (e.relatedTarget != trigger[0]) { - trigger.trigger(evt[1].split(" ")[0]); - } - }); - } - - // bind agein for if same tip element - if (!conf.tip) tip.data("__set", true); - } - - return self; - }, - - hide: function(e) { - - if (!tip || !self.isShown()) { return self; } - - // onBeforeHide - e = $.Event(); - e.type = "onBeforeHide"; - fire.trigger(e); - if (e.isDefaultPrevented()) { return; } - - shown = false; - - effects[conf.effect][1].call(self, function() { - e.type = "onHide"; - fire.trigger(e); - }); - - return self; - }, - - isShown: function(fully) { - return fully ? shown == 'full' : shown; - }, - - getConf: function() { - return conf; - }, - - getTip: function() { - return tip; - }, - - getTrigger: function() { - return trigger; - } - - }); - - // callbacks - $.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) { - - // configuration - if ($.isFunction(conf[name])) { - $(self).on(name, conf[name]); - } - - // API - self[name] = function(fn) { - if (fn) { $(self).on(name, fn); } - return self; - }; - }); - - } - - - // jQuery plugin implementation - $.fn.tooltip = function(conf) { - - conf = $.extend(true, {}, $.tools.tooltip.conf, conf); - - // position can also be given as string - if (typeof conf.position == 'string') { - conf.position = conf.position.split(/,?\s/); - } - - // install tooltip for each entry in jQuery object - // that is not an existing instance - this.each(function() { - if ( $(this).data("tooltip")===null){ - api = new Tooltip($(this), conf); - $(this).data("tooltip", api); - }; - }); - - return conf.api ? api: this; - }; - + + // 'top', 'bottom', 'right', 'left', 'center' + position: ['top', 'center'], + offset: [0, 0], + relative: false, + cancelDefault: true, + + // type to event mapping + events: { + def: "mouseenter,mouseleave", + input: "focus,blur", + widget: "focus mouseenter,blur mouseleave", + tooltip: "mouseenter,mouseleave" + }, + + // 1.2 + layout: '', + tipClass: 'tooltip' + }, + + addEffect: function(name, loadFn, hideFn) { + effects[name] = [loadFn, hideFn]; + } + }; + + + var effects = { + toggle: [ + function(done) { + var conf = this.getConf(), tip = this.getTip(), o = conf.opacity; + if (o < 1) { tip.css({opacity: o}); } + tip.show(); + done.call(); + }, + + function(done) { + this.getTip().hide(); + done.call(); + } + ], + + fade: [ + function(done) { + var conf = this.getConf(); + if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { + this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done); + } + else { + this.getTip().show(); + done(); + } + }, + function(done) { + var conf = this.getConf(); + if (!/msie/.test(navigator.userAgent.toLowerCase()) || conf.fadeIE) { + this.getTip().fadeOut(conf.fadeOutSpeed, done); + } + else { + this.getTip().hide(); + done(); + } + } + ] + }; + + + /* calculate tip position relative to the trigger */ + function getPosition(trigger, tip, conf) { + + + // get origin top/left position + var top = conf.relative ? trigger.position().top : trigger.offset().top, + left = conf.relative ? trigger.position().left : trigger.offset().left, + pos = conf.position[0]; + + top -= tip.outerHeight() - conf.offset[0]; + left += trigger.outerWidth() + conf.offset[1]; + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + top -= $(window).scrollTop(); + } + + // adjust Y + var height = tip.outerHeight() + trigger.outerHeight(); + if (pos == 'center') { top += height / 2; } + if (pos == 'bottom') { top += height; } + + + // adjust X + pos = conf.position[1]; + var width = tip.outerWidth() + trigger.outerWidth(); + if (pos == 'center') { left -= width / 2; } + if (pos == 'left') { left -= width; } + + return {top: top, left: left}; + } + + + + function Tooltip(trigger, conf) { + + var self = this, + fire = trigger.add(self), + tip, + timer = 0, + pretimer = 0, + title = trigger.attr("title"), + tipAttr = trigger.attr("data-tooltip"), + effect = effects[conf.effect], + shown, + + // get show/hide configuration + isInput = trigger.is(":input"), + isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"), + type = trigger.attr("type"), + evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def']; + + + // check that configuration is sane + if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; } + + evt = evt.split(/,\s*/); + if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; } + + + // trigger --> show + trigger.on(evt[0], function(e) { + + clearTimeout(timer); + if (conf.predelay) { + pretimer = setTimeout(function() { self.show(e); }, conf.predelay); + + } else { + self.show(e); + } + + // trigger --> hide + }).on(evt[1], function(e) { + clearTimeout(pretimer); + if (conf.delay) { + timer = setTimeout(function() { self.hide(e); }, conf.delay); + + } else { + self.hide(e); + } + + }); + + + // remove default title + if (title && conf.cancelDefault) { + trigger.removeAttr("title"); + trigger.data("title", title); + } + + $.extend(self, { + + show: function(e) { + + // tip not initialized yet + if (!tip) { + + // data-tooltip + if (tipAttr) { + tip = $(tipAttr); + + // single tip element for all + } else if (conf.tip) { + tip = $(conf.tip).eq(0); + + // autogenerated tooltip + } else if (title) { + tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body) + .hide().append(title); + + // manual tooltip + } else { + tip = trigger.find('.' + conf.tipClass); + if (!tip.length) { tip = trigger.next(); } + if (!tip.length) { tip = trigger.parent().next(); } + } + + if (!tip.length) { throw "Cannot find tooltip for " + trigger; } + } + + if (self.isShown()) { return self; } + + // stop previous animation + tip.stop(true, true); + + // get position + var pos = getPosition(trigger, tip, conf); + + // restore title for single tooltip element + if (conf.tip) { + tip.html(trigger.data("title")); + } + + // onBeforeShow + e = $.Event(); + e.type = "onBeforeShow"; + fire.trigger(e, [pos]); + if (e.isDefaultPrevented()) { return self; } + + + // onBeforeShow may have altered the configuration + pos = getPosition(trigger, tip, conf); + + // set position + tip.css({position:'absolute', top: pos.top, left: pos.left}); + + shown = true; + + // invoke effect + effect[0].call(self, function() { + e.type = "onShow"; + shown = 'full'; + fire.trigger(e); + }); + + + // tooltip events + var event = conf.events.tooltip.split(/,\s*/); + + if (!tip.data("__set")) { + + tip.off(event[0]).on(event[0], function() { + clearTimeout(timer); + clearTimeout(pretimer); + }); + + if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) { + tip.off(event[1]).on(event[1], function(e) { + + // being moved to the trigger element + if (e.relatedTarget != trigger[0]) { + trigger.trigger(evt[1].split(" ")[0]); + } + }); + } + + // bind agein for if same tip element + if (!conf.tip) { + tip.data("__set", true); + } + } + + return self; + }, + + hide: function(e) { + + if (!tip || !self.isShown()) { return self; } + + // onBeforeHide + e = $.Event(); + e.type = "onBeforeHide"; + fire.trigger(e); + if (e.isDefaultPrevented()) { return; } + + shown = false; + + effects[conf.effect][1].call(self, function() { + e.type = "onHide"; + fire.trigger(e); + }); + + return self; + }, + + isShown: function(fully) { + return fully ? shown == 'full' : shown; + }, + + getConf: function() { + return conf; + }, + + getTip: function() { + return tip; + }, + + getTrigger: function() { + return trigger; + } + + }); + + // callbacks + $.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + } + + + // jQuery plugin implementation + $.fn.tooltip = function(conf) { + var api; + conf = $.extend(true, {}, $.tools.tooltip.conf, conf); + + // position can also be given as string + if (typeof conf.position == 'string') { + conf.position = conf.position.split(/,?\s/); + } + + // install tooltip for each entry in jQuery object + // that is not an existing instance + this.each(function() { + if ( $(this).data("tooltip")===null){ + api = new Tooltip($(this), conf); + $(this).data("tooltip", api); + } + }); + + return conf.api ? api: this; + }; + }) (jQuery); - + diff --git a/src/tooltip/tooltip.slide.js b/src/tooltip/tooltip.slide.js index eac5057..38322d2 100644 --- a/src/tooltip/tooltip.slide.js +++ b/src/tooltip/tooltip.slide.js @@ -1,78 +1,78 @@ /** - * @license + * @license * jQuery Tools @VERSION / Tooltip Slide Effect - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/tooltip/slide.html * * Since: September 2009 - * Date: @DATE + * Date: @DATE */ -(function($) { +(function($) { + + // version number + var t = $.tools.tooltip; + + // extend global configuragion with effect specific defaults + $.extend(t.conf, { + direction: 'up', // down, left, right + bounce: false, + slideOffset: 10, + slideInSpeed: 200, + slideOutSpeed: 200, + slideFade: !/msie/.test(navigator.userAgent.toLowerCase()) + }); + + // directions for slide effect + var dirs = { + up: ['-', 'top'], + down: ['+', 'top'], + left: ['-', 'left'], + right: ['+', 'left'] + }; + + /* default effect: "slide" */ + t.addEffect("slide", + + // show effect + function(done) { + + // variables + var conf = this.getConf(), + tip = this.getTip(), + params = conf.slideFade ? {opacity: conf.opacity} : {}, + dir = dirs[conf.direction] || dirs.up; + + // direction + params[dir[1]] = dir[0] +'='+ conf.slideOffset; + + // perform animation + if (conf.slideFade) { tip.css({opacity:0}); } + tip.show().animate(params, conf.slideInSpeed, done); + }, + + // hide effect + function(done) { + + // variables + var conf = this.getConf(), + offset = conf.slideOffset, + params = conf.slideFade ? {opacity: 0} : {}, + dir = dirs[conf.direction] || dirs.up; + + // direction + var sign = "" + dir[0]; + if (conf.bounce) { sign = sign == '+' ? '-' : '+'; } + params[dir[1]] = sign +'='+ offset; - // version number - var t = $.tools.tooltip; - - // extend global configuragion with effect specific defaults - $.extend(t.conf, { - direction: 'up', // down, left, right - bounce: false, - slideOffset: 10, - slideInSpeed: 200, - slideOutSpeed: 200, - slideFade: !/msie/.test(navigator.userAgent.toLowerCase()) - }); - - // directions for slide effect - var dirs = { - up: ['-', 'top'], - down: ['+', 'top'], - left: ['-', 'left'], - right: ['+', 'left'] - }; - - /* default effect: "slide" */ - t.addEffect("slide", - - // show effect - function(done) { + // perform animation + this.getTip().animate(params, conf.slideOutSpeed, function() { + $(this).hide(); + done.call(); + }); + } + ); - // variables - var conf = this.getConf(), - tip = this.getTip(), - params = conf.slideFade ? {opacity: conf.opacity} : {}, - dir = dirs[conf.direction] || dirs.up; +})(jQuery); - // direction - params[dir[1]] = dir[0] +'='+ conf.slideOffset; - - // perform animation - if (conf.slideFade) { tip.css({opacity:0}); } - tip.show().animate(params, conf.slideInSpeed, done); - }, - - // hide effect - function(done) { - - // variables - var conf = this.getConf(), - offset = conf.slideOffset, - params = conf.slideFade ? {opacity: 0} : {}, - dir = dirs[conf.direction] || dirs.up; - - // direction - var sign = "" + dir[0]; - if (conf.bounce) { sign = sign == '+' ? '-' : '+'; } - params[dir[1]] = sign +'='+ offset; - - // perform animation - this.getTip().animate(params, conf.slideOutSpeed, function() { - $(this).hide(); - done.call(); - }); - } - ); - -})(jQuery); - diff --git a/src/validator/validator.js b/src/validator/validator.js index 94ab9a0..45ebdec 100644 --- a/src/validator/validator.js +++ b/src/validator/validator.js @@ -1,623 +1,623 @@ /** - * @license + * @license * jQuery Tools Validator @VERSION - HTML5 is here. Now use it. - * + * * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. - * + * * http://flowplayer.org/tools/form/validator/ - * + * * Since: Mar 2010 - * Date: @DATE + * Date: @DATE */ -/*jslint evil: true */ -(function($) { - - $.tools = $.tools || {version: '@VERSION'}; - - // globals - var typeRe = /\[type=([a-z]+)\]/, - numRe = /^-?[0-9]*(\.[0-9]+)?$/, - dateInput = $.tools.dateinput, - - // http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/ - emailRe = /^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i, - urlRe = /^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i, - v; - - v = $.tools.validator = { - - conf: { - grouped: false, // show all error messages at once inside the container - effect: 'default', // show/hide effect for error message. only 'default' is built-in - errorClass: 'invalid', // input field class name in case of validation error - - // when to check for validity? - inputEvent: null, // change, blur, keyup, null - errorInputEvent: 'keyup', // change, blur, keyup, null - formEvent: 'submit', // submit, null - - lang: 'en', // default language for error messages - message: '', - messageAttr: 'data-message', // name of the attribute for overridden error message - messageClass: 'error', // error message element's class name - offset: [0, 0], - position: 'center right', - singleError: false, // validate all inputs at once - speed: 'normal' // message's fade-in speed - }, - - - /* The Error Messages */ - messages: { - "*": { en: "Please correct this value" } - }, - - localize: function(lang, messages) { - $.each(messages, function(key, msg) { - v.messages[key] = v.messages[key] || {}; - v.messages[key][lang] = msg; - }); - }, - - localizeFn: function(key, messages) { - v.messages[key] = v.messages[key] || {}; - $.extend(v.messages[key], messages); - }, - - /** - * Adds a new validator - */ - fn: function(matcher, msg, fn) { - - // no message supplied - if ($.isFunction(msg)) { - fn = msg; - - // message(s) on second argument - } else { - if (typeof msg == 'string') { msg = {en: msg}; } - this.messages[matcher.key || matcher] = msg; - } - - // check for "[type=xxx]" (not supported by jQuery) - var test = typeRe.exec(matcher); - if (test) { matcher = isType(test[1]); } - - // add validator to the arsenal - fns.push([matcher, fn]); - }, - - /* Add new show/hide effect */ - addEffect: function(name, showFn, closeFn) { - effects[name] = [showFn, closeFn]; - } - - }; - - /* calculate error message position relative to the input */ - function getPosition(trigger, el, conf) { - - // Get the first element in the selector set - el = $(el).first() || el; - - // get origin top/left position - var top = trigger.offset().top, - left = trigger.offset().left, - pos = conf.position.split(/,?\s+/), - y = pos[0], - x = pos[1]; - - top -= el.outerHeight() - conf.offset[0]; - left += trigger.outerWidth() + conf.offset[1]; - - - // iPad position fix - if (/iPad/i.test(navigator.userAgent)) { - top -= $(window).scrollTop(); - } - - // adjust Y - var height = el.outerHeight() + trigger.outerHeight(); - if (y == 'center') { top += height / 2; } - if (y == 'bottom') { top += height; } - - // adjust X - var width = trigger.outerWidth(); - if (x == 'center') { left -= (width + el.outerWidth()) / 2; } - if (x == 'left') { left -= width; } - - return {top: top, left: left}; - } - - - - // $.is("[type=xxx]") or $.filter("[type=xxx]") not working in jQuery 1.3.2 or 1.4.2 - function isType(type) { - function fn() { - return this.getAttribute("type") == type; - } - fn.key = "[type=\"" + type + "\"]"; - return fn; - } - - - var fns = [], effects = { - - 'default' : [ - - // show errors function - function(errs) { - - var conf = this.getConf(); - - // loop errors - $.each(errs, function(i, err) { - - // add error class - var input = err.input; - input.addClass(conf.errorClass); - - // get handle to the error container - var msg = input.data("msg.el"); - - // create it if not present - if (!msg) { - msg = $(conf.message).addClass(conf.messageClass).appendTo(document.body); - input.data("msg.el", msg); - } - - // clear the container - msg.css({visibility: 'hidden'}).find("p").remove(); - - // populate messages - $.each(err.messages, function(i, m) { - $("").html(m).appendTo(msg); - }); - - // make sure the width is not full body width so it can be positioned correctly - if (msg.outerWidth() == msg.parent().width()) { - msg.add(msg.find("p")).css({display: 'inline'}); - } - - // insert into correct position (relative to the field) - var pos = getPosition(input, msg, conf); - - msg.css({ visibility: 'visible', position: 'absolute', top: pos.top, left: pos.left }) - .fadeIn(conf.speed); - }); - - - // hide errors function - }, function(inputs) { - - var conf = this.getConf(); - inputs.removeClass(conf.errorClass).each(function() { - var msg = $(this).data("msg.el"); - if (msg) { msg.css({visibility: 'hidden'}); } - }); - } - ] - }; - - - /* sperial selectors */ - $.each("email,url,number".split(","), function(i, key) { - $.expr[':'][key] = function(el) { - return el.getAttribute("type") === key; - }; - }); - - - /* - oninvalid() jQuery plugin. - Usage: $("input:eq(2)").oninvalid(function() { ... }); - */ - $.fn.oninvalid = function( fn ){ - return this[fn ? "on" : "trigger"]("OI", fn); - }; - - - /******* built-in HTML5 standard validators *********/ - - v.fn(":email", "Please enter a valid email address", function(el, v) { - return !v || emailRe.test(v); - }); - - v.fn(":url", "Please enter a valid URL", function(el, v) { - return !v || urlRe.test(v); - }); - - v.fn(":number", "Please enter a numeric value.", function(el, v) { - return numRe.test(v); - }); - - v.fn("[max]", "Please enter a value no larger than $1", function(el, v) { - - // skip empty values and dateinputs - if (v === '' || dateInput && el.is(":date")) { return true; } - - var max = el.attr("max"); - return parseFloat(v) <= parseFloat(max) ? true : [max]; - }); - - v.fn("[min]", "Please enter a value of at least $1", function(el, v) { - - // skip empty values and dateinputs - if (v === '' || dateInput && el.is(":date")) { return true; } - - var min = el.attr("min"); - return parseFloat(v) >= parseFloat(min) ? true : [min]; - }); - - v.fn("[required]", "Please complete this mandatory field.", function(el, v) { - if (el.is(":checkbox")) { return el.is(":checked"); } - return !!v; - }); - - v.fn("[pattern]", function(el, v) { - return v === '' || new RegExp("^" + el.attr("pattern") + "$").test(v); - }); - - v.fn(":radio[required]", "Please select an option.", function(el) { - var checked = false; - var els = $("[name='" + el.attr("name") + "']").each(function(i, el) { - if ($(el).is(":checked") || checked) { - checked = true; - } - }); - return (checked) ? true : false; - }); - - function Validator(inputs, form, conf) { - - // private variables - var self = this, - fire = form.add(self); - - // make sure there are input fields available - inputs = inputs.not(":button, :image, :reset, :submit"); - +/*jslint evil: true */ +(function($) { + + $.tools = $.tools || {version: '@VERSION'}; + + // globals + var typeRe = /\[type=([a-z]+)\]/, + numRe = /^-?[0-9]*(\.[0-9]+)?$/, + dateInput = $.tools.dateinput, + + // http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/ + emailRe = /^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,6})$/i, + urlRe = /^(https?:\/\/)?[\da-z\.\-]+\.[a-z\.]{2,6}[#&+_\?\/\w \.\-=]*$/i, + v; + + v = $.tools.validator = { + + conf: { + grouped: false, // show all error messages at once inside the container + effect: 'default', // show/hide effect for error message. only 'default' is built-in + errorClass: 'invalid', // input field class name in case of validation error + + // when to check for validity? + inputEvent: null, // change, blur, keyup, null + errorInputEvent: 'keyup', // change, blur, keyup, null + formEvent: 'submit', // submit, null + + lang: 'en', // default language for error messages + message: '', + messageAttr: 'data-message', // name of the attribute for overridden error message + messageClass: 'error', // error message element's class name + offset: [0, 0], + position: 'center right', + singleError: false, // validate all inputs at once + speed: 'normal' // message's fade-in speed + }, + + + /* The Error Messages */ + messages: { + "*": { en: "Please correct this value" } + }, + + localize: function(lang, messages) { + $.each(messages, function(key, msg) { + v.messages[key] = v.messages[key] || {}; + v.messages[key][lang] = msg; + }); + }, + + localizeFn: function(key, messages) { + v.messages[key] = v.messages[key] || {}; + $.extend(v.messages[key], messages); + }, + + /** + * Adds a new validator + */ + fn: function(matcher, msg, fn) { + + // no message supplied + if ($.isFunction(msg)) { + fn = msg; + + // message(s) on second argument + } else { + if (typeof msg == 'string') { msg = {en: msg}; } + this.messages[matcher.key || matcher] = msg; + } + + // check for "[type=xxx]" (not supported by jQuery) + var test = typeRe.exec(matcher); + if (test) { matcher = isType(test[1]); } + + // add validator to the arsenal + fns.push([matcher, fn]); + }, + + /* Add new show/hide effect */ + addEffect: function(name, showFn, closeFn) { + effects[name] = [showFn, closeFn]; + } + + }; + + /* calculate error message position relative to the input */ + function getPosition(trigger, el, conf) { + + // Get the first element in the selector set + el = $(el).first() || el; + + // get origin top/left position + var top = trigger.offset().top, + left = trigger.offset().left, + pos = conf.position.split(/,?\s+/), + y = pos[0], + x = pos[1]; + + top -= el.outerHeight() - conf.offset[0]; + left += trigger.outerWidth() + conf.offset[1]; + + + // iPad position fix + if (/iPad/i.test(navigator.userAgent)) { + top -= $(window).scrollTop(); + } + + // adjust Y + var height = el.outerHeight() + trigger.outerHeight(); + if (y == 'center') { top += height / 2; } + if (y == 'bottom') { top += height; } + + // adjust X + var width = trigger.outerWidth(); + if (x == 'center') { left -= (width + el.outerWidth()) / 2; } + if (x == 'left') { left -= width; } + + return {top: top, left: left}; + } + + + + // $.is("[type=xxx]") or $.filter("[type=xxx]") not working in jQuery 1.3.2 or 1.4.2 + function isType(type) { + function fn() { + return this.getAttribute("type") == type; + } + fn.key = "[type=\"" + type + "\"]"; + return fn; + } + + + var fns = [], effects = { + + 'default' : [ + + // show errors function + function(errs) { + + var conf = this.getConf(); + + // loop errors + $.each(errs, function(i, err) { + + // add error class + var input = err.input; + input.addClass(conf.errorClass); + + // get handle to the error container + var msg = input.data("msg.el"); + + // create it if not present + if (!msg) { + msg = $(conf.message).addClass(conf.messageClass).appendTo(document.body); + input.data("msg.el", msg); + } + + // clear the container + msg.css({visibility: 'hidden'}).find("p").remove(); + + // populate messages + $.each(err.messages, function(i, m) { + $("").html(m).appendTo(msg); + }); + + // make sure the width is not full body width so it can be positioned correctly + if (msg.outerWidth() == msg.parent().width()) { + msg.add(msg.find("p")).css({display: 'inline'}); + } + + // insert into correct position (relative to the field) + var pos = getPosition(input, msg, conf); + + msg.css({ visibility: 'visible', position: 'absolute', top: pos.top, left: pos.left }) + .fadeIn(conf.speed); + }); + + + // hide errors function + }, function(inputs) { + + var conf = this.getConf(); + inputs.removeClass(conf.errorClass).each(function() { + var msg = $(this).data("msg.el"); + if (msg) { msg.css({visibility: 'hidden'}); } + }); + } + ] + }; + + + /* sperial selectors */ + $.each("email,url,number".split(","), function(i, key) { + $.expr[':'][key] = function(el) { + return el.getAttribute("type") === key; + }; + }); + + + /* + oninvalid() jQuery plugin. + Usage: $("input:eq(2)").oninvalid(function() { ... }); + */ + $.fn.oninvalid = function( fn ){ + return this[fn ? "on" : "trigger"]("OI", fn); + }; + + + /******* built-in HTML5 standard validators *********/ + + v.fn(":email", "Please enter a valid email address", function(el, v) { + return !v || emailRe.test(v); + }); + + v.fn(":url", "Please enter a valid URL", function(el, v) { + return !v || urlRe.test(v); + }); + + v.fn(":number", "Please enter a numeric value.", function(el, v) { + return numRe.test(v); + }); + + v.fn("[max]", "Please enter a value no larger than $1", function(el, v) { + + // skip empty values and dateinputs + if (v === '' || dateInput && el.is(":date")) { return true; } + + var max = el.attr("max"); + return parseFloat(v) <= parseFloat(max) ? true : [max]; + }); + + v.fn("[min]", "Please enter a value of at least $1", function(el, v) { + + // skip empty values and dateinputs + if (v === '' || dateInput && el.is(":date")) { return true; } + + var min = el.attr("min"); + return parseFloat(v) >= parseFloat(min) ? true : [min]; + }); + + v.fn("[required]", "Please complete this mandatory field.", function(el, v) { + if (el.is(":checkbox")) { return el.is(":checked"); } + return !!v; + }); + + v.fn("[pattern]", function(el, v) { + return v === '' || new RegExp("^" + el.attr("pattern") + "$").test(v); + }); + + v.fn(":radio[required]", "Please select an option.", function(el) { + var checked = false; + var els = $("[name='" + el.attr("name") + "']").each(function(i, el) { + if ($(el).is(":checked") || checked) { + checked = true; + } + }); + return (checked) ? true : false; + }); + + function Validator(inputs, form, conf) { + + // private variables + var self = this, + fire = form.add(self); + + // make sure there are input fields available + inputs = inputs.not(":button, :image, :reset, :submit"); + // Prevent default Firefox validation form.attr("novalidate", "novalidate"); - // utility function - function pushMessage(to, matcher, returnValue) { - - // only one message allowed - if (!conf.grouped && to.length) { return; } - - // the error message - var msg; - - // substitutions are returned - if (returnValue === false || $.isArray(returnValue)) { - msg = v.messages[matcher.key || matcher] || v.messages["*"]; - msg = msg[conf.lang] || v.messages["*"].en; - - // substitution - var matches = msg.match(/\$\d/g); - - if (matches && $.isArray(returnValue)) { - $.each(matches, function(i) { - msg = msg.replace(this, returnValue[i]); - }); - } - - // error message is returned directly - } else { - msg = returnValue[conf.lang] || returnValue; - } - - to.push(msg); - } - - - // API methods - $.extend(self, { - - getConf: function() { - return conf; - }, - - getForm: function() { - return form; - }, - - getInputs: function() { - return inputs; - }, - - reflow: function() { - inputs.each(function() { - var input = $(this), - msg = input.data("msg.el"); - - if (msg) { - var pos = getPosition(input, msg, conf); - msg.css({ top: pos.top, left: pos.left }); - } - }); - return self; - }, - - /* @param e - for internal use only */ - invalidate: function(errs, e) { - - // errors are given manually: { fieldName1: 'message1', fieldName2: 'message2' } - if (!e) { - var errors = []; - $.each(errs, function(key, val) { - var input = inputs.filter("[name='" + key + "']"); - if (input.length) { - - // trigger HTML5 ininvalid event - input.trigger("OI", [val]); - - errors.push({ input: input, messages: [val]}); - } - }); - - errs = errors; - e = $.Event(); - } - - // onFail callback - e.type = "onFail"; - fire.trigger(e, [errs]); - - // call the effect - if (!e.isDefaultPrevented()) { - effects[conf.effect][0].call(self, errs, e); - } - - return self; - }, - - reset: function(els) { - els = els || inputs; - els.removeClass(conf.errorClass).each(function() { - var msg = $(this).data("msg.el"); - if (msg) { - msg.remove(); - $(this).data("msg.el", null); - } - }).off(conf.errorInputEvent + '.v' || ''); - return self; - }, - - destroy: function() { - form.off(conf.formEvent + ".V reset.V"); - inputs.off(conf.inputEvent + ".V change.V"); - return self.reset(); - }, - - + // utility function + function pushMessage(to, matcher, returnValue) { + + // only one message allowed + if (!conf.grouped && to.length) { return; } + + // the error message + var msg; + + // substitutions are returned + if (returnValue === false || $.isArray(returnValue)) { + msg = v.messages[matcher.key || matcher] || v.messages["*"]; + msg = msg[conf.lang] || v.messages["*"].en; + + // substitution + var matches = msg.match(/\$\d/g); + + if (matches && $.isArray(returnValue)) { + $.each(matches, function(i) { + msg = msg.replace(this, returnValue[i]); + }); + } + + // error message is returned directly + } else { + msg = returnValue[conf.lang] || returnValue; + } + + to.push(msg); + } + + + // API methods + $.extend(self, { + + getConf: function() { + return conf; + }, + + getForm: function() { + return form; + }, + + getInputs: function() { + return inputs; + }, + + reflow: function() { + inputs.each(function() { + var input = $(this), + msg = input.data("msg.el"); + + if (msg) { + var pos = getPosition(input, msg, conf); + msg.css({ top: pos.top, left: pos.left }); + } + }); + return self; + }, + + /* @param e - for internal use only */ + invalidate: function(errs, e) { + + // errors are given manually: { fieldName1: 'message1', fieldName2: 'message2' } + if (!e) { + var errors = []; + $.each(errs, function(key, val) { + var input = inputs.filter("[name='" + key + "']"); + if (input.length) { + + // trigger HTML5 ininvalid event + input.trigger("OI", [val]); + + errors.push({ input: input, messages: [val]}); + } + }); + + errs = errors; + e = $.Event(); + } + + // onFail callback + e.type = "onFail"; + fire.trigger(e, [errs]); + + // call the effect + if (!e.isDefaultPrevented()) { + effects[conf.effect][0].call(self, errs, e); + } + + return self; + }, + + reset: function(els) { + els = els || inputs; + els.removeClass(conf.errorClass).each(function() { + var msg = $(this).data("msg.el"); + if (msg) { + msg.remove(); + $(this).data("msg.el", null); + } + }).off(conf.errorInputEvent + '.v' || ''); + return self; + }, + + destroy: function() { + form.off(conf.formEvent + ".V reset.V"); + inputs.off(conf.inputEvent + ".V change.V"); + return self.reset(); + }, + + //{{{ checkValidity() - flesh and bone of this tool - - /* @returns boolean */ - checkValidity: function(els, e) { - - els = els || inputs; - els = els.not(":disabled"); - - // filter duplicate elements by name - var names = {}; - els = els.filter(function(){ - var name = $(this).attr("name"); - if (!names[name]) { - names[name] = true; - return $(this); - } - }); - - if (!els.length) { return true; } - - e = e || $.Event(); - - // onBeforeValidate - e.type = "onBeforeValidate"; - fire.trigger(e, [els]); - if (e.isDefaultPrevented()) { return e.result; } - - // container for errors - var errs = []; - - // loop trough the inputs - els.each(function() { - - // field and it's error message container - var msgs = [], - el = $(this).data("messages", msgs), - event = dateInput && el.is(":date") ? "onHide.v" : conf.errorInputEvent + ".v"; - - // cleanup previous validation event - el.off(event); - - - // loop all validator functions - $.each(fns, function() { - var fn = this, match = fn[0]; - - // match found - if (el.filter(match).length) { - - // execute a validator function - var returnValue = fn[1].call(self, el, el.val()); - - - // validation failed. multiple substitutions can be returned with an array - if (returnValue !== true) { - - // onBeforeFail - e.type = "onBeforeFail"; - fire.trigger(e, [el, match]); - if (e.isDefaultPrevented()) { return false; } - - // overridden custom message - var msg = el.attr(conf.messageAttr); - if (msg) { - msgs = [msg]; - return false; - } else { - pushMessage(msgs, match, returnValue); - } - } - } - }); - - if (msgs.length) { - - errs.push({input: el, messages: msgs}); - - // trigger HTML5 ininvalid event - el.trigger("OI", [msgs]); - - // begin validating upon error event type (such as keyup) - if (conf.errorInputEvent) { - el.on(event, function(e) { - self.checkValidity(el, e); - }); - } - } - - if (conf.singleError && errs.length) { return false; } - - }); - - - // validation done. now check that we have a proper effect at hand - var eff = effects[conf.effect]; - if (!eff) { throw "Validator: cannot find effect \"" + conf.effect + "\""; } - - // errors found - if (errs.length) { - self.invalidate(errs, e); - return false; - - // no errors - } else { - - // call the effect - eff[1].call(self, els, e); - - // onSuccess callback - e.type = "onSuccess"; - fire.trigger(e, [els]); - - els.off(conf.errorInputEvent + ".v"); - } - - return true; - } -//}}} - - }); - - // callbacks - $.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","), function(i, name) { - - // configuration - if ($.isFunction(conf[name])) { - $(self).on(name, conf[name]); - } - - // API methods - self[name] = function(fn) { - if (fn) { $(self).on(name, fn); } - return self; - }; - }); - - - // form validation - if (conf.formEvent) { - form.on(conf.formEvent + ".V", function(e) { - if (!self.checkValidity(null, e)) { - return e.preventDefault(); - } - // Reset event type and target - e.target = form; - e.type = conf.formEvent; - }); - } - - // form reset - form.on("reset.V", function() { - self.reset(); - }); - - // disable browser's default validation mechanism - if (inputs[0] && inputs[0].validity) { - inputs.each(function() { - this.oninvalid = function() { - return false; - }; - }); - } - - // Web Forms 2.0 compatibility - if (form[0]) { - form[0].checkValidity = self.checkValidity; - } - - // input validation - if (conf.inputEvent) { - inputs.on(conf.inputEvent + ".V", function(e) { - self.checkValidity($(this), e); - }); - } - - // checkboxes and selects are checked separately - inputs.filter(":checkbox, select").filter("[required]").on("change.V", function(e) { - var el = $(this); - if (this.checked || (el.is("select") && $(this).val())) { - effects[conf.effect][1].call(self, el, e); - } - }); - - // get radio groups by name - inputs.filter(":radio[required]").on("change.V", function(e) { - var els = $("[name='" + $(e.srcElement).attr("name") + "']"); - if ((els != null) && (els.length != 0)) { - self.checkValidity(els, e); - } - }); - - // reposition tooltips when window is resized - $(window).resize(function() { - self.reflow(); - }); - - } - - - // jQuery plugin initialization - $.fn.validator = function(conf) { - - var instance = this.data("validator"); - - // destroy existing instance - if (instance) { - instance.destroy(); - this.removeData("validator"); - } - - // configuration - conf = $.extend(true, {}, v.conf, conf); - - // selector is a form - if (this.is("form")) { - return this.each(function() { - var form = $(this); - instance = new Validator(form.find(":input"), form, conf); - form.data("validator", instance); - }); - - } else { - instance = new Validator(this, this.eq(0).closest("form"), conf); - return this.data("validator", instance); - } - - }; - + + /* @returns boolean */ + checkValidity: function(els, e) { + + els = els || inputs; + els = els.not(":disabled"); + + // filter duplicate elements by name + var names = {}; + els = els.filter(function(){ + var name = $(this).attr("name"); + if (!names[name]) { + names[name] = true; + return $(this); + } + }); + + if (!els.length) { return true; } + + e = e || $.Event(); + + // onBeforeValidate + e.type = "onBeforeValidate"; + fire.trigger(e, [els]); + if (e.isDefaultPrevented()) { return e.result; } + + // container for errors + var errs = []; + + // loop trough the inputs + els.each(function() { + + // field and it's error message container + var msgs = [], + el = $(this).data("messages", msgs), + event = dateInput && el.is(":date") ? "onHide.v" : conf.errorInputEvent + ".v"; + + // cleanup previous validation event + el.off(event); + + + // loop all validator functions + $.each(fns, function() { + var fn = this, match = fn[0]; + + // match found + if (el.filter(match).length) { + + // execute a validator function + var returnValue = fn[1].call(self, el, el.val()); + + + // validation failed. multiple substitutions can be returned with an array + if (returnValue !== true) { + + // onBeforeFail + e.type = "onBeforeFail"; + fire.trigger(e, [el, match]); + if (e.isDefaultPrevented()) { return false; } + + // overridden custom message + var msg = el.attr(conf.messageAttr); + if (msg) { + msgs = [msg]; + return false; + } else { + pushMessage(msgs, match, returnValue); + } + } + } + }); + + if (msgs.length) { + + errs.push({input: el, messages: msgs}); + + // trigger HTML5 ininvalid event + el.trigger("OI", [msgs]); + + // begin validating upon error event type (such as keyup) + if (conf.errorInputEvent) { + el.on(event, function(e) { + self.checkValidity(el, e); + }); + } + } + + if (conf.singleError && errs.length) { return false; } + + }); + + + // validation done. now check that we have a proper effect at hand + var eff = effects[conf.effect]; + if (!eff) { throw "Validator: cannot find effect \"" + conf.effect + "\""; } + + // errors found + if (errs.length) { + self.invalidate(errs, e); + return false; + + // no errors + } else { + + // call the effect + eff[1].call(self, els, e); + + // onSuccess callback + e.type = "onSuccess"; + fire.trigger(e, [els]); + + els.off(conf.errorInputEvent + ".v"); + } + + return true; + } +//}}} + + }); + + // callbacks + $.each("onBeforeValidate,onBeforeFail,onFail,onSuccess".split(","), function(i, name) { + + // configuration + if ($.isFunction(conf[name])) { + $(self).on(name, conf[name]); + } + + // API methods + self[name] = function(fn) { + if (fn) { $(self).on(name, fn); } + return self; + }; + }); + + + // form validation + if (conf.formEvent) { + form.on(conf.formEvent + ".V", function(e) { + if (!self.checkValidity(null, e)) { + return e.preventDefault(); + } + // Reset event type and target + e.target = form; + e.type = conf.formEvent; + }); + } + + // form reset + form.on("reset.V", function() { + self.reset(); + }); + + // disable browser's default validation mechanism + if (inputs[0] && inputs[0].validity) { + inputs.each(function() { + this.oninvalid = function() { + return false; + }; + }); + } + + // Web Forms 2.0 compatibility + if (form[0]) { + form[0].checkValidity = self.checkValidity; + } + + // input validation + if (conf.inputEvent) { + inputs.on(conf.inputEvent + ".V", function(e) { + self.checkValidity($(this), e); + }); + } + + // checkboxes and selects are checked separately + inputs.filter(":checkbox, select").filter("[required]").on("change.V", function(e) { + var el = $(this); + if (this.checked || (el.is("select") && $(this).val())) { + effects[conf.effect][1].call(self, el, e); + } + }); + + // get radio groups by name + inputs.filter(":radio[required]").on("change.V", function(e) { + var els = $("[name='" + $(e.srcElement).attr("name") + "']"); + if ((els !== null) && (els.length !== 0)) { + self.checkValidity(els, e); + } + }); + + // reposition tooltips when window is resized + $(window).resize(function() { + self.reflow(); + }); + + } + + + // jQuery plugin initialization + $.fn.validator = function(conf) { + + var instance = this.data("validator"); + + // destroy existing instance + if (instance) { + instance.destroy(); + this.removeData("validator"); + } + + // configuration + conf = $.extend(true, {}, v.conf, conf); + + // selector is a form + if (this.is("form")) { + return this.each(function() { + var form = $(this); + instance = new Validator(form.find(":input"), form, conf); + form.data("validator", instance); + }); + + } else { + instance = new Validator(this, this.eq(0).closest("form"), conf); + return this.data("validator", instance); + } + + }; + })(jQuery);