/** * @fileoverview jQuery Autocomplete * Version 1.2 (13/03/2010) * Written by Yehuda Katz (wycats@gmail.com) and Rein Henrichs (reinh@reinh.com) * Additional contributions from Emmanuel Gomez, Austin King,  * Nikos Dimitrakopoulos, Javier Gonel * @requires jQuery v1.2, jQuery dimensions plugin * * Copyright 2007-2010 Yehuda Katz, Rein Henrichs * Dual licensed under the MIT and GPL licenses: *   http://www.opensource.org/licenses/mit-license.php *   http://www.gnu.org/licenses/gpl.html * * @description Form autocomplete plugin using preloaded or Ajax JSON data source * * Simple autocomplete with basic JSON data source * <code>$('input#user-name').autocomplete({list: ["quentin", "adam", "admin"]});</code> * * Simple autocomplete with Ajax loaded JSON data source * <code>$('input#user-name').autocomplete({ajax: "/usernames.js"});</code> * */(function($) {	/** @namespace */	$.ui = $.ui || {};  	/** @namespace */	$.ui.autocomplete = $.ui.autocomplete || {};  	var active = {};	var KEY = {		ESC: 27,	    RETURN: 13,	    TAB: 9,	    BS: 8,	    DEL: 46,	    UP: 38,	    DOWN: 40	};		$.fn.autocomplete = function(opt) {		/* Default options */		opt = $.extend({}, {			/**			 * Milliseconds after the last keystroke to (re-)filter the list			 */			timeout: 500,			/**			 * How many options are too many?			 * if there are more matches than threshold, the list will not be displayed			 */			threshold: 100,			/**			 * By default the with of the input box is used for the autocomplete			 * suggestions. If you want to change that, specify here a width in pixels.			 */			adjustWidth: true,			/**			 * Maximum number of items to show. By default show all.			 */			maxResults: undefined,			/**			 * Minumum number of characters needed before starting the autocomplete			 * If set to 'undefined', the empty string will be passed to the			 * 'filterList' function. This can be used to display			 * a full list when no characters are introduced.			 */			minCharacters: 0,			    	    ie6width: '400px',			/**			 * Get the complete list of items			 * override this to control how to get the list of potential matches			 * default is to use the 'list' option passed during initialization			 *  and trigger "updateList" event with list as data			 *			 * @param input the text input being autocompleted			 */			getList: function(input) {				input.triggerHandler("updateList", [opt.list]);			},			/**			 * Called to determine if a given data item matches the user's input			 *			 * @param {string} item data item being tested for match			 * @param {RegExp} matcher regex to test the item with			 * @return {boolean} true if this data item matches user input			 */			match: function(item, matcher) {				// Do not use !==								return (item.match)?(item.match(matcher) != undefined):true;							},			/**			 * Called to build the matcher			 *			 * @param typed the text entered by user in the text input			 * @return regex used to filter the complete list			 */			matcher: function(typed) {				return new RegExp(typed);			},			/**			 * Update the list of matching items			 * override this to control how the filtered list is generated from the complete list			 *			 * @param list complete list to be filtered			 * @param val text entered in the text input			 * @return filtered list with items that match _val_ (however matching is defined)			 */			filterList: function(list, val) {				var matcher = opt.matcher(val),					grepCallback = function(text, i) {						return opt.match(text, matcher);					},					index = 0;							if (this.maxResults) {					grepCallback = function(text, i) {						if (index>this.maxResults) {							return false;						}						index++;						return opt.match(text, matcher);					};				}				return $.grep(list, grepCallback);			},      /**       * Update the list of matching items       * override this to control how markup is built from the list of matches       *       * @param unfilteredList unfiltered list of potential matches       * @param val the text in the input field       *       * @return container (which should be positioned and visible)       */      updateList: function(unfilteredList, val) {        if (opt.minCharacters && val.length <= opt.minCharacters) {          return false;        }        var list = opt.filterList(unfilteredList, val);        if(list.length === 0 || list.length > opt.threshold) {return false;}        return opt.buildList(list);      },      /**       * Build the list of matches       * override this to control how markup is built from the list of matches       * make sure the elements in the list have the matching object       * in their $.fn.data as "originalObject"       *       * @param list list of items matching user input       * @return container       */      buildList: function(list) {        var listItems = $(list).map(function() {          var node = $(opt.template(this))[0];          $.data(node, "originalObject", this);          return node;        });        // IE seems to wrap the wrapper in a random div wrapper so        // drill down to the node in opt.wrapper.        var container = $(opt.wrapper).append(listItems);// .parents(":last").children();        // TODO: need to verify that parents(":last").children really does the below        var wrapTag = $(opt.wrapper)[0].tagName;        while (container[0].tagName !== wrapTag) {          container = container.children(':first');        }        return container;      },      wrapper: "<ul class='jq-ui-autocomplete'></ul>",      /**       * Display the list of matches       * override this to control the container position or size       * or to skip appending the list to the html body       *       * @param input the text input being autocompleted       * @param container the container of the list of matches (typically an ol/ul)       *       * @return container (which should be positioned and visible)       */      displayList: function(input, container) {        var offset = input.offset();        if (jQuery.browser.msie && parseInt(jQuery.browser.version) == 6) {          container.css({              top: offset.top + input.outerHeight(),             left: offset.left,             width: "500px" /*this.adjustWidth?input.width():undefined*/          })            .appendTo("body");          $(".jq-ui-autocomplete li").css({width: container.width()});          } else {             container.css({              top: offset.top + input.outerHeight(),              left: offset.left,              minWidth: this.adjustWidth?input.width():undefined            })            .appendTo("body");          $(".jq-ui-autocomplete li").css({width: container.width()});        }                  return container;      },      /**       * Dismiss the list of matches       * override this to control how the list container is dismissed       * default is to remove the element       *       * @param container the container of the list of matches (typically an ol/ul)       */      dismissList: function(container) {        container.remove();      },      template: function(str) { return "<li>" + opt.insertText(str) + "</li>"; },      /**       * Provide a value for the text input from the active object,       * also used to fill the li element in the default _template_ implementation       *       * @param item active item in the list       */      insertText: function(item) { return item; },      displayText: function(item) { return item; }    }, opt);		/* 		 * Additional options from autocomplete.ext (for example 'ajax', and 'templateText') 		 * if these options where passed in the opt object and the $.ui.autocomplete.ext is present.		 */		if($.ui.autocomplete.ext) {			for(var ext in $.ui.autocomplete.ext) {				if(opt[ext]) {					opt = $.extend(opt, $.ui.autocomplete.ext[ext](opt));					delete opt[ext];				}			} 		}		function preventTabInAutocompleteMode(e) {			var k = e.which || e.keycode;			if ($.data(document.body, "autocompleteMode") && k == KEY.TAB) {				e.preventDefault();			}		}    function startTypingTimeout(e, element) {      $.data(element, "typingTimeout", window.setTimeout(function() {        $(e.target || e.srcElement).triggerHandler("autocomplete");      }, opt.timeout));    }    function  handleKeyDownUp(e) {      var k = e.which || e.keycode;      if ((k == KEY.UP || k == KEY.DOWN) && !$.data(this, "typingTimeout")) {        startTypingTimeout(e, this);      } else if (k == KEY.BS || k == KEY.DEL) {        var typingTimeout = $.data(this, "typingTimeout");        if (typingTimeout) {          window.clearInterval(typingTimeout);        }        startTypingTimeout(e, this);      } else {        preventTabInAutocompleteMode(e);      }    }    		return this.each(function() {			$(this)				//.attr("autocomplete", "off")				.keydown(handleKeyDownUp)				.keyup(handleKeyDownUp)				.keypress(function(e) {					var typingTimeout = $.data(this, "typingTimeout");					var k = e.keyCode || e.which; // keyCode == 0 in Gecko/FF on keypress					if(typingTimeout) {						window.clearInterval(typingTimeout);					}					if($.data(document.body, "suppressKey")) {						return $.data(document.body, "suppressKey", false);					} else if($.data(document.body, "autocompleteMode") && k < 32 && k != KEY.BS && k != KEY.DEL) {						return false;					} else if (k == KEY.BS || k == KEY.DEL || k > 32) { // more than ESC and RETURN and the like						startTypingTimeout(e, this);					}				})				.bind("autocomplete", function() {					var self = $(this);					self.one("updateList", function(e, completeList, matchVal) {				        opt.searchstring = matchVal || self.val();						var container = opt.updateList(completeList, matchVal || self.val());						// turn off autcomplete mode even if the list is empty (container === false)						$("body").triggerHandler("off.autocomplete");						if (container === false) { return false; }						opt.container = opt.displayList(self, container);						$("body").autocompleteMode(opt.container, self, container.find("li").length, opt);					});					opt.getList(self);				});				if (typeof opt.init == "function") { opt.init(self); }		});	};	$.fn.autocompleteMode = function(container, input, size, opt) {		var original = input.val(),			selected = -1,			mouseDown = false;		$.data(document.body, "autocompleteMode", true);		$("body").one("cancel.autocomplete", function() {			input.triggerHandler("cancelled.autocomplete");			$("body").triggerHandler("off.autocomplete");			input.val(original);		});		$("body").bind("activate.autocomplete", function(e) {			//console.log('activate');			// Try hitting return to activate autocomplete and then hitting it again on blank input			// to close it.  w/o checking the active object first this input.triggerHandler() will barf.			if (active.length) {				// if activate and selected -> clicked!				input.triggerHandler("activated.autocomplete", [$.data(active[0], "originalObject"), active]);			}			// if nothing active when activate event and we had a mousedown event before			// then the user is dragging something in the list. Ignore action.			else if(mouseDown) {				mouseDown = false;				if(document.activeElement && document.activeElement != input)					input.trigger("focus");				return false;			}			$("body").triggerHandler("off.autocomplete");		});	$("body").one("off.autocomplete", function(e, reset) {		opt.dismissList(container);		$.data(document.body, "autocompleteMode", false);		input.unbind("keydown.autocomplete");		$("body").add(window)			.unbind("click.autocomplete")			.unbind("cancel.autocomplete")			.unbind("activate.autocomplete");    });	// If a click bubbles all the way up to the window, close the autocomplete	$(window).bind("click.autocomplete", function() {		//alert('test');		$("body").triggerHandler("cancel.autocomplete");	});    var select = function() {      active = container.find("li")        .removeClass("active")        .filter(":visible")        .slice(selected, selected + 1)        .addClass("active");      if (active.length) {        input.triggerHandler("itemSelected.autocomplete", [$.data(active[0], "originalObject"), active]);        input.val(opt.displayText($.data(active[0], "originalObject")));        if (opt.idfield) {          $(opt.idfield).val($.data(active[0], "originalObject").id);        }        if (opt.afterSelect){          opt.afterSelect($.data(active[0], "originalObject"));        }              } else {        input.triggerHandler("noneSelected.autocomplete");        input.val(original);      }    };	container		.mouseover(function(e) {	        // If you hover over the container, but not its children, return	        if(e.target == container[0]) { return; }	        var selectedItem = $(e.target).is('li') ? $(e.target)[0] : $(e.target).parents('li')[0];	        // Set the selected item to the item hovered over and make it active	        selected = container.find("li").index(selectedItem);	        select();		})		// IE8 was triggering spurious activate events when clicking outside		// the container when a list item was active. I couldn't figure out where		// the activate events were coming from, so I'm deactivating the list		.mouseout(function(e) {			selected = -1;			select();		})		.mousedown(function() { mouseDown = true; 		  //console.log('mousedown');		})		.bind("click.autocomplete", function(e) {        $("body").triggerHandler("activate.autocomplete");        $.data(document.body, "suppressKey", false);      });    input      .bind("keydown.autocomplete", function(e) {        var k = e.which || e.keyCode; // in IE e.which is undefined        switch(k) {          case KEY.ESC:            $("body").triggerHandler("cancel.autocomplete");            break;			// TAB & Return behave in the same way.          case KEY.TAB:		  case KEY.RETURN:            if (selected == -1) {				// If nothing is selected, select the first				selected = selected >= size - 1 ? 0 : selected + 1;				select();            }             $("body").triggerHandler("activate.autocomplete");            break;          case KEY.DOWN:            selected = selected >= size - 1 ? 0 : selected + 1;            select();            break;          case KEY.UP:            selected = selected <= 0 ? size - 1 : selected - 1;            select();            break;          default:            return true;        }        $.data(document.body, "suppressKey", true);      });  };})(jQuery);/* * jQuery Autocomplete Extensions * Version 1.2 (07/03/2010) * Written by Yehuda Katz (wycats@gmail.com) and Rein Henrichs (reinh@reinh.com) * Additional contributions from Emmanuel Gomez, Austin King * Nikos Dimitrakopoulos, Javier Gonel * @requires: jQuery v1.2 or later *  * Copyright 2007-2009 Yehuda Katz, Rein Henrichs * Dual licensed under the MIT and GPL licenses: *   http://www.opensource.org/licenses/mit-license.php *   http://www.gnu.org/licenses/gpl.html * */(function($) {	/** @namespace */  $.ui = $.ui || {};	/** @namespace */  $.ui.autocomplete = $.ui.autocomplete || {};	/** @namespace */  $.ui.autocomplete.ext = $.ui.autocomplete.ext || {};    /*   * @description Overrides the default 'getList' option with remote call replacement.   *   * @param {Object} opt Should contain a .ajax property with the url of the remote service to call.   * @returns A function which calls the remote service, fetches the result and triggers an "updateList" event on the input element.   */  $.ui.autocomplete.ext.ajax = function(opt) {    var ajax = opt.ajax;    return { getList: function(input) {      if (input.val().match(/^\s*$/)) return false;      $.getJSON(ajax, { s: input.val(), atr:input.attr('atr') }, function(json) { input.trigger("updateList", [json]); });    } };  };  /*   * @description Overrides the default 'template' option.   *   * @param {Object} opt Should contain a .templateText string with the template to parse and return.   *    if .templateBegin or .templateEnd are present,   *    they will determine begin/end tags in template compilation   * @returns A function that executes the given template with the obj passed to it.   */  $.ui.autocomplete.ext.templateText = function(opt) {    var begin = opt.templateBegin || "<%", end = opt.templateEnd || "%>";    var template = $.makeTemplate(opt.templateText, begin, end);    return { template: function(obj) { return template(obj); } };  };  })(jQuery);/* Copyright (c) 2006 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. * * $LastChangedDate: 2007-07-21 18:44:59 -0500 (Sat, 21 Jul 2007) $ * $Rev: 2446 $ * * Version 2.1.1 * *  */ /*extern document, jQuery, navigator */(function(jQuery){/** * The bgiframe is chainable and applies the iframe hack to get  * around zIndex issues in IE6. It will only apply itself in IE6  * and adds a class to the iframe called 'bgiframe'. The iframe * is appeneded as the first child of the matched element(s)  * with a tabIndex and zIndex of -1. *  * By default the plugin will take borders, sized with pixel units, * into account. If a different unit is used for the border's width, * then you will need to use the top and left settings as explained below. * * NOTICE: This plugin has been reported to cause perfromance problems * when used on elements that change properties (like width, height and * opacity) a lot in IE6. Most of these problems have been caused by  * the expressions used to calculate the elements width, height and  * borders. Some have reported it is due to the opacity filter. All  * these settings can be changed if needed as explained below. * * @example $('div').bgiframe(); * @before <div><p>Paragraph</p></div> * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div> * * @param Map settings Optional settings to configure the iframe. * @option String|Number top The iframe must be offset to the top * 		by the width of the top border. This should be a negative  *      number representing the border-top-width. If a number is  * 		is used here, pixels will be assumed. Otherwise, be sure *		to specify a unit. An expression could also be used.  * 		By default the value is "auto" which will use an expression  * 		to get the border-top-width if it is in pixels. * @option String|Number left The iframe must be offset to the left * 		by the width of the left border. This should be a negative  *      number representing the border-left-width. If a number is  * 		is used here, pixels will be assumed. Otherwise, be sure *		to specify a unit. An expression could also be used.  * 		By default the value is "auto" which will use an expression  * 		to get the border-left-width if it is in pixels. * @option String|Number width This is the width of the iframe. If *		a number is used here, pixels will be assume. Otherwise, be sure * 		to specify a unit. An experssion could also be used. *		By default the value is "auto" which will use an experssion * 		to get the offsetWidth. * @option String|Number height This is the height of the iframe. If *		a number is used here, pixels will be assume. Otherwise, be sure * 		to specify a unit. An experssion could also be used. *		By default the value is "auto" which will use an experssion * 		to get the offsetHeight. * @option Boolean opacity This is a boolean representing whether or not * 		to use opacity. If set to true, the opacity of 0 is applied. If *		set to false, the opacity filter is not applied. Default: true. * @option String src This setting is provided so that one could change  *		the src of the iframe to whatever they need. *		Default: "javascript:false;" * * @name bgiframe * @type jQuery * @cat Plugins/bgiframe * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net) */jQuery.fn.bgIframe = jQuery.fn.bgiframe = function(s) {	// This is only for IE6	if ( jQuery.browser.msie && /6.0/.test(navigator.userAgent) ) {		s = jQuery.extend({			top     : 'auto', // auto == .currentStyle.borderTopWidth			left    : 'auto', // auto == .currentStyle.borderLeftWidth			width   : 'auto', // auto == offsetWidth			height  : 'auto', // auto == offsetHeight			opacity : true,			src     : 'javascript:false;'		}, s || {});		var prop = function(n){return n&&n.constructor==Number?n+'px':n;},		    html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+		               'style="display:block;position:absolute;z-index:-1;'+			               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+					       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+					       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+					       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+					       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+					'"/>';		return this.each(function() {			if (jQuery('> iframe.bgiframe', this).length === 0) {				this.insertBefore( document.createElement(html), this.firstChild );			}		});	}	return this;};})(jQuery);/** * jCache - A client cache plugin for jQuery * Should come in handy when data needs to be cached in client to improve performance. * Author: 	Phan Van An  *			phoenixheart@gmail.com *			http://www.skidvn.com * License : Read jQuery's licenseUsage:    1. 	Include this plugin into your web document after jQuery:    	<script type="text/javascript" src="js/jquery.jcache.js"></script>    2.	[OPTIONAL] Set the max cached item number, for example 20    	$.jCache.maxSize = 20;     3. 	Start playing around with it:    	- Put an item into cache: $.jCache.setItem(theKey, the Value);    	- Retrieve an item from cache: var theValue = $.jCache.getItem(theKey);    	- ... */(function (jQuery){	this.version = '(beta)(0.0.1)';	 jQuery.jCache = jQuery.jCache || {};		/**	 * The maximum items this cache should hold. 	 * If the cache is going to be overload, oldest item will be deleted (FIFO).	 * Since the cached object is retained inside browser's state, 	 * a too big value on a too big web apps may affect system memory.	 * Default is 10.	 */	this.maxSize = 10;	    /**     * An array to keep track of the cache keys     */	this.keys = new Array();		/**	 * Number of currently cached items	 */	this.cache_length = 0;		/**	 * An associated array to contain the cached items	 */	this.items = new Array();		/*	 * @desc	Puts an item into the cache	 *	 * @param	string Key of the item	 * @param 	string Value of the item	 * @return	string Value of the item	 */	this.setItem = function(pKey, pValue)	{		if (typeof(pValue) != 'undefined') 		{			if (typeof(this.items[pKey]) == 'undefined') 			{				this.cache_length++;			}			this.keys.push(pKey);			this.items[pKey] = pValue;						if (this.cache_length > this.maxSize)			{				this.removeOldestItem();			}		}	   		return pValue;	}		/*	 * @desc	Removes an item from the cache using its key	 * @param 	string Key of the item	 */	this.removeItem = function(pKey)	{		var tmp;		if (typeof(this.items[pKey]) != 'undefined') 		{			this.cache_length--;			var tmp = this.items[pKey];			delete this.items[pKey];		}	   		return tmp;	}	/*	 * @desc 	Retrieves an item from the cache by its key	 *	 * @param 	string Key of the item	 * @return	string Value of the item	 */	this.getItem = function(pKey) 	{		return this.items[pKey];	}	/*	 * @desc	Indicates if the cache has an item specified by its key	 * @param 	string Key of the item	 * @return 	boolean TRUE or FALSE	 */	this.hasItem = function(pKey)	{		return typeof(this.items[pKey]) != 'undefined';	}		/**	 * @desc	Removes the oldest cached item from the cache	 */	this.removeOldestItem = function()	{		this.removeItem(this.keys.shift());	}		/**	 * @desc	Clears the cache	 * @return	Number of items cleared	 */	this.clear = function()	{		var tmp = this.cache_length;		this.keys = new Array();		this.cache_length = 0;		this.items = new Array();		return tmp;	}		jQuery.jCache = this;	return jQuery;})(jQuery);
