(function($){
$.fn.ajaxSubmit=function(options){
var encode=function(v){
return escape(v);}
if(!this.length){
log('ajaxSubmit: skipping submit process - no element selected');
return this;}
if(typeof options=='function')
options={success:options};
options=$.extend({
url:this.attr('action')||window.location.toString(),
type:this.attr('method')||'GET'},options||{});
var veto={};
this.trigger('form-pre-serialize',[this,options,veto]);
if(veto.veto){
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
return this;}
var a=this.formToArray(options.semantic);
if(options.data){
options.extraData=options.data;
for(var n in options.data)
a.push({name:n,value:options.data[n]});}
if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false){
log('ajaxSubmit: submit aborted via beforeSubmit callback');
return this;}
this.trigger('form-submit-validate',[a,this,options,veto]);
if(veto.veto){
log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
return this;}
var q=this.param(a);
if(options.type.toUpperCase()=='GET'){
options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;
options.data=null;}
else
options.data=q;
var $form=this,callbacks=[];
if(options.resetForm)callbacks.push(function(){$form.resetForm();});
if(options.clearForm)callbacks.push(function(){$form.clearForm();});
if(!options.dataType&&options.target){
var oldSuccess=options.success||function(){};
callbacks.push(function(data){
$(options.target).html(data).each(oldSuccess,arguments);});}
else if(options.success)
callbacks.push(options.success);
options.success=function(data,status){
for(var i=0,max=callbacks.length;i<max;i++)
callbacks[i](data,status,$form);};
var files=$('input:file',this).fieldValue();
var found=false;
for(var j=0;j<files.length;j++)
if(files[j])
found=true;
if(options.iframe||found){
if($.browser.safari&&options.closeKeepAlive)
$.get(options.closeKeepAlive,fileUpload);
else
fileUpload();}
else
$.ajax(options);
this.trigger('form-submit-notify',[this,options]);
return this;
function fileUpload(){
var form=$form[0];
if($(':input[@name=submit]',form).length){
alert('Error: Form elements must not be named "submit".');
return;}
var opts=$.extend({},$.ajaxSettings,options);
var id='jqFormIO'+(new Date().getTime());
var $io=$('<iframe id="'+id+'" name="'+id+'" />');
var io=$io[0];
if($.browser.msie||$.browser.opera)
io.src='javascript:false;document.write("");';
$io.css({position:'absolute',top:'-1000px',left:'-1000px'});
var xhr={
responseText:null,
responseXML:null,
status:0,
statusText:'n/a',
getAllResponseHeaders:function(){},
getResponseHeader:function(){},
setRequestHeader:function(){}};
var g=opts.global;
if(g&&!$.active++)$.event.trigger("ajaxStart");
if(g)$.event.trigger("ajaxSend",[xhr,opts]);
var cbInvoked=0;
var timedOut=0;
var sub=form.clk;
if(sub){
var n=sub.name;
if(n&&!sub.disabled){
options.extraData=options.extraData||{};
options.extraData[n]=sub.value;
if(sub.type=="image"){
options.extraData[name+'.x']=form.clk_x;
options.extraData[name+'.y']=form.clk_y;}}}
setTimeout(function(){
var t=$form.attr('target'),a=$form.attr('action');
$form.attr({
target:id,
encoding:'multipart/form-data',
enctype:'multipart/form-data',
method:'POST',
action:opts.url});
if(opts.timeout)
setTimeout(function(){timedOut=true;cb();},opts.timeout);
var extraInputs=[];
try{
if(options.extraData)
for(var n in options.extraData)
extraInputs.push(
$('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
.appendTo(form)[0]);
$io.appendTo('body');
io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false);
form.submit();}
finally{
$form.attr('action',a);
t?$form.attr('target',t):$form.removeAttr('target');
$(extraInputs).remove();}},10);
function cb(){
if(cbInvoked++)return;
io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);
var operaHack=0;
var ok=true;
try{
if(timedOut)throw 'timeout';
var data,doc;
doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;
if(doc.body==null&&!operaHack&&$.browser.opera){
operaHack=1;
cbInvoked--;
setTimeout(cb,100);
return;}
xhr.responseText=doc.body?doc.body.innerHTML:null;
xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;
xhr.getResponseHeader=function(header){
var headers={'content-type':opts.dataType};
return headers[header];};
if(opts.dataType=='json'||opts.dataType=='script'){
var ta=doc.getElementsByTagName('textarea')[0];
xhr.responseText=ta?ta.value:xhr.responseText;}
else if(opts.dataType=='xml'&&!xhr.responseXML&&xhr.responseText!=null){
xhr.responseXML=toXml(xhr.responseText);}
data=$.httpData(xhr,opts.dataType);}
catch(e){
ok=false;
$.handleError(opts,xhr,'error',e);}
if(ok){
opts.success(data,'success');
if(g)$.event.trigger("ajaxSuccess",[xhr,opts]);}
if(g)$.event.trigger("ajaxComplete",[xhr,opts]);
if(g&&!--$.active)$.event.trigger("ajaxStop");
if(opts.complete)opts.complete(xhr,ok?'success':'error');
setTimeout(function(){
$io.remove();
xhr.responseXML=null;},100);};
function toXml(s,doc){
if(window.ActiveXObject){
doc=new ActiveXObject('Microsoft.XMLDOM');
doc.async='false';
doc.loadXML(s);}
else
doc=(new DOMParser()).parseFromString(s,'text/xml');
return(doc&&doc.documentElement&&doc.documentElement.tagName!='parsererror')?doc:null;};};};
$.fn.ajaxForm=function(options){
return this.ajaxFormUnbind().bind('submit.form-plugin',function(){
$(this).ajaxSubmit(options);
return false;}).each(function(){
$(":submit,input:image",this).bind('click.form-plugin',function(e){
var $form=this.form;
$form.clk=this;
if(this.type=='image'){
if(e.offsetX!=undefined){
$form.clk_x=e.offsetX;
$form.clk_y=e.offsetY;}else if(typeof $.fn.offset=='function'){
var offset=$(this).offset();
$form.clk_x=e.pageX-offset.left;
$form.clk_y=e.pageY-offset.top;}else{
$form.clk_x=e.pageX-this.offsetLeft;
$form.clk_y=e.pageY-this.offsetTop;}}
setTimeout(function(){$form.clk=$form.clk_x=$form.clk_y=null;},10);});});};
$.fn.ajaxFormUnbind=function(){
this.unbind('submit.form-plugin');
return this.each(function(){
$(":submit,input:image",this).unbind('click.form-plugin');});};
$.fn.formToArray=function(semantic){
var a=[];
if(this.length==0)return a;
var form=this[0];
var els=semantic?form.getElementsByTagName('*'):form.elements;
if(!els)return a;
for(var i=0,max=els.length;i<max;i++){
var el=els[i];
var n=el.name;
if(!n)continue;
if(semantic&&form.clk&&el.type=="image"){
if(!el.disabled&&form.clk==el)
a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});
continue;}
var v=$.fieldValue(el,true);
if(v&&v.constructor==Array){
for(var j=0,jmax=v.length;j<jmax;j++)
a.push({name:n,value:v[j]});}
else if(v!==null&&typeof v!='undefined')
a.push({name:n,value:v});}
if(!semantic&&form.clk){
var inputs=form.getElementsByTagName("input");
for(var i=0,max=inputs.length;i<max;i++){
var input=inputs[i];
var n=input.name;
if(n&&!input.disabled&&input.type=="image"&&form.clk==input)
a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}}
return a;};
$.fn.formSerialize=function(semantic){
return this.param(this.formToArray(semantic));};
$.fn.fieldSerialize=function(successful){
var a=[];
this.each(function(){
var n=this.name;
if(!n)return;
var v=$.fieldValue(this,successful);
if(v&&v.constructor==Array){
for(var i=0,max=v.length;i<max;i++)
a.push({name:n,value:v[i]});}
else if(v!==null&&typeof v!='undefined')
a.push({name:this.name,value:v});});
return this.param(a);};
$.fn.fieldValue=function(successful){
for(var val=[],i=0,max=this.length;i<max;i++){
var el=this[i];
var v=$.fieldValue(el,successful);
if(v===null||typeof v=='undefined'||(v.constructor==Array&&!v.length))
continue;
v.constructor==Array?$.merge(val,v):val.push(v);}
return val;};
$.fieldValue=function(el,successful){
var n=el.name,t=el.type,tag=el.tagName.toLowerCase();
if(typeof successful=='undefined')successful=true;
if(successful&&(!n||el.disabled||t=='reset'||t=='button'||(t=='checkbox'||t=='radio')&&!el.checked||(t=='submit'||t=='image')&&el.form&&el.form.clk!=el||
tag=='select'&&el.selectedIndex==-1))
return null;
if(tag=='select'){
var index=el.selectedIndex;
if(index<0)return null;
var a=[],ops=el.options;
var one=(t=='select-one');
var max=(one?index+1:ops.length);
for(var i=(one?index:0);i<max;i++){
var op=ops[i];
if(op.selected){
var v=$.browser.msie&&!(op.attributes['value'].specified)?op.text:op.value;
if(one)return v;
a.push(v);}}
return a;}
return el.value;};
$.fn.clearForm=function(){
return this.each(function(){
$('input,select,textarea',this).clearFields();});};
$.fn.clearFields=$.fn.clearInputs=function(){
return this.each(function(){
var t=this.type,tag=this.tagName.toLowerCase();
if(t=='text'||t=='password'||tag=='textarea')
this.value='';
else if(t=='checkbox'||t=='radio')
this.checked=false;
else if(tag=='select')
this.selectedIndex=-1;});};
$.fn.resetForm=function(){
return this.each(function(){
if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType))
this.reset();});};
$.fn.param=function(a){
var encode=function(v){
return/[^\x00-\xff]/g.test(v)?escape(v):v;}
var s=[];
if(a.constructor==Array||a.jquery)
jQuery.each(a,function(){
s.push(encode(this.name)+"="+encode(this.value));});
else
for(var j in a)
if(a[j]&&a[j].constructor==Array)
jQuery.each(a[j],function(){
s.push(encode(j)+"="+encode(this));});
else
s.push(encode(j)+"="+encode(a[j]));
return s.join("&").replace(/%20/g,"+");}
$.fn.enable=function(b){
if(b==undefined)b=true;
return this.each(function(){
this.disabled=!b});};
$.fn.select=function(select){
if(select==undefined)select=true;
return this.each(function(){
var t=this.type;
if(t=='checkbox'||t=='radio')
this.checked=select;
else if(this.tagName.toLowerCase()=='option'){
var $sel=$(this).parent('select');
if(select&&$sel[0]&&$sel[0].type=='select-one'){
$sel.find('option').select(false);}
this.selected=select;}});};
function log(){
if($.fn.ajaxSubmit.debug&&window.console&&window.console.log)
window.console.log('[jquery.form] '+Array.prototype.join.call(arguments,''));};})(jQuery);

