[Jifty-commit] r4839 - in jifty/branches/jquery: lib/Jifty

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sun Jan 13 00:53:34 EST 2008


Author: gugod
Date: Sun Jan 13 00:53:34 2008
New Revision: 4839

Added:
   jifty/branches/jquery/share/web/static/js/iautocompleter.js   (contents, props changed)
   jifty/branches/jquery/share/web/static/js/iutil.js   (contents, props changed)
   jifty/branches/jquery/share/web/static/js/jifty_interface.js   (contents, props changed)
Modified:
   jifty/branches/jquery/lib/Jifty/Web.pm
   jifty/branches/jquery/share/web/static/js/jifty.js

Log:
Pull in "Interace Element for jQuery" ( http://interface.eyecon.ro/ )
for replacing Ajax.Autocomplete.

Instead of directly modifying their code, I choose to override their
functions in another file that's loaded after them.

So Jifty.Autocompleter now works without scriptaculous now. Also,
it's not inheriting anything from any other classes, but just a
plain object in javascript.

Noted here that the beforeShow / beforeHide hacks have not been
ported yet.


Modified: jifty/branches/jquery/lib/Jifty/Web.pm
==============================================================================
--- jifty/branches/jquery/lib/Jifty/Web.pm	(original)
+++ jifty/branches/jquery/lib/Jifty/Web.pm	Sun Jan 13 00:53:34 2008
@@ -40,6 +40,9 @@
     json.js
     prototype.js
     jquery-1.2.1.js
+    iutil.js
+    iautocompleter.js
+    jifty_interface.js
     jquery_noconflict.js
     behaviour.js
     scriptaculous/builder.js

Added: jifty/branches/jquery/share/web/static/js/iautocompleter.js
==============================================================================
--- (empty file)
+++ jifty/branches/jquery/share/web/static/js/iautocompleter.js	Sun Jan 13 00:53:34 2008
@@ -0,0 +1,536 @@
+/**
+ * Interface Elements for jQuery
+ * Autocompleter
+ * 
+ * http://interface.eyecon.ro
+ * 
+ * Copyright (c) 2006 Stefan Petre
+ * Dual licensed under the MIT (MIT-LICENSE.txt) 
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *  
+ */
+
+/**
+ * Attach AJAX driven autocomplete/sugestion box to text input fields.
+ *
+ * 
+ * 
+ * @name Autocomplete
+ * @description Attach AJAX driven autocomplete/sugestion box to text input fields.
+ * @param Hash hash A hash of parameters
+ * @option String source the URL to request
+ * @option Integer delay (optional) the delayed time to start the AJAX request
+ * @option Boolean autofill (optional) when true the first sugested value fills the input
+ * @option String helperClass (optional) the CSS class applied to sugestion box
+ * @option String selectClass (optional) the CSS class applied to selected/hovered item
+ * @option Integer minchars (optional) the number of characters needed before starting AJAX request
+ * @option Hash fx (optional) {type:[slide|blind|fade]; duration: integer} the fx type to apply to sugestion box and duration for that fx
+ * @option Function onSelect (optional) A function to be executed whenever an item it is selected
+ * @option Function onShow (optional) A function to be executed whenever the suggection box is displayed
+ * @option Function onHide (optional) A function to be executed whenever the suggection box is hidden
+ * @option Function onHighlight (optional) A function to be executed whenever an item it is highlighted
+ *
+ * @type jQuery
+ * @cat Plugins/Interface
+ * @author Stefan Petre
+ */
+jQuery.iAuto = {
+	helper : null,
+	content : null,
+	iframe: null,
+	timer : null,
+	lastValue: null,
+	currentValue: null,
+	subject: null,
+	selectedItem : null,
+	items: null,
+	
+	empty : function()
+	{
+		jQuery.iAuto.content.empty();
+		if (jQuery.iAuto.iframe) {
+			jQuery.iAuto.iframe.hide();
+		}
+	},
+
+	clear : function()
+	{
+		jQuery.iAuto.items = null;
+		jQuery.iAuto.selectedItem = null;
+		jQuery.iAuto.lastValue = jQuery.iAuto.subject.value;
+		if(jQuery.iAuto.helper.css('display') == 'block') {
+			if (jQuery.iAuto.subject.autoCFG.fx) {
+				switch(jQuery.iAuto.subject.autoCFG.fx.type) {
+					case 'fade':
+						jQuery.iAuto.helper.fadeOut(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
+						break;
+					case 'slide':
+						jQuery.iAuto.helper.SlideOutUp(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
+						break;
+					case 'blind':
+						jQuery.iAuto.helper.BlindUp(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
+						break;
+				}
+			} else {
+				jQuery.iAuto.helper.hide();
+			}
+			if (jQuery.iAuto.subject.autoCFG.onHide)
+				jQuery.iAuto.subject.autoCFG.onHide.apply(jQuery.iAuto.subject, [jQuery.iAuto.helper, jQuery.iAuto.iframe]);
+		} else {
+			jQuery.iAuto.empty();
+		}
+		window.clearTimeout(jQuery.iAuto.timer);
+	},
+
+	update : function ()
+	{
+		var subject = jQuery.iAuto.subject;
+		var subjectValue = jQuery.iAuto.getFieldValues(subject);
+		//var selectionStart = jQuery.iAuto.getSelectionStart(subject);
+		if (subject && subjectValue.item != jQuery.iAuto.lastValue && subjectValue.item.length >= subject.autoCFG.minchars) {
+			jQuery.iAuto.lastValue = subjectValue.item;
+			jQuery.iAuto.currentValue = subjectValue.item;
+
+			data = {
+				field: jQuery(subject).attr('name')||'field',
+				value: subjectValue.item
+			};
+
+			jQuery.ajax(
+				{
+					type: 'POST',
+					data: jQuery.param(data),
+					success: function(xml)
+					{
+						subject.autoCFG.lastSuggestion = jQuery('item',xml);
+						size = subject.autoCFG.lastSuggestion.size();
+						if (size > 0) {
+							var toWrite = '';
+							subject.autoCFG.lastSuggestion.each(
+								function(nr)
+								{
+									toWrite += '<li rel="' + jQuery('value', this).text() + '" dir="' + nr + '" style="cursor: default;">' + jQuery('text', this).text() + '</li>';
+								}
+							);
+							if (subject.autoCFG.autofill) {
+								var valueToAdd = jQuery('value', subject.autoCFG.lastSuggestion.get(0)).text();
+								subject.value = subjectValue.pre + valueToAdd + subject.autoCFG.multipleSeparator + subjectValue.post;
+								jQuery.iAuto.selection(
+									subject, 
+									subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + subjectValue.item.length) : valueToAdd.length,
+									subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + valueToAdd.length) : valueToAdd.length
+								);
+							}
+							
+							if (size > 0) {
+								jQuery.iAuto.writeItems(subject, toWrite);
+							} else {
+								jQuery.iAuto.clear();
+							}
+						} else {
+							jQuery.iAuto.clear();
+						}
+					},
+					url : subject.autoCFG.source
+				}
+			);
+		}
+	},
+	
+	writeItems : function(subject, toWrite)
+	{
+		jQuery.iAuto.content.html(toWrite);
+		jQuery.iAuto.items = jQuery('li', jQuery.iAuto.content.get(0));
+		jQuery.iAuto.items
+			.mouseover(jQuery.iAuto.hoverItem)
+			.bind('click', jQuery.iAuto.clickItem);
+		var position = jQuery.iUtil.getPosition(subject);
+		var size = jQuery.iUtil.getSize(subject);
+		jQuery.iAuto.helper
+			.css('top', position.y + size.hb + 'px')
+			.css('left', position.x +  'px')
+			.addClass(subject.autoCFG.helperClass);
+		if (jQuery.iAuto.iframe) {
+			jQuery.iAuto.iframe
+				.css('display', 'block')
+				.css('top', position.y + size.hb + 'px')
+				.css('left', position.x +  'px')
+				.css('width', jQuery.iAuto.helper.css('width'))
+				.css('height', jQuery.iAuto.helper.css('height'));
+		}
+		jQuery.iAuto.selectedItem = 0;
+		jQuery.iAuto.items.get(0).className = subject.autoCFG.selectClass;
+		jQuery.iAuto.applyOn(subject,subject.autoCFG.lastSuggestion.get(0), 'onHighlight');
+		
+		if (jQuery.iAuto.helper.css('display') == 'none') {
+			if (subject.autoCFG.inputWidth) {
+				var borders = jQuery.iUtil.getPadding(subject, true);
+				var paddings = jQuery.iUtil.getBorder(subject, true);
+				jQuery.iAuto.helper.css('width', subject.offsetWidth - (jQuery.boxModel ? (borders.l + borders.r + paddings.l + paddings.r) : 0 ) + 'px');
+			}
+			if (subject.autoCFG.fx) {
+				switch(subject.autoCFG.fx.type) {
+					case 'fade':
+						jQuery.iAuto.helper.fadeIn(subject.autoCFG.fx.duration);
+						break;
+					case 'slide':
+						jQuery.iAuto.helper.SlideInUp(subject.autoCFG.fx.duration);
+						break;
+					case 'blind':
+						jQuery.iAuto.helper.BlindDown(subject.autoCFG.fx.duration);
+						break;
+				}
+			} else {
+				jQuery.iAuto.helper.show();
+			}
+			
+			if (jQuery.iAuto.subject.autoCFG.onShow)
+				jQuery.iAuto.subject.autoCFG.onShow.apply(jQuery.iAuto.subject, [jQuery.iAuto.helper, jQuery.iAuto.iframe]);
+		}
+	},
+	
+	checkCache : function()
+	{
+		var subject = this;
+		if (subject.autoCFG.lastSuggestion) {
+			
+			jQuery.iAuto.lastValue = subject.value;
+			jQuery.iAuto.currentValue = subject.value;
+			
+			var toWrite = '';
+			subject.autoCFG.lastSuggestion.each(
+				function(nr)
+				{
+					value = jQuery('value', this).text().toLowerCase();
+					inputValue = subject.value.toLowerCase();
+					if (value.indexOf(inputValue) == 0) {
+						toWrite += '<li rel="' + jQuery('value', this).text() + '" dir="' + nr + '" style="cursor: default;">' + jQuery('text', this).text() + '</li>';
+					}
+				}
+			);
+			
+			if (toWrite != '') {
+				jQuery.iAuto.writeItems(subject, toWrite);
+				
+				this.autoCFG.inCache = true;
+				return;
+			}
+		}
+		subject.autoCFG.lastSuggestion = null;
+		this.autoCFG.inCache = false;
+	},
+
+	selection : function(field, start, end)
+	{
+		if (field.createTextRange) {
+			var selRange = field.createTextRange();
+			selRange.collapse(true);
+			selRange.moveStart("character", start);
+			selRange.moveEnd("character", - end + start);
+			selRange.select();
+		} else if (field.setSelectionRange) {
+			field.setSelectionRange(start, end);
+		} else {
+			if (field.selectionStart) {
+				field.selectionStart = start;
+				field.selectionEnd = end;
+			}
+		}
+		field.focus();
+	},
+	
+	getSelectionStart : function(field)
+	{
+		if (field.selectionStart)
+			return field.selectionStart;
+		else if(field.createTextRange) {
+			var selRange = document.selection.createRange();
+			var selRange2 = selRange.duplicate();
+			return 0 - selRange2.moveStart('character', -100000);
+			//result.end = result.start + range.text.length;
+			/*var selRange = document.selection.createRange();
+			var isCollapsed = selRange.compareEndPoints("StartToEnd", selRange) == 0;
+			if (!isCollapsed)
+				selRange.collapse(true);
+			var bookmark = selRange.getBookmark();
+			return bookmark.charCodeAt(2) - 2;*/
+		}
+	},
+	
+	getFieldValues : function(field)
+	{
+		var fieldData = {
+			value: field.value,
+			pre: '',
+			post: '',
+			item: ''
+		};
+		
+		if(field.autoCFG.multiple) {
+			var finishedPre = false;
+			var selectionStart = jQuery.iAuto.getSelectionStart(field)||0;
+			var chunks = fieldData.value.split(field.autoCFG.multipleSeparator);
+			for (var i=0; i<chunks.length; i++) {
+				if(
+					(fieldData.pre.length + chunks[i].length >= selectionStart
+					 || 
+					selectionStart == 0)
+					 && 
+					!finishedPre 
+				) {
+					if (fieldData.pre.length <= selectionStart)
+						fieldData.item = chunks[i];
+					else 
+						fieldData.post += chunks[i] + (chunks[i] != '' ? field.autoCFG.multipleSeparator : '');
+					finishedPre = true;
+				} else if (finishedPre){
+					fieldData.post += chunks[i] + (chunks[i] != '' ? field.autoCFG.multipleSeparator : '');
+				}
+				if(!finishedPre) {
+					fieldData.pre += chunks[i] + (chunks.length > 1 ? field.autoCFG.multipleSeparator : '');
+				}
+			}
+		} else {
+			fieldData.item = fieldData.value;
+		}
+		return fieldData;
+	},
+	
+	autocomplete : function(e)
+	{
+		window.clearTimeout(jQuery.iAuto.timer);
+		var subject = jQuery.iAuto.getFieldValues(this);
+				
+		var pressedKey = e.charCode || e.keyCode || -1;
+		if (/13|27|35|36|38|40|9/.test(pressedKey) && jQuery.iAuto.items) {
+			if (window.event) {
+				window.event.cancelBubble = true;
+				window.event.returnValue = false;
+			} else {
+				e.preventDefault();
+				e.stopPropagation();
+			}
+			if (jQuery.iAuto.selectedItem != null) 
+				jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
+			else
+				jQuery.iAuto.selectedItem = -1;
+			switch(pressedKey) {
+				//enter
+				case 9:
+				case 13:
+					if (jQuery.iAuto.selectedItem == -1)
+						jQuery.iAuto.selectedItem = 0;
+					var selectedItem = jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0);
+					var valueToAdd = selectedItem.getAttribute('rel');
+					this.value = subject.pre + valueToAdd + this.autoCFG.multipleSeparator + subject.post;
+					jQuery.iAuto.lastValue = subject.item;
+					jQuery.iAuto.selection(
+						this, 
+						subject.pre.length + valueToAdd.length + this.autoCFG.multipleSeparator.length, 
+						subject.pre.length + valueToAdd.length + this.autoCFG.multipleSeparator.length
+					);
+					jQuery.iAuto.clear();
+					if (this.autoCFG.onSelect) {
+						iteration = parseInt(selectedItem.getAttribute('dir'))||0;
+						jQuery.iAuto.applyOn(this,this.autoCFG.lastSuggestion.get(iteration), 'onSelect');
+					}
+					if (this.scrollIntoView)
+						this.scrollIntoView(false);
+					return pressedKey != 13;
+					break;
+				//escape
+				case 27:
+					this.value = subject.pre + jQuery.iAuto.lastValue + this.autoCFG.multipleSeparator + subject.post;
+					this.autoCFG.lastSuggestion = null;
+					jQuery.iAuto.clear();
+					if (this.scrollIntoView)
+						this.scrollIntoView(false);
+					return false;
+					break;
+				//end
+				case 35:
+					jQuery.iAuto.selectedItem = jQuery.iAuto.items.size() - 1;
+					break;
+				//home
+				case 36:
+					jQuery.iAuto.selectedItem = 0;
+					break;
+				//up
+				case 38:
+					jQuery.iAuto.selectedItem --;
+					if (jQuery.iAuto.selectedItem < 0)
+						jQuery.iAuto.selectedItem = jQuery.iAuto.items.size() - 1;
+					break;
+				case 40:
+					jQuery.iAuto.selectedItem ++;
+					if (jQuery.iAuto.selectedItem == jQuery.iAuto.items.size())
+						jQuery.iAuto.selectedItem = 0;
+					break;
+			}
+			jQuery.iAuto.applyOn(this,this.autoCFG.lastSuggestion.get(jQuery.iAuto.selectedItem||0), 'onHighlight');
+			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = this.autoCFG.selectClass;
+			if (jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).scrollIntoView)
+				jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).scrollIntoView(false);
+			if(this.autoCFG.autofill) {
+				var valToAdd = jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).getAttribute('rel');
+				this.value = subject.pre + valToAdd + this.autoCFG.multipleSeparator + subject.post;
+				if(jQuery.iAuto.lastValue.length != valToAdd.length)
+					jQuery.iAuto.selection(
+						this, 
+						subject.pre.length + jQuery.iAuto.lastValue.length, 
+						subject.pre.length + valToAdd.length
+					);
+			}
+			return false;
+		}
+		jQuery.iAuto.checkCache.apply(this);
+		
+		if (this.autoCFG.inCache == false) {
+			if (subject.item != jQuery.iAuto.lastValue && subject.item.length >= this.autoCFG.minchars)
+				jQuery.iAuto.timer = window.setTimeout(jQuery.iAuto.update, this.autoCFG.delay);
+			if (jQuery.iAuto.items) {
+				jQuery.iAuto.clear();
+			}
+		}
+		return true;
+	},
+
+	applyOn: function(field, item, type)
+	{
+		if (field.autoCFG[type]) {
+			var data = {};
+			childs = item.getElementsByTagName('*');
+			for(i=0; i<childs.length; i++){
+				data[childs[i].tagName] = childs[i].firstChild.nodeValue;
+			}
+			field.autoCFG[type].apply(field,[data]);
+		}
+	},
+	
+	hoverItem : function(e)
+	{
+		if (jQuery.iAuto.items) {
+			if (jQuery.iAuto.selectedItem != null) 
+				jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
+			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
+			jQuery.iAuto.selectedItem = parseInt(this.getAttribute('dir'))||0;
+			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = jQuery.iAuto.subject.autoCFG.selectClass;
+		}
+	},
+
+	clickItem : function(event)
+	{	
+		window.clearTimeout(jQuery.iAuto.timer);
+		
+		event = event || jQuery.event.fix( window.event );
+		event.preventDefault();
+		event.stopPropagation();
+		var subject = jQuery.iAuto.getFieldValues(jQuery.iAuto.subject);
+		var valueToAdd = this.getAttribute('rel');
+		jQuery.iAuto.subject.value = subject.pre + valueToAdd + jQuery.iAuto.subject.autoCFG.multipleSeparator + subject.post;
+		jQuery.iAuto.lastValue = this.getAttribute('rel');
+		jQuery.iAuto.selection(
+			jQuery.iAuto.subject, 
+			subject.pre.length + valueToAdd.length + jQuery.iAuto.subject.autoCFG.multipleSeparator.length, 
+			subject.pre.length + valueToAdd.length + jQuery.iAuto.subject.autoCFG.multipleSeparator.length
+		);
+		jQuery.iAuto.clear();
+		if (jQuery.iAuto.subject.autoCFG.onSelect) {
+			iteration = parseInt(this.getAttribute('dir'))||0;
+			jQuery.iAuto.applyOn(jQuery.iAuto.subject,jQuery.iAuto.subject.autoCFG.lastSuggestion.get(iteration), 'onSelect');
+		}
+
+		return false;
+	},
+
+	protect : function(e)
+	{
+		pressedKey = e.charCode || e.keyCode || -1;
+		if (/13|27|35|36|38|40/.test(pressedKey) && jQuery.iAuto.items) {
+			if (window.event) {
+				window.event.cancelBubble = true;
+				window.event.returnValue = false;
+			} else {
+				e.preventDefault();
+				e.stopPropagation();
+			}
+			return false;
+		}
+	},
+
+	build : function(options)
+	{
+		if (!options.source || !jQuery.iUtil) {
+			return;
+		}
+
+		if (!jQuery.iAuto.helper) {
+			if (jQuery.browser.msie) {
+				jQuery('body', document).append('<iframe style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" id="autocompleteIframe" src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+				jQuery.iAuto.iframe = jQuery('#autocompleteIframe');
+			}
+			jQuery('body', document).append('<div id="autocompleteHelper" style="position: absolute; top: 0; left: 0; z-index: 30001; display: none;"><ul style="margin: 0;padding: 0; list-style: none; z-index: 30002;">&nbsp;</ul></div>');
+			jQuery.iAuto.helper = jQuery('#autocompleteHelper');
+			jQuery.iAuto.content = jQuery('ul', jQuery.iAuto.helper);
+		}
+
+		return this.each(
+			function()
+			{
+				if (this.tagName != 'INPUT' && this.getAttribute('type') != 'text' )
+					return;
+				this.autoCFG = {};
+				this.autoCFG.source = options.source;
+				this.autoCFG.minchars = Math.abs(parseInt(options.minchars)||1);
+				this.autoCFG.helperClass = options.helperClass ? options.helperClass : '';
+				this.autoCFG.selectClass = options.selectClass ? options.selectClass : '';
+				this.autoCFG.onSelect = options.onSelect && options.onSelect.constructor == Function ? options.onSelect : null;
+				this.autoCFG.onShow = options.onShow && options.onShow.constructor == Function ? options.onShow : null;
+				this.autoCFG.onHide = options.onHide && options.onHide.constructor == Function ? options.onHide : null;
+				this.autoCFG.onHighlight = options.onHighlight && options.onHighlight.constructor == Function ? options.onHighlight : null;
+				this.autoCFG.inputWidth = options.inputWidth||false;
+				this.autoCFG.multiple = options.multiple||false;
+				this.autoCFG.multipleSeparator = this.autoCFG.multiple ? (options.multipleSeparator||', '):'';
+				this.autoCFG.autofill = options.autofill ? true : false;
+				this.autoCFG.delay = Math.abs(parseInt(options.delay)||1000);
+				if (options.fx && options.fx.constructor == Object) {
+					if (!options.fx.type || !/fade|slide|blind/.test(options.fx.type)) {
+						options.fx.type = 'slide';
+					}
+					if (options.fx.type == 'slide' && !jQuery.fx.slide)
+						return;
+					if (options.fx.type == 'blind' && !jQuery.fx.BlindDirection)
+						return;
+
+					options.fx.duration = Math.abs(parseInt(options.fx.duration)||400);
+					if (options.fx.duration > this.autoCFG.delay) {
+						options.fx.duration = this.autoCFG.delay - 100;
+					}
+					this.autoCFG.fx = options.fx;
+				}
+				this.autoCFG.lastSuggestion = null;
+				this.autoCFG.inCache = false;
+
+				jQuery(this)
+					.attr('autocomplete', 'off')
+					.focus(
+						function()
+						{
+							jQuery.iAuto.subject = this;
+							jQuery.iAuto.lastValue = this.value;
+						}
+					)
+					.keypress(jQuery.iAuto.protect)
+					.keyup(jQuery.iAuto.autocomplete)
+					
+					.blur(
+						function()
+						{
+							jQuery.iAuto.timer = window.setTimeout(jQuery.iAuto.clear, 200);
+						}
+					);
+			}
+		);
+	}
+};
+jQuery.fn.Autocomplete = jQuery.iAuto.build;
\ No newline at end of file

