/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Version: 1.0.3 * Requires jQuery 1.1.3+ * Docs: http://docs.jquery.com/Plugins/livequery */ (function($) { $.extend($.fn, { livequery: function(type, fn, fn2) { var self = this, q; // Handle different call patterns if ($.isFunction(type)) fn2 = fn, fn = type, type = undefined; // See if Live Query already exists $.each( $.livequery.queries, function(i, query) { if ( self.selector == query.selector && self.context == query.context && type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) ) // Found the query, exit the each loop return (q = query) && false; }); // Create new Live Query if it wasn't found q = q || new $.livequery(this.selector, this.context, type, fn, fn2); // Make sure it is running q.stopped = false; // Run it immediately for the first time q.run(); // Contnue the chain return this; }, expire: function(type, fn, fn2) { var self = this; // Handle different call patterns if ($.isFunction(type)) fn2 = fn, fn = type, type = undefined; // Find the Live Query based on arguments and stop it $.each( $.livequery.queries, function(i, query) { if ( self.selector == query.selector && self.context == query.context && (!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped ) $.livequery.stop(query.id); }); // Continue the chain return this; } }); $.livequery = function(selector, context, type, fn, fn2) { this.selector = selector; this.context = context || document; this.type = type; this.fn = fn; this.fn2 = fn2; this.elements = []; this.stopped = false; // The id is the index of the Live Query in $.livequery.queries this.id = $.livequery.queries.push(this)-1; // Mark the functions for matching later on fn.$lqguid = fn.$lqguid || $.livequery.guid++; if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++; // Return the Live Query return this; }; $.livequery.prototype = { stop: function() { var query = this; if ( this.type ) // Unbind all bound events this.elements.unbind(this.type, this.fn); else if (this.fn2) // Call the second function for all matched elements this.elements.each(function(i, el) { query.fn2.apply(el); }); // Clear out matched elements this.elements = []; // Stop the Live Query from running until restarted this.stopped = true; }, run: function() { // Short-circuit if stopped if ( this.stopped ) return; var query = this; var oEls = this.elements, els = $(this.selector, this.context), nEls = els.not(oEls); // Set elements to the latest set of matched elements this.elements = els; if (this.type) { // Bind events to newly matched elements nEls.bind(this.type, this.fn); // Unbind events to elements no longer matched if (oEls.length > 0) $.each(oEls, function(i, el) { if ( $.inArray(el, els) < 0 ) $.event.remove(el, query.type, query.fn); }); } else { // Call the first function for newly matched elements nEls.each(function() { query.fn.apply(this); }); // Call the second function for elements no longer matched if ( this.fn2 && oEls.length > 0 ) $.each(oEls, function(i, el) { if ( $.inArray(el, els) < 0 ) query.fn2.apply(el); }); } } }; $.extend($.livequery, { guid: 0, queries: [], queue: [], running: false, timeout: null, checkQueue: function() { if ( $.livequery.running && $.livequery.queue.length ) { var length = $.livequery.queue.length; // Run each Live Query currently in the queue while ( length-- ) $.livequery.queries[ $.livequery.queue.shift() ].run(); } }, pause: function() { // Don't run anymore Live Queries until restarted $.livequery.running = false; }, play: function() { // Restart Live Queries $.livequery.running = true; // Request a run of the Live Queries $.livequery.run(); }, registerPlugin: function() { $.each( arguments, function(i,n) { // Short-circuit if the method doesn't exist if (!$.fn[n]) return; // Save a reference to the original method var old = $.fn[n]; // Create a new method $.fn[n] = function() { // Call the original method var r = old.apply(this, arguments); // Request a run of the Live Queries $.livequery.run(); // Return the original methods result return r; } }); }, run: function(id) { if (id != undefined) { // Put the particular Live Query in the queue if it doesn't already exist if ( $.inArray(id, $.livequery.queue) < 0 ) $.livequery.queue.push( id ); } else // Put each Live Query in the queue if it doesn't already exist $.each( $.livequery.queries, function(id) { if ( $.inArray(id, $.livequery.queue) < 0 ) $.livequery.queue.push( id ); }); // Clear timeout if it already exists if ($.livequery.timeout) clearTimeout($.livequery.timeout); // Create a timeout to check the queue and actually run the Live Queries $.livequery.timeout = setTimeout($.livequery.checkQueue, 20); }, stop: function(id) { if (id != undefined) // Stop are particular Live Query $.livequery.queries[ id ].stop(); else // Stop all Live Queries $.each( $.livequery.queries, function(id) { $.livequery.queries[ id ].stop(); }); } }); // Register core DOM manipulation methods $.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove'); // Run Live Queries when the Document is ready $(function() { $.livequery.play(); }); // Save a reference to the original init method var init = $.prototype.init; // Create a new init method that exposes two new properties: selector and context $.prototype.init = function(a,c) { // Call the original init and save the result var r = init.apply(this, arguments); // Copy over properties if they exist already if (a && a.selector) r.context = a.context, r.selector = a.selector; // Set properties if ( typeof a == 'string' ) r.context = c || document, r.selector = a; // Return the result return r; }; // Give the init function the jQuery prototype for later instantiation (needed after Rev 4091) $.prototype.init.prototype = $.prototype; })(jQuery); (function( $ ) { /** * jQuery.fn.dependsOn * @version 1.0.1 * @date September 22, 2010 * @since 1.0.0, September 19, 2010 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle} * @author Benjamin "balupton" Lupton {@link http://www.balupton.com} * @copyright (c) 2010 Benjamin Arthur Lupton {@link http://www.balupton.com} * @license Attribution-ShareAlike 2.5 Generic {@link http://creativecommons.org/licenses/by-sa/2.5/ */ $.fn.dependsOn = function(attribute){ if ((attribute === null) || (typeof attribute === 'undefined')) var attribute = 'depends_on'; this.each(function(){ var $target = $(this), depends = $target.attr(attribute).split("="), $source = $("*[name='"+depends[0]+"']:not(:hidden)"), source = $source.attr('id') || $source.attr('name'), value = depends[1]; // Add Data var dependsOnStatus = $target.data('dependsOnStatus')||{}; dependsOnStatus[source] = false; $target.data('dependsOnStatus',dependsOnStatus); // Add Event $source.change(function(){ var pass = false; var $source = $(this); // so $source won't be a group for radios // Determine if ( (value === null) || (typeof value === 'undefined') ) { // We don't have a value if ( $source.is(':checkbox,:radio') ) { pass = $source.is(':selected:enabled,:checked:enabled'); } else { pass = Boolean($source.val()); } } else { // We do have a value if ( $source.is(':checkbox,:radio') ) { pass = $source.is(':selected:enabled,:checked:enabled') && ($source.val() == value); } else { pass = $source.val() == value; } } // Update var dependsOnStatus = $target.data('dependsOnStatus')||{}; dependsOnStatus[source] = pass; $target.data('dependsOnStatus',dependsOnStatus); // Determine var passAll = true; $.each(dependsOnStatus, function(i,v){ if ( !v ) { passAll = false; return false; // break } }); // console.log(dependsOnStatus); // Adjust if ( !passAll ) { $target.attr('disabled','disabled').addClass('disabled'); $target.parent('label').addClass('disabled'); } else { $target.removeAttr('disabled').removeClass('disabled'); $target.parent('label').removeClass('disabled'); } }).trigger('change'); // Chain return this; }); }; })(jQuery); /** * AJAX Upload * Project page - http://valums.com/ajax-upload/ * Copyright (c) 2008 Andris Valums, http://valums.com * Licensed under the MIT license (http://valums.com/mit-license/) */ (function(){ var d = document, w = window; /** * Get element by id */ function get(element){ if (typeof element == "string") element = d.getElementById(element); return element; } /** * Attaches event to a dom element */ function addEvent(el, type, fn){ if (w.addEventListener){ el.addEventListener(type, fn, false); } else if (w.attachEvent){ var f = function(){ fn.call(el, w.event); }; el.attachEvent('on' + type, f) } } /** * Creates and returns element from html chunk */ var toElement = function(){ var div = d.createElement('div'); return function(html){ div.innerHTML = html; var el = div.childNodes[0]; div.removeChild(el); return el; } }(); function hasClass(ele,cls){ return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')); } function addClass(ele,cls) { if (!hasClass(ele,cls)) ele.className += " "+cls; } function removeClass(ele,cls) { var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)'); ele.className=ele.className.replace(reg,' '); } // getOffset function copied from jQuery lib (http://jquery.com/) if (document.documentElement["getBoundingClientRect"]){ // Get Offset using getBoundingClientRect // http://ejohn.org/blog/getboundingclientrect-is-awesome/ var getOffset = function(el){ var box = el.getBoundingClientRect(), doc = el.ownerDocument, body = doc.body, docElem = doc.documentElement, // for ie clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, // In Internet Explorer 7 getBoundingClientRect property is treated as physical, // while others are logical. Make all logical, like in IE8. zoom = 1; if (body.getBoundingClientRect) { var bound = body.getBoundingClientRect(); zoom = (bound.right - bound.left)/body.clientWidth; } if (zoom > 1){ clientTop = 0; clientLeft = 0; } var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop, left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft; return { top: top, left: left }; } } else { // Get offset adding all offsets var getOffset = function(el){ if (w.jQuery){ return jQuery(el).offset(); } var top = 0, left = 0; do { top += el.offsetTop || 0; left += el.offsetLeft || 0; } while (el = el.offsetParent); return { left: left, top: top }; } } function getBox(el){ var left, right, top, bottom; var offset = getOffset(el); left = offset.left; top = offset.top; right = left + el.offsetWidth; bottom = top + el.offsetHeight; return { left: left, right: right, top: top, bottom: bottom }; } /** * Crossbrowser mouse coordinates */ function getMouseCoords(e){ // pageX/Y is not supported in IE // http://www.quirksmode.org/dom/w3c_cssom.html if (!e.pageX && e.clientX){ // In Internet Explorer 7 some properties (mouse coordinates) are treated as physical, // while others are logical (offset). var zoom = 1; var body = document.body; if (body.getBoundingClientRect) { var bound = body.getBoundingClientRect(); zoom = (bound.right - bound.left)/body.clientWidth; } return { x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft, y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop }; } return { x: e.pageX, y: e.pageY }; } /** * Function generates unique id */ var getUID = function(){ var id = 0; return function(){ return 'ValumsAjaxUpload' + id++; } }(); function fileFromPath(file){ return file.replace(/.*(\/|\\)/, ""); } function getExt(file){ return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : ''; } /** * Cross-browser way to get xhr object */ var getXhr = function(){ var xhr; return function(){ if (xhr) return xhr; if (typeof XMLHttpRequest !== 'undefined') { xhr = new XMLHttpRequest(); } else { var v = [ "Microsoft.XmlHttp", "MSXML2.XmlHttp.5.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.2.0" ]; for (var i=0; i < v.length; i++){ try { xhr = new ActiveXObject(v[i]); break; } catch (e){} } } return xhr; } }(); // Please use AjaxUpload , Ajax_upload will be removed in the next version Ajax_upload = AjaxUpload = function(button, options){ if (button.jquery){ // jquery object was passed button = button[0]; } else if (typeof button == "string" && /^#.*/.test(button)){ button = button.slice(1); } button = get(button); this._input = null; this._button = button; this._disabled = false; this._submitting = false; // Variable changes to true if the button was clicked // 3 seconds ago (requred to fix Safari on Mac error) this._justClicked = false; this._parentDialog = d.body; if (window.jQuery && jQuery.ui && jQuery.ui.dialog){ var parentDialog = jQuery(this._button).parents('.ui-dialog'); if (parentDialog.length){ this._parentDialog = parentDialog[0]; } } this._settings = { // Location of the server-side upload script action: 'upload.php', // File upload name name: 'userfile', // Additional data to send data: {}, // Submit file as soon as it's selected autoSubmit: true, // The type of data that you're expecting back from the server. // Html and xml are detected automatically. // Only useful when you are using json data as a response. // Set to "json" in that case. responseType: false, // Location of the server-side script that fixes Safari // hanging problem returning "Connection: close" header closeConnection: '', // Class applied to button when mouse is hovered hoverClass: 'hover', // When user selects a file, useful with autoSubmit disabled onChange: function(file, extension){}, // Callback to fire before file is uploaded // You can return false to cancel upload onSubmit: function(file, extension){}, // Fired when file upload is completed // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! onComplete: function(file, response) {} }; // Merge the users options with our defaults for (var i in options) { this._settings[i] = options[i]; } this._createInput(); this._rerouteClicks(); } // assigning methods to our class AjaxUpload.prototype = { setData : function(data){ this._settings.data = data; }, disable : function(){ this._disabled = true; }, enable : function(){ this._disabled = false; }, // removes instance destroy : function(){ if(this._input){ if(this._input.parentNode){ this._input.parentNode.removeChild(this._input); } this._input = null; } }, /** * Creates invisible file input above the button */ _createInput : function(){ var self = this; var input = d.createElement("input"); input.setAttribute('type', 'file'); input.setAttribute('name', this._settings.name); var styles = { 'position' : 'absolute' ,'margin': '-5px 0 0 -175px' ,'padding': 0 ,'width': '220px' ,'height': '30px' ,'fontSize': '14px' ,'opacity': 0 ,'cursor': 'pointer' ,'display' : 'none' ,'zIndex' : 2147483583 //Max zIndex supported by Opera 9.0-9.2x // Strange, I expected 2147483647 // Doesn't work in IE :( //,'direction' : 'ltr' }; for (var i in styles){ input.style[i] = styles[i]; } // Make sure that element opacity exists // (IE uses filter instead) if ( ! (input.style.opacity === "0")){ input.style.filter = "alpha(opacity=0)"; } this._parentDialog.appendChild(input); addEvent(input, 'change', function(){ // get filename from input var file = fileFromPath(this.value); if(self._settings.onChange.call(self, file, getExt(file)) == false ){ return; } // Submit form when value is changed if (self._settings.autoSubmit){ self.submit(); } }); // Fixing problem with Safari // The problem is that if you leave input before the file select dialog opens // it does not upload the file. // As dialog opens slowly (it is a sheet dialog which takes some time to open) // there is some time while you can leave the button. // So we should not change display to none immediately addEvent(input, 'click', function(){ self.justClicked = true; setTimeout(function(){ // we will wait 3 seconds for dialog to open self.justClicked = false; }, 2500); }); this._input = input; }, _rerouteClicks : function (){ var self = this; // IE displays 'access denied' error when using this method // other browsers just ignore click() // addEvent(this._button, 'click', function(e){ // self._input.click(); // }); var box, dialogOffset = {top:0, left:0}, over = false; addEvent(self._button, 'mouseover', function(e){ if (!self._input || over) return; over = true; box = getBox(self._button); if (self._parentDialog != d.body){ dialogOffset = getOffset(self._parentDialog); } }); // We can't use mouseout on the button, // because invisible input is over it addEvent(document, 'mousemove', function(e){ var input = self._input; if (!input || !over) return; if (self._disabled){ removeClass(self._button, self._settings.hoverClass); input.style.display = 'none'; return; } var c = getMouseCoords(e); if ((c.x >= box.left) && (c.x <= box.right) && (c.y >= box.top) && (c.y <= box.bottom)){ input.style.top = c.y - dialogOffset.top + 'px'; input.style.left = c.x - dialogOffset.left + 'px'; input.style.display = 'block'; addClass(self._button, self._settings.hoverClass); } else { // mouse left the button over = false; var check = setInterval(function(){ // if input was just clicked do not hide it // to prevent safari bug if (self.justClicked){ return; } if ( !over ){ input.style.display = 'none'; } clearInterval(check); }, 25); removeClass(self._button, self._settings.hoverClass); } }); }, /** * Creates iframe with unique name */ _createIframe : function(){ // unique name // We cannot use getTime, because it sometimes return // same value in safari :( var id = getUID(); // Remove ie6 "This page contains both secure and nonsecure items" prompt // http://tinyurl.com/77w9wh var iframe = toElement('