;(function($)
{
	
$.fn.ajaxForm = function(options)
{
	var defaults = 
	{
		preStart: $.noop, 
		
		dataType: 'html', 
		
		ajaxStart:    $.noop, 
		ajaxSuccess:  $.noop, 
		ajaxError:    $.noop, 
		ajaxComplete: $.noop
	};
	var settings = $.extend(defaults, options);
	
	$(this).each(function()
	{
		var $this = $(this);
		$this.find(':submit, :input[type=image]').click(function(e)
		{
			var $button = $(this);
			$this.data('submitter', $button);
		});
	});
	
	$(this).submit(function(e)
	{
		e.preventDefault();
		
		// Collect data, don't collect .
		var postData   = new Object();
		var $submitter = $(this).data('submitter');
		$(':input:not(:submit):not(:input[type=image])', this).filter(function(index)
		{
			postData[$(this).attr('name')] = $(this).val();
		});
		postData[$submitter.attr('name')]        = $submitter.val();
		postData[$submitter.attr('name') + '.x'] = '';
		
		// Trigger preStart, continue if the result returned is not explicitly false.
		var result = settings.preStart.apply(this, Array.prototype.slice.call($.extend(arguments, postData), 0, 0));
		if(result === false) return false;
		
		// Trigger ajaxStart.
		settings.ajaxStart.apply(this, Array.prototype.slice.call($.extend(arguments, postData), 0, 0));
		
		// Send data.
		(function($this)
		{
			$.ajax(
			{
				url:      settings.url || $this.attr('action') || window.location.toString(), 
				type:     settings.type || $this.attr('method') || 'GET', 
				dataType: settings.dataType, 
				data:     postData, // To be based on the form data.
				
				// Note we'll pass the original form object into the ajax event handlers.
				success:  function()
				{
					settings.ajaxSuccess.apply(this, Array.prototype.slice.call($.makeArray(arguments).concat([$this]), 0, 4));
				}, 
				error:    function()
				{
					settings.ajaxError.apply(this, Array.prototype.slice.call($.makeArray(arguments).concat([$this]), 0, 4));
				}, 
				complete: function()
				{
					settings.ajaxComplete.apply(this, Array.prototype.slice.call($.makeArray(arguments).concat([$this]), 0, 3));
				}
			});
		})($(this));
	});
	return this;
};
	
})(jQuery);