Added: jifty/branches/jquery/share/web/static/js/iutil.js
==============================================================================
--- (empty file)
+++ jifty/branches/jquery/share/web/static/js/iutil.js	Sun Jan 13 00:53:34 2008
@@ -0,0 +1,245 @@
+/**
+ * Interface Elements for jQuery
+ * utility function
+ *
+ * http://interface.eyecon.ro
+ *
+ * Copyright (c) 2006 Stefan Petre
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ *
+ */
+
+jQuery.iUtil = {
+	getPosition : function(e)
+	{
+		var x = 0;
+		var y = 0;
+		var es = e.style;
+		var restoreStyles = false;
+		if (jQuery(e).css('display') == 'none') {
+			var oldVisibility = es.visibility;
+			var oldPosition = es.position;
+			restoreStyles = true;
+			es.visibility = 'hidden';
+			es.display = 'block';
+			es.position = 'absolute';
+		}
+		var el = e;
+		while (el){
+			x += el.offsetLeft + (el.currentStyle && !jQuery.browser.opera ?parseInt(el.currentStyle.borderLeftWidth)||0:0);
+			y += el.offsetTop + (el.currentStyle && !jQuery.browser.opera ?parseInt(el.currentStyle.borderTopWidth)||0:0);
+			el = el.offsetParent;
+		}
+		el = e;
+		while (el && el.tagName  && el.tagName.toLowerCase() != 'body')
+		{
+			x -= el.scrollLeft||0;
+			y -= el.scrollTop||0;
+			el = el.parentNode;
+		}
+		if (restoreStyles == true) {
+			es.display = 'none';
+			es.position = oldPosition;
+			es.visibility = oldVisibility;
+		}
+		return {x:x, y:y};
+	},
+	getPositionLite : function(el)
+	{
+		var x = 0, y = 0;
+		while(el) {
+			x += el.offsetLeft || 0;
+			y += el.offsetTop || 0;
+			el = el.offsetParent;
+		}
+		return {x:x, y:y};
+	},
+	getSize : function(e)
+	{
+		var w = jQuery.css(e,'width');
+		var h = jQuery.css(e,'height');
+		var wb = 0;
+		var hb = 0;
+		var es = e.style;
+		if (jQuery(e).css('display') != 'none') {
+			wb = e.offsetWidth;
+			hb = e.offsetHeight;
+		} else {
+			var oldVisibility = es.visibility;
+			var oldPosition = es.position;
+			es.visibility = 'hidden';
+			es.display = 'block';
+			es.position = 'absolute';
+			wb = e.offsetWidth;
+			hb = e.offsetHeight;
+			es.display = 'none';
+			es.position = oldPosition;
+			es.visibility = oldVisibility;
+		}
+		return {w:w, h:h, wb:wb, hb:hb};
+	},
+	getSizeLite : function(el)
+	{
+		return {
+			wb:el.offsetWidth||0,
+			hb:el.offsetHeight||0
+		};
+	},
+	getClient : function(e)
+	{
+		var h, w, de;
+		if (e) {
+			w = e.clientWidth;
+			h = e.clientHeight;
+		} else {
+			de = document.documentElement;
+			w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
+			h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
+		}
+		return {w:w,h:h};
+	},
+	getScroll : function (e)
+	{
+		var t=0, l=0, w=0, h=0, iw=0, ih=0;
+		if (e && e.nodeName.toLowerCase() != 'body') {
+			t = e.scrollTop;
+			l = e.scrollLeft;
+			w = e.scrollWidth;
+			h = e.scrollHeight;
+			iw = 0;
+			ih = 0;
+		} else  {
+			if (document.documentElement) {
+				t = document.documentElement.scrollTop;
+				l = document.documentElement.scrollLeft;
+				w = document.documentElement.scrollWidth;
+				h = document.documentElement.scrollHeight;
+			} else if (document.body) {
+				t = document.body.scrollTop;
+				l = document.body.scrollLeft;
+				w = document.body.scrollWidth;
+				h = document.body.scrollHeight;
+			}
+			iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;
+			ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;
+		}
+		return { t: t, l: l, w: w, h: h, iw: iw, ih: ih };
+	},
+	getMargins : function(e, toInteger)
+	{
+		var el = jQuery(e);
+		var t = el.css('marginTop') || '';
+		var r = el.css('marginRight') || '';
+		var b = el.css('marginBottom') || '';
+		var l = el.css('marginLeft') || '';
+		if (toInteger)
+			return {
+				t: parseInt(t)||0,
+				r: parseInt(r)||0,
+				b: parseInt(b)||0,
+				l: parseInt(l)
+			};
+		else
+			return {t: t, r: r,	b: b, l: l};
+	},
+	getPadding : function(e, toInteger)
+	{
+		var el = jQuery(e);
+		var t = el.css('paddingTop') || '';
+		var r = el.css('paddingRight') || '';
+		var b = el.css('paddingBottom') || '';
+		var l = el.css('paddingLeft') || '';
+		if (toInteger)
+			return {
+				t: parseInt(t)||0,
+				r: parseInt(r)||0,
+				b: parseInt(b)||0,
+				l: parseInt(l)
+			};
+		else
+			return {t: t, r: r,	b: b, l: l};
+	},
+	getBorder : function(e, toInteger)
+	{
+		var el = jQuery(e);
+		var t = el.css('borderTopWidth') || '';
+		var r = el.css('borderRightWidth') || '';
+		var b = el.css('borderBottomWidth') || '';
+		var l = el.css('borderLeftWidth') || '';
+		if (toInteger)
+			return {
+				t: parseInt(t)||0,
+				r: parseInt(r)||0,
+				b: parseInt(b)||0,
+				l: parseInt(l)||0
+			};
+		else
+			return {t: t, r: r,	b: b, l: l};
+	},
+	getPointer : function(event)
+	{
+		var x = event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)) || 0;
+		var y = event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)) || 0;
+		return {x:x, y:y};
+	},
+	traverseDOM : function(nodeEl, func)
+	{
+		func(nodeEl);
+		nodeEl = nodeEl.firstChild;
+		while(nodeEl){
+			jQuery.iUtil.traverseDOM(nodeEl, func);
+			nodeEl = nodeEl.nextSibling;
+		}
+	},
+	purgeEvents : function(nodeEl)
+	{
+		jQuery.iUtil.traverseDOM(
+			nodeEl,
+			function(el)
+			{
+				for(var attr in el){
+					if(typeof el[attr] === 'function') {
+						el[attr] = null;
+					}
+				}
+			}
+		);
+	},
+	centerEl : function(el, axis)
+	{
+		var clientScroll = jQuery.iUtil.getScroll();
+		var windowSize = jQuery.iUtil.getSize(el);
+		if (!axis || axis == 'vertically')
+			jQuery(el).css(
+				{
+					top: clientScroll.t + ((Math.max(clientScroll.h,clientScroll.ih) - clientScroll.t - windowSize.hb)/2) + 'px'
+				}
+			);
+		if (!axis || axis == 'horizontally')
+			jQuery(el).css(
+				{
+					left:	clientScroll.l + ((Math.max(clientScroll.w,clientScroll.iw) - clientScroll.l - windowSize.wb)/2) + 'px'
+				}
+			);
+	},
+	fixPNG : function (el, emptyGIF) {
+		var images = jQuery('img[@src*="png"]', el||document), png;
+		images.each( function() {
+			png = this.src;				
+			this.src = emptyGIF;
+			this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + png + "')";
+		});
+	}
+};
+
+// Helper function to support older browsers!
+[].indexOf || (Array.prototype.indexOf = function(v, n){
+	n = (n == null) ? 0 : n;
+	var m = this.length;
+	for (var i=n; i<m; i++)
+		if (this[i] == v)
+			return i;
+	return -1;
+});

Modified: jifty/branches/jquery/share/web/static/js/jifty.js
==============================================================================
--- jifty/branches/jquery/share/web/static/js/jifty.js	(original)
+++ jifty/branches/jquery/share/web/static/js/jifty.js	Sun Jan 13 00:53:34 2008
@@ -1379,103 +1379,64 @@
     return this;
 };
 
-jQuery.extend(Jifty.Autocompleter.prototype, Ajax.Autocompleter.prototype);
-
 jQuery.extend(Jifty.Autocompleter.prototype, {
-  initialize: function(field, div) {
-    this.field  = Jifty.$(field);
-    this.action = Form.Element.getAction(this.field);
-    this.url    = '/__jifty/autocomplete.xml';
-
-    var self = this;
-    jQuery(this.field).bind("focus", function(event) {
-        self.onFocus(event);
-    });
-      
-    this.baseInitialize(this.field, Jifty.$(div), {
-        minChars: "0",
-        beforeShow: this.beforeShow,
-        beforeHide: this.beforeHide,
-        frequency: 0.1,
-        onShow: this.onShow,
-        onHide: this.onHide,
-        afterUpdateElement: this.afterUpdate
-    });
-  },
-
-  onShow: function(element, update) {
-      if(!update.style.position || update.style.position=='absolute') {
-        update.style.position = 'absolute';
-        Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
-      }
-      jQuery(update).show();
-  },
-
-  onHide: function(element, update) {
-      jQuery(update).hide();
-  },
+    initialize: function(field, div) {
+        this.field  = Jifty.$(field);
+        this.action = Form.Element.getAction(this.field);
+        this.url    = '/__jifty/autocomplete.xml';
+
+        var self = this;
+        jQuery(this.field).bind("focus", function(event) {
+            self.changed  = true;
+            self.hasFocus = true;
+            Jifty.current_autocompleter_object = self;
+        });
+        
+        jQuery(this.field).Autocomplete({
+            source: this.url,
+            minchars: 0,
+            delay: 100,
+            helperClass: 'autocomplete',
+            selectClass: 'selected'
+        });
+    },
+
+    beforeShow: function() {
+        /* Prevents the race for canonicalization and updating via autocomplete */
+        if ( this.field.onblur ) {
+            this.element._onblur = this.element.onblur;
+            this.element.onblur  = null;
+        }
+    },
 
-  beforeShow: function(obj) {
-    /* Prevents the race for canonicalization and updating
-       via autocomplete */
-    if ( obj.element.onblur ) {
-        obj.element._onblur = obj.element.onblur;
-        obj.element.onblur  = null;
-    }
-  },
+    beforeHide: function() {
+        /* Restore onblur and config option */
+        if ( this.element._onblur ) {
+            this.element.onblur  = this.element._onblur;
+            this.element._onblur = null;
+        }
+    },
 
-  beforeHide: function(obj) {
-    /* Restore onblur and config option */
-    if ( obj.element._onblur ) {
-        obj.element.onblur  = obj.element._onblur;
-        obj.element._onblur = null;
+    afterUpdate: function(field, selection) {
+        Form.Element.validate(field);
+    },
+
+    buildRequest: function() {
+        var request = { path: this.url, actions: {} };
+        var a = {};
+        a['moniker'] = 'autocomplete';
+        a['class']   = 'Jifty::Action::Autocomplete';
+        a['fields']  = {};
+        a['fields']['moniker']  = this.action.moniker;
+        a['fields']['argument'] = Form.Element.getField(this.field);
+        request['actions']['autocomplete'] = a;
+        request['actions'][this.action.moniker] = this.action.data_structure();
+        request['actions'][this.action.moniker]['active']  = 0;
+        return request;
     }
-  },
-
-  onFocus: function(event) {
-    this.changed  = true;
-    this.hasFocus = true;
-
-    if (this.observer)
-        clearTimeout(this.observer);
-
-    this.onObserverEvent();
-  },
-
-  afterUpdate: function(field, selection) {
-     Form.Element.validate(field);
-  },
-
-  getUpdatedChoices: function() {
-      var request = { path: this.url, actions: {} };
-
-      var a = {};
-      a['moniker'] = 'autocomplete';
-      a['class']   = 'Jifty::Action::Autocomplete';
-      a['fields']  = {};
-      a['fields']['moniker']  = this.action.moniker;
-      a['fields']['argument'] = Form.Element.getField(this.field);
-      request['actions']['autocomplete'] = a;
-      request['actions'][this.action.moniker] = this.action.data_structure();
-      request['actions'][this.action.moniker]['active']  = 0;
-      
-      var self = this;
-      jQuery.ajax({
-          url: this.url,
-          type: 'post',
-          data: JSON.stringify(request),
-          complete: function(xhr, status) {
-              self.onComplete(xhr);
-          },
-          beforeSend: function(xhr) {
-              xhr.setRequestHeader('Content-Type', 'text/x-json');
-          }
-      });
-
-
-  }
 });
 
+
 Jifty.Placeholder = function() {
     this.initialize.apply(this, arguments);
     return this;

Added: jifty/branches/jquery/share/web/static/js/jifty_interface.js
==============================================================================
--- (empty file)
+++ jifty/branches/jquery/share/web/static/js/jifty_interface.js	Sun Jan 13 00:53:34 2008
@@ -0,0 +1,59 @@
+/**
+ * This file overrides functions defined in Interface Elements for jQuery (http://interface.eyecon.ro)
+ * so they can work with Jifty. It must be loaded after all Interface scripts, and better before
+ * jquery_noconflict.js
+ */
+
+jQuery.iAuto.update = function() {
+    var subject = jQuery.iAuto.subject;
+    var subjectValue = jQuery.iAuto.getFieldValues(subject);
+    //var selectionStart = jQuery.iAuto.getSelectionStart(subject);
+    if (subject && subjectValue.item != jQuery.iAuto.lastValue && subjectValue.item.length >= subject.autoCFG.minchars) {
+	jQuery.iAuto.lastValue = subjectValue.item;
+	jQuery.iAuto.currentValue = subjectValue.item;
+
+        var request = Jifty.current_autocompleter_object.buildRequest();
+	jQuery.ajax(
+	    {
+		type: 'post',
+		data: JSON.stringify(request),
+		success: function(xml)
+		{
+		    subject.autoCFG.lastSuggestion = jQuery('li',xml);
+		    size = subject.autoCFG.lastSuggestion.size();
+		    if (size > 0) {
+			var toWrite = '';
+
+			subject.autoCFG.lastSuggestion.each(
+			    function(nr) {
+				toWrite += '<li rel="' + jQuery(this).text() + '" dir="' + nr + '" style="cursor: default;">' + jQuery(this).text() + '</li>';
+			    }
+			);
+                        
+			if (subject.autoCFG.autofill) {
+			    var valueToAdd = jQuery('value', subject.autoCFG.lastSuggestion.get(0)).text();
+			    subject.value = subjectValue.pre + valueToAdd + subject.autoCFG.multipleSeparator + subjectValue.post;
+			    jQuery.iAuto.selection(
+				subject, 
+				subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + subjectValue.item.length) : valueToAdd.length,
+				subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + valueToAdd.length) : valueToAdd.length
+			    );
+			}
+			
+			if (size > 0) {
+			    jQuery.iAuto.writeItems(subject, toWrite);
+			} else {
+			    jQuery.iAuto.clear();
+			}
+		    } else {
+			jQuery.iAuto.clear();
+		    }
+		},
+                beforeSend: function(xhr) {
+                    xhr.setRequestHeader('Content-Type', 'text/x-json');
+                },
+		url : subject.autoCFG.source
+	    }
+	);
+    }
+};


More information about the Jifty-commit mailing list