diff options
| author | wei <> | 2006-08-30 23:28:51 +0000 | 
|---|---|---|
| committer | wei <> | 2006-08-30 23:28:51 +0000 | 
| commit | 2fda7f49f3792a0718838742b76a4b533c169af9 (patch) | |
| tree | 46a5a3eb53a0d64fc25894bfd219a82cecffa807 /framework/Web/Javascripts | |
| parent | 1f560ccd8a9e21871dbedd548fc97f231131c771 (diff) | |
Updated TInPlaceTextBox
Diffstat (limited to 'framework/Web/Javascripts')
| -rw-r--r-- | framework/Web/Javascripts/js/compressed/ajax.js | 354 | ||||
| -rw-r--r-- | framework/Web/Javascripts/js/compressed/prado.js | 128 | ||||
| -rw-r--r-- | framework/Web/Javascripts/js/compressed/validator.js | 8 | ||||
| -rw-r--r-- | framework/Web/Javascripts/js/debug/ajax.js | 2599 | ||||
| -rw-r--r-- | framework/Web/Javascripts/js/debug/prado.js | 723 | ||||
| -rw-r--r-- | framework/Web/Javascripts/js/debug/validator.js | 19 | ||||
| -rw-r--r-- | framework/Web/Javascripts/prado/inlineeditor.js | 30 | ||||
| -rw-r--r-- | framework/Web/Javascripts/prado/validation3.js | 6 | 
8 files changed, 1868 insertions, 1999 deletions
diff --git a/framework/Web/Javascripts/js/compressed/ajax.js b/framework/Web/Javascripts/js/compressed/ajax.js index f39f8325..b65892cc 100644 --- a/framework/Web/Javascripts/js/compressed/ajax.js +++ b/framework/Web/Javascripts/js/compressed/ajax.js @@ -5,7 +5,7 @@ this.responders.push(responderToAdd);},unregister:function(responderToRemove){th  Object.extend(this.options,options||{});},responseIsSuccess:function(){return this.transport.status==undefined||this.transport.status==0||(this.transport.status>=200&&this.transport.status<300);},responseIsFailure:function(){return!this.responseIsSuccess();}}  Ajax.Request=Class.create();Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];Ajax.Request.prototype=Object.extend(new Ajax.Base(),{initialize:function(url,options){this.transport=Ajax.getTransport();this.setOptions(options);this.request(url);},request:function(url){var parameters=this.options.parameters||'';if(parameters.length>0)parameters+='&_=';try{this.url=url;if(this.options.method=='get'&¶meters.length>0)  this.url+=(this.url.match(/\?/)?'&':'?')+parameters;Ajax.Responders.dispatch('onCreate',this,this.transport);this.transport.open(this.options.method,this.url,this.options.asynchronous);if(this.options.asynchronous){this.transport.onreadystatechange=this.onStateChange.bind(this);setTimeout((function(){this.respondToReadyState(1)}).bind(this),10);} -this.setRequestHeaders();var body=this.options.postBody?this.options.postBody:parameters;this.transport.send(this.options.method=='post'?body:null);}catch(e){this.dispatchException(e);}},setRequestHeaders:function(){var requestHeaders=['X-Requested-With','XMLHttpRequest','X-Prototype-Version',Prototype.Version,'Accept','text/javascript, text/html, application/xml, text/xml, */*'];if(this.options.method=='post'){requestHeaders.push('Content-type',this.options.contentType);if(this.transport.overrideMimeType) +this.setRequestHeaders();var body=this.options.postBody?this.options.postBody:parameters;this.transport.send(this.options.method=='post'?body:null);}catch(e){this.dispatchException(e);}},setRequestHeaders:function(){var requestHeaders=['X-Requested-With','XMLHttpRequest','X-Prototype-Version',Prototype.Version,'Accept','text/javascript, text/html, application/xml, text/xml'];if(this.options.method=='post'){requestHeaders.push('Content-type',this.options.contentType);if(this.transport.overrideMimeType)  requestHeaders.push('Connection','close');}  if(this.options.requestHeaders)  requestHeaders.push.apply(requestHeaders,this.options.requestHeaders);for(var i=0;i<requestHeaders.length;i+=2) @@ -20,74 +20,92 @@ this.transport=Ajax.getTransport();this.setOptions(options);var onComplete=this.  response=response.stripScripts();if(receiver){if(this.options.insertion){new this.options.insertion(receiver,response);}else{Element.update(receiver,response);}}  if(this.responseIsSuccess()){if(this.onComplete)  setTimeout(this.onComplete.bind(this),10);}}});Ajax.PeriodicalUpdater=Class.create();Ajax.PeriodicalUpdater.prototype=Object.extend(new Ajax.Base(),{initialize:function(container,url,options){this.setOptions(options);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=container;this.url=url;this.start();},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent();},stop:function(){this.updater.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments);},updateComplete:function(request){if(this.options.decay){this.decay=(request.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=request.responseText;} -this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});Prado.AJAX={Service:'Prototype'};Prado.AJAX.EvalScript=function(output) -{var match=new RegExp(Ajax.Updater.ScriptFragment,'img');var scripts=output.match(match);if(scripts) -{match=new RegExp(Ajax.Updater.ScriptFragment,'im');setTimeout((function() -{for(var i=0;i<scripts.length;i++) -eval(scripts[i].match(match)[1]);}).bind(this),50);}} -Prado.AJAX.Request=Class.create();Prado.AJAX.Request.prototype=Object.extend(Ajax.Request.prototype,{evalJSON:function() +this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});Object.extend(Ajax.Request.prototype,{respondToReadyState:function(readyState) +{var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);if(event=='Complete')  {try -{var json=this.transport.getResponseHeader('X-JSON'),object;object=eval(json);return object;} +{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(this,json);}catch(e){this.dispatchException(e);} +if((this.header('Content-type')||'').match(/^text\/javascript/i)) +this.evalResponse();} +try{(this.options['on'+event]||Prototype.emptyFunction)(this,json);Ajax.Responders.dispatch('on'+event,this,transport,json);}catch(e){this.dispatchException(e);} +if(event=='Complete') +this.transport.onreadystatechange=Prototype.emptyFunction;},getHeaderData:function(name) +{try +{var json=this.header(name);return eval('('+json+')');} +catch(e) +{if(typeof(json)=="string") +return Prado.CallbackRequest.decode(json);}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',FIELD_POSTBACK_TARGET:'PRADO_POSTBACK_TARGET',FIELD_POSTBACK_PARAMETER:'PRADO_POSTBACK_PARAMETER',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',PAGESTATE_HEADER:'X-PRADO-PAGESTATE',requestInProgress:null,addPostLoaders:function(ids) +{this.PostDataLoaders=this.PostDataLoaders.concat(ids);list=[];this.PostDataLoaders.each(function(id) +{if(list.indexOf(id)<0) +list.push(id);});this.PostDataLoaders=list;},dispatchActions:function(transport,actions) +{if(actions&&actions.length>0) +actions.each(this.__run.bind(this,transport));},__run:function(transport,command) +{for(var method in command) +{try +{method.toFunction().apply(this,command[method].concat(transport));}  catch(e) -{if(isString(json)) -{return Prado.AJAX.JSON.parse(json);}}},respondToReadyState:function(readyState){var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.evalJSON();if(event=='Complete'&&transport.status) -Ajax.Responders.dispatch('on'+transport.status,this,transport,json);(this.options['on'+event]||Prototype.emptyFunction)(transport,json);Ajax.Responders.dispatch('on'+event,this,transport,json);if(event=='Complete') -(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(transport,json);if(event=='Complete') -this.transport.onreadystatechange=Prototype.emptyFunction;}});Prado.AJAX.Error=function(e,code) -{e.name='Prado.AJAX.Error';e.code=code;return e;} -Prado.AJAX.RequestBuilder=Class.create();Prado.AJAX.RequestBuilder.prototype={initialize:function() -{this.body='';this.data=[];},encode:function(data) -{return Prado.AJAX.JSON.stringify(data);},build:function(data) -{var sep='';for(var argName in data) -{if(isFunction(data[argName]))continue;try -{this.body+=sep+argName+'=';this.body+=encodeURIComponent(this.encode(data[argName]));}catch(e){throw Prado.AJAX.Error(e,1006);} -sep='&';}},getAll:function() -{this.build(this.data);return this.body;}} -Prado.AJAX.RemoteObject=function(){};Prado.AJAX.RemoteObject.Request=Class.create();Prado.AJAX.RemoteObject.Request.prototype=Object.extend(Prado.AJAX.Request.prototype,{initialize:function(options) -{this.transport=Ajax.getTransport();this.setOptions(options);this.post=new Prado.AJAX.RequestBuilder();},invokeRemoteObject:function(url,args) -{this.initParameters(args);this.options.postBody=this.post.getAll();this.request(url);},initParameters:function(args) -{this.post.data['__parameters']=[];for(var i=0;i<args.length;i++) -this.post.data['__parameters'][i]=args[i];}});Prado.AJAX.RemoteObject.prototype={baseInitialize:function(handlers,options) -{this.__handlers=handlers||{};this.__service=new Prado.AJAX.RemoteObject.Request(options);},__call:function(url,method,args) -{this.__service.options.onSuccess=this.__onSuccess.bind(this);this.__callback=method;return this.__service.invokeRemoteObject(url+"/"+method,args);},__onSuccess:function(transport,json) -{if(this.__handlers[this.__callback]) -this.__handlers[this.__callback](json,transport.responseText);}};Prado.AJAX.Exception={"on505":function(request,transport,e) -{var msg='HTTP '+transport.status+" with response";Logger.error(msg,transport.responseText);Logger.exception(e);},onComplete:function(request,transport,e) -{if(transport.status!=505) -{var msg='HTTP '+transport.status+" with response : \n";msg+=transport.responseText+"\n";msg+="Data : \n"+inspect(e);Logger.warn(msg);}},format:function(e) +{if(typeof(Logger)!="undefined") +Prado.CallbackRequest.Exception.onException(null,e);}}},Exception:{"on500":function(request,transport,data) +{var e=request.getHeaderData(Prado.CallbackRequest.ERROR_HEADER);Logger.error("Callback Server Error "+e.code,this.formatException(e));},'on200':function(request,transport,data) +{if(transport.status<500) +{var msg='HTTP '+transport.status+" with response : \n";msg+=transport.responseText+"\n";msg+="Data : \n"+inspect(data)+"\n";msg+="Actions : \n";data=request.getHeaderData(Prado.CallbackRequest.ACTION_HEADER);if(data&&data.length>0) +{data.each(function(action) +{msg+=inspect(action)+"\n";});} +Logger.warn(msg);}},onException:function(request,e) +{msg="";$H(e).each(function(item) +{msg+=item.key+": "+item.value+"\n";}) +Logger.error('Uncaught Callback Client Exception:',msg);},formatException:function(e)  {var msg=e.type+" with message \""+e.message+"\"";msg+=" in "+e.file+"("+e.line+")\n";msg+="Stack trace:\n";var trace=e.trace;for(var i=0;i<trace.length;i++)  {msg+="  #"+i+" "+trace[i].file;msg+="("+trace[i].line+"): ";msg+=trace[i]["class"]+"->"+trace[i]["function"]+"()"+"\n";} -return msg;},logException:function(e) -{var msg=Prado.AJAX.Exception.format(e);Logger.error("Server Error "+e.code,msg);}} -Event.OnLoad(function() +msg+=e.version+" "+e.time+"\n";return msg;}},encode:function(data) +{return Prado.JSON.stringify(data);},decode:function(data) +{if(typeof(data)=="string"&&data.trim().length>0) +return Prado.JSON.parse(data);else +return null;},dispatchPriorityRequest:function(callback) +{this.abortRequestInProgress();callback.request=new Ajax.Request(callback.url,callback.options);callback.timeout=setTimeout(function() +{Prado.CallbackRequest.abortRequestInProgress();},callback.options.RequestTimeOut);this.requestInProgress=callback;return true;},dispatchNormalRequest:function(callback) +{new Ajax.Request(callback.url,callback.options);return true;},abortRequestInProgress:function() +{inProgress=Prado.CallbackRequest.requestInProgress;if(inProgress) +{inProgress.request.transport.abort();clearTimeout(inProgress.timeout);Prado.CallbackRequest.requestInProgress=null;return true;} +return false;},updatePageState:function(request,transport) +{pagestate=$(this.FIELD_CALLBACK_PAGESTATE);if(request.options.EnablePageStateUpdate&&request.options.HasPriority&&pagestate) +{data=request.header(this.PAGESTATE_HEADER);if(typeof(data)=="string"&&data.length>0) +pagestate.value=data;else +{if(typeof(Logger)!="undefined") +Logger.debug("Bad page state:"+data);}}}}) +Ajax.Responders.register({onComplete:function(request) +{if(request.options.HasPriority) +Prado.CallbackRequest.abortRequestInProgress();}});Event.OnLoad(function()  {if(typeof Logger!="undefined") -{Logger.exception=Prado.AJAX.Exception.logException;Ajax.Responders.register(Prado.AJAX.Exception);}});Prado.AJAX.Callback=Class.create();Prado.AJAX.Callback.prototype=Object.extend(new Prado.AJAX.RemoteObject(),{initialize:function(ID,options) -{if(!isString(ID)&&typeof(ID.id)!="undefined") -ID=ID.id;if(!isString(ID)) -throw new Error('A Control ID must be specified');this.baseInitialize(this,options);this.options=options||[];this.__service.post.data['__ID']=ID;this.requestCallback();},collectPostData:function() -{var IDs=Prado.AJAX.Callback.IDs;this.__service.post.data['__data']={};for(var i=0;i<IDs.length;i++) -{var id=IDs[i];if(id.indexOf("[]")>-1) -this.__service.post.data['__data'][id]=this.collectArrayPostData(id);else if(isObject($(id))) -this.__service.post.data['__data'][id]=$F(id);}},collectArrayPostData:function(name) -{var elements=document.getElementsByName(name);var data=[];$A(elements).each(function(el) -{if($F(el))data.push($F(el));});return data;},requestCallback:function() -{this.collectPostData();if(Prado.AJAX.Validate(this.options)) -return this.__call(Prado.AJAX.Callback.Server,'handleCallback',this.options.params);},handleCallback:function(result,output) -{if(typeof(result)!="undefined"&&!isNull(result)) -{this.options.onSuccess(result['data'],output);if(result['actions']) -result.actions.each(Prado.AJAX.Callback.Action.__run);}}});Prado.AJAX.Callback.Action={__run:function(command) -{for(var name in command) -{if(command[name][0]&&($(command[name][0])||command[name][0].indexOf("[]")>-1)) -{name.toFunction().apply(this,command[name]);}}}};Prado.AJAX.Validate=function(options) -{if(options.CausesValidation) -{if(options.ValidatorGroup) -return Prado.Validation.ValidateValidatorGroup(options.ValidatorGroup);else if(options.ValidationGroup) -return Prado.Validation.ValidateValidationGroup(options.ValidationGroup);else -return Prado.Validation.ValidateNonGroup(options.ValidationForm);} -else -return true;};Prado.AJAX.Callback.Server='';Prado.AJAX.Callback.IDs=[];Prado.Callback=function(ID,params,onSuccess,options) -{var callback={'params':[params]||[],'onSuccess':onSuccess||Prototype.emptyFunction,'CausesValidation':true};Object.extend(callback,options||{});new Prado.AJAX.Callback(ID,callback);return false;} -Array.prototype.______array='______array';Prado.AJAX.JSON={org:'http://www.JSON.org',copyright:'(c)2005 JSON.org',license:'http://www.crockford.com/JSON/license.html',stringify:function(arg){var c,i,l,s='',v;switch(typeof arg){case'object':if(arg){if(arg.______array=='______array'){for(i=0;i<arg.length;++i){v=this.stringify(arg[i]);if(s){s+=',';} +Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{},id:null,request:null,initialize:function(id,options) +{this.id=id;this.options=Object.extend({RequestTimeOut:30000,EnablePageStateUpdate:true,HasPriority:true,CausesValidation:true,ValidationGroup:null,PostInputs:true},options||{});},setParameter:function(value) +{this.options['params']=value;},getParameter:function() +{return this.options['params'];},setRequestTimeOut:function(timeout) +{this.options['RequestTimeOut']=timeout;},getRequestTimeOut:function() +{return this.options['RequestTimeOut'];},setCausesValidation:function(validate) +{this.options['CausesValidation']=validate;},getCausesValidation:function() +{return this.options['CausesValidation'];},setValidationGroup:function(group) +{this.options['ValidationGroup']=group;},getValidationGroup:function() +{return this.options['ValidationGroup'];},dispatch:function() +{Object.extend(this.options,{postBody:this._getPostData(),parameters:''});if(this.options.CausesValidation&&typeof(Prado.Validation)!="undefined") +{var form=this.options.Form||Prado.Validation.getForm();if(Prado.Validation.validate(form,this.options.ValidationGroup,this)==false) +return false;} +if(this.options.HasPriority) +return Prado.CallbackRequest.dispatchPriorityRequest(this);else +return Prado.CallbackRequest.dispatchNormalRequest(this);},_getPostData:function() +{var data={};var callback=Prado.CallbackRequest;if(this.options.PostInputs!=false) +{callback.PostDataLoaders.each(function(name) +{$A(document.getElementsByName(name)).each(function(element) +{if(element.type&&element.name==name) +{value=$F(element);if(typeof(value)!="undefined") +data[name]=value;}})})} +if(typeof(this.options.params)!="undefined") +data[callback.FIELD_CALLBACK_PARAMETER]=callback.encode(this.options.params);var pageState=$F(callback.FIELD_CALLBACK_PAGESTATE);if(typeof(pageState)!="undefined") +data[callback.FIELD_CALLBACK_PAGESTATE]=pageState;data[callback.FIELD_CALLBACK_TARGET]=this.id;if(this.options.EventTarget) +data[callback.FIELD_POSTBACK_TARGET]=this.options.EventTarget;if(this.options.EventParameter) +data[callback.FIELD_POSTBACK_PARAMETER]=this.options.EventParameter;return $H(data).toQueryString();}} +Prado.Callback=function(UniqueID,parameter,onSuccess,options) +{var callback={'params':parameter||'','onSuccess':onSuccess||Prototype.emptyFunction};Object.extend(callback,options||{});request=new Prado.CallbackRequest(UniqueID,callback);request.dispatch();return false;} +Array.prototype.______array='______array';Prado.JSON={org:'http://www.JSON.org',copyright:'(c)2005 JSON.org',license:'http://www.crockford.com/JSON/license.html',stringify:function(arg){var c,i,l,s='',v;switch(typeof arg){case'object':if(arg){if(arg.______array=='______array'){for(i=0;i<arg.length;++i){v=this.stringify(arg[i]);if(s){s+=',';}  s+=v;}  return'['+s+']';}else if(typeof arg.toString!='undefined'){for(i in arg){v=arg[i];if(typeof v!='undefined'&&typeof v!='function'){v=this.stringify(v);if(s){s+=',';}  s+=this.stringify(i)+':'+v;}} @@ -182,118 +200,96 @@ Element.removeClassName(this.element,this.options.hoverClassName)  if(this.saving)return;this.effect=new Effect.Highlight(this.element,{startcolor:this.options.highlightcolor,endcolor:this.options.highlightendcolor,restorecolor:this.originalBackground});},leaveEditMode:function(){Element.removeClassName(this.element,this.options.savingClassName);this.removeForm();this.leaveHover();this.element.style.backgroundColor=this.originalBackground;Element.show(this.element);if(this.options.externalControl){Element.show(this.options.externalControl);}  this.editing=false;this.saving=false;this.oldInnerHTML=null;this.onLeaveEditMode();},onComplete:function(transport){this.leaveEditMode();this.options.onComplete.bind(this)(transport,this.element);},onEnterEditMode:function(){},onLeaveEditMode:function(){},dispose:function(){if(this.oldInnerHTML){this.element.innerHTML=this.oldInnerHTML;}  this.leaveEditMode();Event.stopObserving(this.element,'click',this.onclickListener);Event.stopObserving(this.element,'mouseover',this.mouseoverListener);Event.stopObserving(this.element,'mouseout',this.mouseoutListener);if(this.options.externalControl){Event.stopObserving(this.options.externalControl,'click',this.onclickListener);Event.stopObserving(this.options.externalControl,'mouseover',this.mouseoverListener);Event.stopObserving(this.options.externalControl,'mouseout',this.mouseoutListener);}}};Ajax.InPlaceCollectionEditor=Class.create();Object.extend(Ajax.InPlaceCollectionEditor.prototype,Ajax.InPlaceEditor.prototype);Object.extend(Ajax.InPlaceCollectionEditor.prototype,{createEditField:function(){if(!this.cached_selectTag){var selectTag=document.createElement("select");var collection=this.options.collection||[];var optionTag;collection.each(function(e,i){optionTag=document.createElement("option");optionTag.value=(e instanceof Array)?e[0]:e;if(this.options.value==optionTag.value)optionTag.selected=true;optionTag.appendChild(document.createTextNode((e instanceof Array)?e[1]:e));selectTag.appendChild(optionTag);}.bind(this));this.cached_selectTag=selectTag;} -this.editField=this.cached_selectTag;if(this.options.loadTextURL)this.loadExternalText();this.form.appendChild(this.editField);this.options.callback=function(form,value){return"value="+encodeURIComponent(value);}}});Form.Element.DelayedObserver=Class.create();Form.Element.DelayedObserver.prototype={initialize:function(element,delay,callback){this.delay=delay||0.5;this.element=$(element);this.callback=callback;this.timer=null;this.lastValue=$F(this.element);Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));},delayedListener:function(event){if(this.lastValue==$F(this.element))return;if(this.timer)clearTimeout(this.timer);this.timer=setTimeout(this.onTimerEvent.bind(this),this.delay*1000);this.lastValue=$F(this.element);},onTimerEvent:function(){this.timer=null;this.callback(this.element,$F(this.element));}};if(typeof Effect=='undefined') -throw("dragdrop.js requires including script.aculo.us' effects.js library");var Droppables={drops:[],remove:function(element){this.drops=this.drops.reject(function(d){return d.element==$(element)});},add:function(element){element=$(element);var options=Object.extend({greedy:true,hoverclass:null,tree:false},arguments[1]||{});if(options.containment){options._containers=[];var containment=options.containment;if((typeof containment=='object')&&(containment.constructor==Array)){containment.each(function(c){options._containers.push($(c))});}else{options._containers.push($(containment));}} -if(options.accept)options.accept=[options.accept].flatten();Element.makePositioned(element);options.element=element;this.drops.push(options);},findDeepestChild:function(drops){deepest=drops[0];for(i=1;i<drops.length;++i) -if(Element.isParent(drops[i].element,deepest.element)) -deepest=drops[i];return deepest;},isContained:function(element,drop){var containmentNode;if(drop.tree){containmentNode=element.treeNode;}else{containmentNode=element.parentNode;} -return drop._containers.detect(function(c){return containmentNode==c});},isAffected:function(point,element,drop){return((drop.element!=element)&&((!drop._containers)||this.isContained(element,drop))&&((!drop.accept)||(Element.classNames(element).detect(function(v){return drop.accept.include(v)})))&&Position.within(drop.element,point[0],point[1]));},deactivate:function(drop){if(drop.hoverclass) -Element.removeClassName(drop.element,drop.hoverclass);this.last_active=null;},activate:function(drop){if(drop.hoverclass) -Element.addClassName(drop.element,drop.hoverclass);this.last_active=drop;},show:function(point,element){if(!this.drops.length)return;var affected=[];if(this.last_active)this.deactivate(this.last_active);this.drops.each(function(drop){if(Droppables.isAffected(point,element,drop)) -affected.push(drop);});if(affected.length>0){drop=Droppables.findDeepestChild(affected);Position.within(drop.element,point[0],point[1]);if(drop.onHover) -drop.onHover(element,drop.element,Position.overlap(drop.overlap,drop.element));Droppables.activate(drop);}},fire:function(event,element){if(!this.last_active)return;Position.prepare();if(this.isAffected([Event.pointerX(event),Event.pointerY(event)],element,this.last_active)) -if(this.last_active.onDrop) -this.last_active.onDrop(element,this.last_active.element,event);},reset:function(){if(this.last_active) -this.deactivate(this.last_active);}} -var Draggables={drags:[],observers:[],register:function(draggable){if(this.drags.length==0){this.eventMouseUp=this.endDrag.bindAsEventListener(this);this.eventMouseMove=this.updateDrag.bindAsEventListener(this);this.eventKeypress=this.keyPress.bindAsEventListener(this);Event.observe(document,"mouseup",this.eventMouseUp);Event.observe(document,"mousemove",this.eventMouseMove);Event.observe(document,"keypress",this.eventKeypress);} -this.drags.push(draggable);},unregister:function(draggable){this.drags=this.drags.reject(function(d){return d==draggable});if(this.drags.length==0){Event.stopObserving(document,"mouseup",this.eventMouseUp);Event.stopObserving(document,"mousemove",this.eventMouseMove);Event.stopObserving(document,"keypress",this.eventKeypress);}},activate:function(draggable){window.focus();this.activeDraggable=draggable;},deactivate:function(){this.activeDraggable=null;},updateDrag:function(event){if(!this.activeDraggable)return;var pointer=[Event.pointerX(event),Event.pointerY(event)];if(this._lastPointer&&(this._lastPointer.inspect()==pointer.inspect()))return;this._lastPointer=pointer;this.activeDraggable.updateDrag(event,pointer);},endDrag:function(event){if(!this.activeDraggable)return;this._lastPointer=null;this.activeDraggable.endDrag(event);this.activeDraggable=null;},keyPress:function(event){if(this.activeDraggable) -this.activeDraggable.keyPress(event);},addObserver:function(observer){this.observers.push(observer);this._cacheObserverCallbacks();},removeObserver:function(element){this.observers=this.observers.reject(function(o){return o.element==element});this._cacheObserverCallbacks();},notify:function(eventName,draggable,event){if(this[eventName+'Count']>0) -this.observers.each(function(o){if(o[eventName])o[eventName](eventName,draggable,event);});},_cacheObserverCallbacks:function(){['onStart','onEnd','onDrag'].each(function(eventName){Draggables[eventName+'Count']=Draggables.observers.select(function(o){return o[eventName];}).length;});}} -var Draggable=Class.create();Draggable._revertCache={};Draggable._dragging={};Draggable.prototype={initialize:function(element){var options=Object.extend({handle:false,starteffect:function(element){element._opacity=Element.getOpacity(element);Draggable._dragging[element]=true;new Effect.Opacity(element,{duration:0.2,from:element._opacity,to:0.7});},reverteffect:function(element,top_offset,left_offset){var dur=Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;Draggable._revertCache[element]=new Effect.Move(element,{x:-left_offset,y:-top_offset,duration:dur,queue:{scope:'_draggable',position:'end'}});},endeffect:function(element){var toOpacity=typeof element._opacity=='number'?element._opacity:1.0;new Effect.Opacity(element,{duration:0.2,from:0.7,to:toOpacity,queue:{scope:'_draggable',position:'end'},afterFinish:function(){Draggable._dragging[element]=false}});},zindex:1000,revert:false,scroll:false,scrollSensitivity:20,scrollSpeed:15,snap:false},arguments[1]||{});this.element=$(element);if(options.handle&&(typeof options.handle=='string')){var h=Element.childrenWithClassName(this.element,options.handle,true);if(h.length>0)this.handle=h[0];} -if(!this.handle)this.handle=$(options.handle);if(!this.handle)this.handle=this.element;if(options.scroll&&!options.scroll.scrollTo&&!options.scroll.outerHTML) -options.scroll=$(options.scroll);Element.makePositioned(this.element);this.delta=this.currentDelta();this.options=options;this.dragging=false;this.eventMouseDown=this.initDrag.bindAsEventListener(this);Event.observe(this.handle,"mousedown",this.eventMouseDown);Draggables.register(this);},destroy:function(){Event.stopObserving(this.handle,"mousedown",this.eventMouseDown);Draggables.unregister(this);},currentDelta:function(){return([parseInt(Element.getStyle(this.element,'left')||'0'),parseInt(Element.getStyle(this.element,'top')||'0')]);},initDrag:function(event){if(typeof Draggable._dragging[this.element]!=undefined&&Draggable._dragging[this.element])return;if(Event.isLeftClick(event)){var src=Event.element(event);if(src.tagName&&(src.tagName=='INPUT'||src.tagName=='SELECT'||src.tagName=='OPTION'||src.tagName=='BUTTON'||src.tagName=='TEXTAREA'))return;if(Draggable._revertCache[this.element]){Draggable._revertCache[this.element].cancel();Draggable._revertCache[this.element]=null;} -var pointer=[Event.pointerX(event),Event.pointerY(event)];var pos=Position.cumulativeOffset(this.element);this.offset=[0,1].map(function(i){return(pointer[i]-pos[i])});Draggables.activate(this);Event.stop(event);}},startDrag:function(event){this.dragging=true;if(this.options.zindex){this.originalZ=parseInt(Element.getStyle(this.element,'z-index')||0);this.element.style.zIndex=this.options.zindex;} -if(this.options.ghosting){this._clone=this.element.cloneNode(true);Position.absolutize(this.element);this.element.parentNode.insertBefore(this._clone,this.element);} -if(this.options.scroll){if(this.options.scroll==window){var where=this._getWindowScroll(this.options.scroll);this.originalScrollLeft=where.left;this.originalScrollTop=where.top;}else{this.originalScrollLeft=this.options.scroll.scrollLeft;this.originalScrollTop=this.options.scroll.scrollTop;}} -Draggables.notify('onStart',this,event);if(this.options.starteffect)this.options.starteffect(this.element);},updateDrag:function(event,pointer){if(!this.dragging)this.startDrag(event);Position.prepare();Droppables.show(pointer,this.element);Draggables.notify('onDrag',this,event);this.draw(pointer);if(this.options.change)this.options.change(this);if(this.options.scroll){this.stopScrolling();var p;if(this.options.scroll==window){with(this._getWindowScroll(this.options.scroll)){p=[left,top,left+width,top+height];}}else{p=Position.page(this.options.scroll);p[0]+=this.options.scroll.scrollLeft;p[1]+=this.options.scroll.scrollTop;p.push(p[0]+this.options.scroll.offsetWidth);p.push(p[1]+this.options.scroll.offsetHeight);} -var speed=[0,0];if(pointer[0]<(p[0]+this.options.scrollSensitivity))speed[0]=pointer[0]-(p[0]+this.options.scrollSensitivity);if(pointer[1]<(p[1]+this.options.scrollSensitivity))speed[1]=pointer[1]-(p[1]+this.options.scrollSensitivity);if(pointer[0]>(p[2]-this.options.scrollSensitivity))speed[0]=pointer[0]-(p[2]-this.options.scrollSensitivity);if(pointer[1]>(p[3]-this.options.scrollSensitivity))speed[1]=pointer[1]-(p[3]-this.options.scrollSensitivity);this.startScrolling(speed);} -if(navigator.appVersion.indexOf('AppleWebKit')>0)window.scrollBy(0,0);Event.stop(event);},finishDrag:function(event,success){this.dragging=false;if(this.options.ghosting){Position.relativize(this.element);Element.remove(this._clone);this._clone=null;} -if(success)Droppables.fire(event,this.element);Draggables.notify('onEnd',this,event);var revert=this.options.revert;if(revert&&typeof revert=='function')revert=revert(this.element);var d=this.currentDelta();if(revert&&this.options.reverteffect){this.options.reverteffect(this.element,d[1]-this.delta[1],d[0]-this.delta[0]);}else{this.delta=d;} -if(this.options.zindex) -this.element.style.zIndex=this.originalZ;if(this.options.endeffect) -this.options.endeffect(this.element);Draggables.deactivate(this);Droppables.reset();},keyPress:function(event){if(event.keyCode!=Event.KEY_ESC)return;this.finishDrag(event,false);Event.stop(event);},endDrag:function(event){if(!this.dragging)return;this.stopScrolling();this.finishDrag(event,true);Event.stop(event);},draw:function(point){var pos=Position.cumulativeOffset(this.element);var d=this.currentDelta();pos[0]-=d[0];pos[1]-=d[1];if(this.options.scroll&&(this.options.scroll!=window)){pos[0]-=this.options.scroll.scrollLeft-this.originalScrollLeft;pos[1]-=this.options.scroll.scrollTop-this.originalScrollTop;} -var p=[0,1].map(function(i){return(point[i]-pos[i]-this.offset[i])}.bind(this));if(this.options.snap){if(typeof this.options.snap=='function'){p=this.options.snap(p[0],p[1],this);}else{if(this.options.snap instanceof Array){p=p.map(function(v,i){return Math.round(v/this.options.snap[i])*this.options.snap[i]}.bind(this))}else{p=p.map(function(v){return Math.round(v/this.options.snap)*this.options.snap}.bind(this))}}} -var style=this.element.style;if((!this.options.constraint)||(this.options.constraint=='horizontal')) -style.left=p[0]+"px";if((!this.options.constraint)||(this.options.constraint=='vertical')) -style.top=p[1]+"px";if(style.visibility=="hidden")style.visibility="";},stopScrolling:function(){if(this.scrollInterval){clearInterval(this.scrollInterval);this.scrollInterval=null;Draggables._lastScrollPointer=null;}},startScrolling:function(speed){if(!(speed[0]||speed[1]))return;this.scrollSpeed=[speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];this.lastScrolled=new Date();this.scrollInterval=setInterval(this.scroll.bind(this),10);},scroll:function(){var current=new Date();var delta=current-this.lastScrolled;this.lastScrolled=current;if(this.options.scroll==window){with(this._getWindowScroll(this.options.scroll)){if(this.scrollSpeed[0]||this.scrollSpeed[1]){var d=delta/1000;this.options.scroll.scrollTo(left+d*this.scrollSpeed[0],top+d*this.scrollSpeed[1]);}}}else{this.options.scroll.scrollLeft+=this.scrollSpeed[0]*delta/1000;this.options.scroll.scrollTop+=this.scrollSpeed[1]*delta/1000;} -Position.prepare();Droppables.show(Draggables._lastPointer,this.element);Draggables.notify('onDrag',this);Draggables._lastScrollPointer=Draggables._lastScrollPointer||$A(Draggables._lastPointer);Draggables._lastScrollPointer[0]+=this.scrollSpeed[0]*delta/1000;Draggables._lastScrollPointer[1]+=this.scrollSpeed[1]*delta/1000;if(Draggables._lastScrollPointer[0]<0) -Draggables._lastScrollPointer[0]=0;if(Draggables._lastScrollPointer[1]<0) -Draggables._lastScrollPointer[1]=0;this.draw(Draggables._lastScrollPointer);if(this.options.change)this.options.change(this);},_getWindowScroll:function(w){var T,L,W,H;with(w.document){if(w.document.documentElement&&documentElement.scrollTop){T=documentElement.scrollTop;L=documentElement.scrollLeft;}else if(w.document.body){T=body.scrollTop;L=body.scrollLeft;} -if(w.innerWidth){W=w.innerWidth;H=w.innerHeight;}else if(w.document.documentElement&&documentElement.clientWidth){W=documentElement.clientWidth;H=documentElement.clientHeight;}else{W=body.offsetWidth;H=body.offsetHeight}} -return{top:T,left:L,width:W,height:H};}} -var SortableObserver=Class.create();SortableObserver.prototype={initialize:function(element,observer){this.element=$(element);this.observer=observer;this.lastValue=Sortable.serialize(this.element);},onStart:function(){this.lastValue=Sortable.serialize(this.element);},onEnd:function(){Sortable.unmark();if(this.lastValue!=Sortable.serialize(this.element)) -this.observer(this.element)}} -var Sortable={sortables:{},_findRootElement:function(element){while(element.tagName!="BODY"){if(element.id&&Sortable.sortables[element.id])return element;element=element.parentNode;}},options:function(element){element=Sortable._findRootElement($(element));if(!element)return;return Sortable.sortables[element.id];},destroy:function(element){var s=Sortable.options(element);if(s){Draggables.removeObserver(s.element);s.droppables.each(function(d){Droppables.remove(d)});s.draggables.invoke('destroy');delete Sortable.sortables[s.element.id];}},create:function(element){element=$(element);var options=Object.extend({element:element,tag:'li',dropOnEmpty:false,tree:false,treeTag:'ul',overlap:'vertical',constraint:'vertical',containment:element,handle:false,only:false,hoverclass:null,ghosting:false,scroll:false,scrollSensitivity:20,scrollSpeed:15,format:/^[^_]*_(.*)$/,onChange:Prototype.emptyFunction,onUpdate:Prototype.emptyFunction},arguments[1]||{});this.destroy(element);var options_for_draggable={revert:true,scroll:options.scroll,scrollSpeed:options.scrollSpeed,scrollSensitivity:options.scrollSensitivity,ghosting:options.ghosting,constraint:options.constraint,handle:options.handle};if(options.starteffect) -options_for_draggable.starteffect=options.starteffect;if(options.reverteffect) -options_for_draggable.reverteffect=options.reverteffect;else -if(options.ghosting)options_for_draggable.reverteffect=function(element){element.style.top=0;element.style.left=0;};if(options.endeffect) -options_for_draggable.endeffect=options.endeffect;if(options.zindex) -options_for_draggable.zindex=options.zindex;var options_for_droppable={overlap:options.overlap,containment:options.containment,tree:options.tree,hoverclass:options.hoverclass,onHover:Sortable.onHover} -var options_for_tree={onHover:Sortable.onEmptyHover,overlap:options.overlap,containment:options.containment,hoverclass:options.hoverclass} -Element.cleanWhitespace(element);options.draggables=[];options.droppables=[];if(options.dropOnEmpty||options.tree){Droppables.add(element,options_for_tree);options.droppables.push(element);} -(this.findElements(element,options)||[]).each(function(e){var handle=options.handle?Element.childrenWithClassName(e,options.handle)[0]:e;options.draggables.push(new Draggable(e,Object.extend(options_for_draggable,{handle:handle})));Droppables.add(e,options_for_droppable);if(options.tree)e.treeNode=element;options.droppables.push(e);});if(options.tree){(Sortable.findTreeElements(element,options)||[]).each(function(e){Droppables.add(e,options_for_tree);e.treeNode=element;options.droppables.push(e);});} -this.sortables[element.id]=options;Draggables.addObserver(new SortableObserver(element,options.onUpdate));},findElements:function(element,options){return Element.findChildren(element,options.only,options.tree?true:false,options.tag);},findTreeElements:function(element,options){return Element.findChildren(element,options.only,options.tree?true:false,options.treeTag);},onHover:function(element,dropon,overlap){if(Element.isParent(dropon,element))return;if(overlap>.33&&overlap<.66&&Sortable.options(dropon).tree){return;}else if(overlap>0.5){Sortable.mark(dropon,'before');if(dropon.previousSibling!=element){var oldParentNode=element.parentNode;element.style.visibility="hidden";dropon.parentNode.insertBefore(element,dropon);if(dropon.parentNode!=oldParentNode) -Sortable.options(oldParentNode).onChange(element);Sortable.options(dropon.parentNode).onChange(element);}}else{Sortable.mark(dropon,'after');var nextElement=dropon.nextSibling||null;if(nextElement!=element){var oldParentNode=element.parentNode;element.style.visibility="hidden";dropon.parentNode.insertBefore(element,nextElement);if(dropon.parentNode!=oldParentNode) -Sortable.options(oldParentNode).onChange(element);Sortable.options(dropon.parentNode).onChange(element);}}},onEmptyHover:function(element,dropon,overlap){var oldParentNode=element.parentNode;var droponOptions=Sortable.options(dropon);if(!Element.isParent(dropon,element)){var index;var children=Sortable.findElements(dropon,{tag:droponOptions.tag,only:droponOptions.only});var child=null;if(children){var offset=Element.offsetSize(dropon,droponOptions.overlap)*(1.0-overlap);for(index=0;index<children.length;index+=1){if(offset-Element.offsetSize(children[index],droponOptions.overlap)>=0){offset-=Element.offsetSize(children[index],droponOptions.overlap);}else if(offset-(Element.offsetSize(children[index],droponOptions.overlap)/2)>=0){child=index+1<children.length?children[index+1]:null;break;}else{child=children[index];break;}}} -dropon.insertBefore(element,child);Sortable.options(oldParentNode).onChange(element);droponOptions.onChange(element);}},unmark:function(){if(Sortable._marker)Element.hide(Sortable._marker);},mark:function(dropon,position){var sortable=Sortable.options(dropon.parentNode);if(sortable&&!sortable.ghosting)return;if(!Sortable._marker){Sortable._marker=$('dropmarker')||document.createElement('DIV');Element.hide(Sortable._marker);Element.addClassName(Sortable._marker,'dropmarker');Sortable._marker.style.position='absolute';document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);} -var offsets=Position.cumulativeOffset(dropon);Sortable._marker.style.left=offsets[0]+'px';Sortable._marker.style.top=offsets[1]+'px';if(position=='after') -if(sortable.overlap=='horizontal') -Sortable._marker.style.left=(offsets[0]+dropon.clientWidth)+'px';else -Sortable._marker.style.top=(offsets[1]+dropon.clientHeight)+'px';Element.show(Sortable._marker);},_tree:function(element,options,parent){var children=Sortable.findElements(element,options)||[];for(var i=0;i<children.length;++i){var match=children[i].id.match(options.format);if(!match)continue;var child={id:encodeURIComponent(match?match[1]:null),element:element,parent:parent,children:new Array,position:parent.children.length,container:Sortable._findChildrenElement(children[i],options.treeTag.toUpperCase())} -if(child.container) -this._tree(child.container,options,child) -parent.children.push(child);} -return parent;},_findChildrenElement:function(element,containerTag){if(element&&element.hasChildNodes) -for(var i=0;i<element.childNodes.length;++i) -if(element.childNodes[i].tagName==containerTag) -return element.childNodes[i];return null;},tree:function(element){element=$(element);var sortableOptions=this.options(element);var options=Object.extend({tag:sortableOptions.tag,treeTag:sortableOptions.treeTag,only:sortableOptions.only,name:element.id,format:sortableOptions.format},arguments[1]||{});var root={id:null,parent:null,children:new Array,container:element,position:0} -return Sortable._tree(element,options,root);},_constructIndex:function(node){var index='';do{if(node.id)index='['+node.position+']'+index;}while((node=node.parent)!=null);return index;},sequence:function(element){element=$(element);var options=Object.extend(this.options(element),arguments[1]||{});return $(this.findElements(element,options)||[]).map(function(item){return item.id.match(options.format)?item.id.match(options.format)[1]:'';});},setSequence:function(element,new_sequence){element=$(element);var options=Object.extend(this.options(element),arguments[2]||{});var nodeMap={};this.findElements(element,options).each(function(n){if(n.id.match(options.format)) -nodeMap[n.id.match(options.format)[1]]=[n,n.parentNode];n.parentNode.removeChild(n);});new_sequence.each(function(ident){var n=nodeMap[ident];if(n){n[1].appendChild(n[0]);delete nodeMap[ident];}});},serialize:function(element){element=$(element);var options=Object.extend(Sortable.options(element),arguments[1]||{});var name=encodeURIComponent((arguments[1]&&arguments[1].name)?arguments[1].name:element.id);if(options.tree){return Sortable.tree(element,arguments[1]).children.map(function(item){return[name+Sortable._constructIndex(item)+"[id]="+ -encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));}).flatten().join('&');}else{return Sortable.sequence(element,arguments[1]).map(function(item){return name+"[]="+encodeURIComponent(item);}).join('&');}}} -Element.isParent=function(child,element){if(!child.parentNode||child==element)return false;if(child.parentNode==element)return true;return Element.isParent(child.parentNode,element);} -Element.findChildren=function(element,only,recursive,tagName){if(!element.hasChildNodes())return null;tagName=tagName.toUpperCase();if(only)only=[only].flatten();var elements=[];$A(element.childNodes).each(function(e){if(e.tagName&&e.tagName.toUpperCase()==tagName&&(!only||(Element.classNames(e).detect(function(v){return only.include(v)})))) -elements.push(e);if(recursive){var grandchildren=Element.findChildren(e,only,recursive,tagName);if(grandchildren)elements.push(grandchildren);}});return(elements.length>0?elements.flatten():[]);} -Element.offsetSize=function(element,type){if(type=='vertical'||type=='height') -return element.offsetHeight;else -return element.offsetWidth;} -if(!Control)var Control={};Control.Slider=Class.create();Control.Slider.prototype={initialize:function(handle,track,options){var slider=this;if(handle instanceof Array){this.handles=handle.collect(function(e){return $(e)});}else{this.handles=[$(handle)];} -this.track=$(track);this.options=options||{};this.axis=this.options.axis||'horizontal';this.increment=this.options.increment||1;this.step=parseInt(this.options.step||'1');this.range=this.options.range||$R(0,1);this.value=0;this.values=this.handles.map(function(){return 0});this.spans=this.options.spans?this.options.spans.map(function(s){return $(s)}):false;this.options.startSpan=$(this.options.startSpan||null);this.options.endSpan=$(this.options.endSpan||null);this.restricted=this.options.restricted||false;this.maximum=this.options.maximum||this.range.end;this.minimum=this.options.minimum||this.range.start;this.alignX=parseInt(this.options.alignX||'0');this.alignY=parseInt(this.options.alignY||'0');this.trackLength=this.maximumOffset()-this.minimumOffset();this.handleLength=this.isVertical()?(this.handles[0].offsetHeight!=0?this.handles[0].offsetHeight:this.handles[0].style.height.replace(/px$/,"")):(this.handles[0].offsetWidth!=0?this.handles[0].offsetWidth:this.handles[0].style.width.replace(/px$/,""));this.active=false;this.dragging=false;this.disabled=false;if(this.options.disabled)this.setDisabled();this.allowedValues=this.options.values?this.options.values.sortBy(Prototype.K):false;if(this.allowedValues){this.minimum=this.allowedValues.min();this.maximum=this.allowedValues.max();} -this.eventMouseDown=this.startDrag.bindAsEventListener(this);this.eventMouseUp=this.endDrag.bindAsEventListener(this);this.eventMouseMove=this.update.bindAsEventListener(this);this.handles.each(function(h,i){i=slider.handles.length-1-i;slider.setValue(parseFloat((slider.options.sliderValue instanceof Array?slider.options.sliderValue[i]:slider.options.sliderValue)||slider.range.start),i);Element.makePositioned(h);Event.observe(h,"mousedown",slider.eventMouseDown);});Event.observe(this.track,"mousedown",this.eventMouseDown);Event.observe(document,"mouseup",this.eventMouseUp);Event.observe(document,"mousemove",this.eventMouseMove);this.initialized=true;},dispose:function(){var slider=this;Event.stopObserving(this.track,"mousedown",this.eventMouseDown);Event.stopObserving(document,"mouseup",this.eventMouseUp);Event.stopObserving(document,"mousemove",this.eventMouseMove);this.handles.each(function(h){Event.stopObserving(h,"mousedown",slider.eventMouseDown);});},setDisabled:function(){this.disabled=true;},setEnabled:function(){this.disabled=false;},getNearestValue:function(value){if(this.allowedValues){if(value>=this.allowedValues.max())return(this.allowedValues.max());if(value<=this.allowedValues.min())return(this.allowedValues.min());var offset=Math.abs(this.allowedValues[0]-value);var newValue=this.allowedValues[0];this.allowedValues.each(function(v){var currentOffset=Math.abs(v-value);if(currentOffset<=offset){newValue=v;offset=currentOffset;}});return newValue;} -if(value>this.range.end)return this.range.end;if(value<this.range.start)return this.range.start;return value;},setValue:function(sliderValue,handleIdx){if(!this.active){this.activeHandleIdx=handleIdx||0;this.activeHandle=this.handles[this.activeHandleIdx];this.updateStyles();} -handleIdx=handleIdx||this.activeHandleIdx||0;if(this.initialized&&this.restricted){if((handleIdx>0)&&(sliderValue<this.values[handleIdx-1])) -sliderValue=this.values[handleIdx-1];if((handleIdx<(this.handles.length-1))&&(sliderValue>this.values[handleIdx+1])) -sliderValue=this.values[handleIdx+1];} -sliderValue=this.getNearestValue(sliderValue);this.values[handleIdx]=sliderValue;this.value=this.values[0];this.handles[handleIdx].style[this.isVertical()?'top':'left']=this.translateToPx(sliderValue);this.drawSpans();if(!this.dragging||!this.event)this.updateFinished();},setValueBy:function(delta,handleIdx){this.setValue(this.values[handleIdx||this.activeHandleIdx||0]+delta,handleIdx||this.activeHandleIdx||0);},translateToPx:function(value){return Math.round(((this.trackLength-this.handleLength)/(this.range.end-this.range.start))*(value-this.range.start))+"px";},translateToValue:function(offset){return((offset/(this.trackLength-this.handleLength)*(this.range.end-this.range.start))+this.range.start);},getRange:function(range){var v=this.values.sortBy(Prototype.K);range=range||0;return $R(v[range],v[range+1]);},minimumOffset:function(){return(this.isVertical()?this.alignY:this.alignX);},maximumOffset:function(){return(this.isVertical()?(this.track.offsetHeight!=0?this.track.offsetHeight:this.track.style.height.replace(/px$/,""))-this.alignY:(this.track.offsetWidth!=0?this.track.offsetWidth:this.track.style.width.replace(/px$/,""))-this.alignY);},isVertical:function(){return(this.axis=='vertical');},drawSpans:function(){var slider=this;if(this.spans) -$R(0,this.spans.length-1).each(function(r){slider.setSpan(slider.spans[r],slider.getRange(r))});if(this.options.startSpan) -this.setSpan(this.options.startSpan,$R(0,this.values.length>1?this.getRange(0).min():this.value));if(this.options.endSpan) -this.setSpan(this.options.endSpan,$R(this.values.length>1?this.getRange(this.spans.length-1).max():this.value,this.maximum));},setSpan:function(span,range){if(this.isVertical()){span.style.top=this.translateToPx(range.start);span.style.height=this.translateToPx(range.end-range.start+this.range.start);}else{span.style.left=this.translateToPx(range.start);span.style.width=this.translateToPx(range.end-range.start+this.range.start);}},updateStyles:function(){this.handles.each(function(h){Element.removeClassName(h,'selected')});Element.addClassName(this.activeHandle,'selected');},startDrag:function(event){if(Event.isLeftClick(event)){if(!this.disabled){this.active=true;var handle=Event.element(event);var pointer=[Event.pointerX(event),Event.pointerY(event)];var track=handle;if(track==this.track){var offsets=Position.cumulativeOffset(this.track);this.event=event;this.setValue(this.translateToValue((this.isVertical()?pointer[1]-offsets[1]:pointer[0]-offsets[0])-(this.handleLength/2)));var offsets=Position.cumulativeOffset(this.activeHandle);this.offsetX=(pointer[0]-offsets[0]);this.offsetY=(pointer[1]-offsets[1]);}else{while((this.handles.indexOf(handle)==-1)&&handle.parentNode) -handle=handle.parentNode;this.activeHandle=handle;this.activeHandleIdx=this.handles.indexOf(this.activeHandle);this.updateStyles();var offsets=Position.cumulativeOffset(this.activeHandle);this.offsetX=(pointer[0]-offsets[0]);this.offsetY=(pointer[1]-offsets[1]);}} -Event.stop(event);}},update:function(event){if(this.active){if(!this.dragging)this.dragging=true;this.draw(event);if(navigator.appVersion.indexOf('AppleWebKit')>0)window.scrollBy(0,0);Event.stop(event);}},draw:function(event){var pointer=[Event.pointerX(event),Event.pointerY(event)];var offsets=Position.cumulativeOffset(this.track);pointer[0]-=this.offsetX+offsets[0];pointer[1]-=this.offsetY+offsets[1];this.event=event;this.setValue(this.translateToValue(this.isVertical()?pointer[1]:pointer[0]));if(this.initialized&&this.options.onSlide) -this.options.onSlide(this.values.length>1?this.values:this.value,this);},endDrag:function(event){if(this.active&&this.dragging){this.finishDrag(event,true);Event.stop(event);} -this.active=false;this.dragging=false;},finishDrag:function(event,success){this.active=false;this.dragging=false;this.updateFinished();},updateFinished:function(){if(this.initialized&&this.options.onChange) -this.options.onChange(this.values.length>1?this.values:this.value,this);this.event=null;}} -Prado.AutoCompleter=Class.create();Prado.AutoCompleter.Base=function(){};Prado.AutoCompleter.Base.prototype=Object.extend(Autocompleter.Base.prototype,{updateElement:function(selectedElement) -{if(this.options.updateElement){this.options.updateElement(selectedElement);return;} -var value=Element.collectTextNodesIgnoreClass(selectedElement,'informal');var lastTokenPos=this.findLastToken();if(lastTokenPos!=-1){var newValue=this.element.value.substr(0,lastTokenPos+1);var whitespace=this.element.value.substr(lastTokenPos+1).match(/^\s+/);if(whitespace) -newValue+=whitespace[0];this.element.value=(newValue+value).trim();}else{this.element.value=value.trim();} -this.element.focus();if(this.options.afterUpdateElement) -this.options.afterUpdateElement(this.element,selectedElement);}});Prado.AutoCompleter.prototype=Object.extend(new Autocompleter.Base(),{initialize:function(element,update,options) -{this.baseInitialize(element,update,options);},onUpdateReturn:function(result) -{if(isString(result)&&result.length>0) -this.updateChoices(result);},getUpdatedChoices:function() -{Prado.Callback(this.element.id,this.getToken(),this.onUpdateReturn.bind(this));}});Prado.ActivePanel={callbacks:{},register:function(id,options) -{Prado.ActivePanel.callbacks[id]=options;},update:function(id,param) -{var request=new Prado.ActivePanel.Request(id,Prado.ActivePanel.callbacks[id]);request.callback(param);}} -Prado.ActivePanel.Request=Class.create();Prado.ActivePanel.Request.prototype={initialize:function(element,options) -{this.element=element;this.setOptions(options);},setOptions:function(options) -{this.options={onSuccess:this.onSuccess.bind(this)} -Object.extend(this.options,options||{});},callback:function(param) -{this.options.params=[param];new Prado.AJAX.Callback(this.element,this.options);},onSuccess:function(result,output) -{if(this.options.update) -{if(!this.options.evalScripts) -output=output.stripScripts();Element.update(this.options.update,output);}}} -Prado.DropContainer=Class.create();Prado.DropContainer.prototype=Object.extend(new Prado.ActivePanel.Request(),{initialize:function(element,options) -{this.element=element;this.setOptions(options);Object.extend(this.options,{onDrop:this.onDrop.bind(this),evalScripts:true,onSuccess:options.onSuccess||this.onSuccess.bind(this)});Droppables.add(element,this.options);},onDrop:function(draggable,droppable) -{this.callback(draggable.id)}});Prado.ActiveImageButton=Class.create();Prado.ActiveImageButton.prototype={initialize:function(element,options) -{this.element=$(element);this.options=options;Event.observe(this.element,"click",this.click.bind(this));},click:function(e) -{var el=$('{$this->ClientID}');var imagePos=Position.cumulativeOffset(this.element);var clickedPos=[e.clientX,e.clientY];var param=(clickedPos[0]-imagePos[0]+1)+","+(clickedPos[1]-imagePos[1]+1);Prado.Callback(this.element,param,null,this.options);Event.stop(e);}}
\ No newline at end of file +this.editField=this.cached_selectTag;if(this.options.loadTextURL)this.loadExternalText();this.form.appendChild(this.editField);this.options.callback=function(form,value){return"value="+encodeURIComponent(value);}}});Form.Element.DelayedObserver=Class.create();Form.Element.DelayedObserver.prototype={initialize:function(element,delay,callback){this.delay=delay||0.5;this.element=$(element);this.callback=callback;this.timer=null;this.lastValue=$F(this.element);Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));},delayedListener:function(event){if(this.lastValue==$F(this.element))return;if(this.timer)clearTimeout(this.timer);this.timer=setTimeout(this.onTimerEvent.bind(this),this.delay*1000);this.lastValue=$F(this.element);},onTimerEvent:function(){this.timer=null;this.callback(this.element,$F(this.element));}};Prado.WebUI.CallbackControl=Class.extend(Prado.WebUI.PostBackControl,{onPostBack:function(event,options) +{request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();Event.stop(event);}});Prado.WebUI.TActiveButton=Class.extend(Prado.WebUI.CallbackControl);Prado.WebUI.TActiveLinkButton=Class.extend(Prado.WebUI.CallbackControl);Prado.WebUI.TActiveImageButton=Class.extend(Prado.WebUI.TImageButton,{onPostBack:function(event,options) +{this.addXYInput(event,options);request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();Event.stop(event);}});Prado.WebUI.TActiveCheckBox=Class.extend(Prado.WebUI.CallbackControl,{onPostBack:function(event,options) +{request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();}});Prado.WebUI.TActiveRadioButton=Class.extend(Prado.WebUI.TActiveCheckBox);Prado.WebUI.TActiveTextBox=Class.extend(Prado.WebUI.TTextBox,{onInit:function(options) +{if(options['TextMode']!='MultiLine') +Event.observe(this.element,"keydown",this.handleReturnKey.bind(this));Event.observe(this.element,"change",this.doCallback.bindEvent(this,options));},doCallback:function(event,options) +{request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();Event.stop(event);}});Prado.WebUI.TAutoComplete=Class.extend(Autocompleter.Base,Prado.WebUI.TActiveTextBox.prototype);Prado.WebUI.TAutoComplete=Class.extend(Prado.WebUI.TAutoComplete,{initialize:function(options) +{this.options=options;this.baseInitialize(options.ID,options.ResultPanel,options);Object.extend(this.options,{onSuccess:this.onComplete.bind(this)});if(options.AutoPostBack) +this.onInit(options);},doCallback:function(event,options) +{if(!this.active) +{request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();Event.stop(event);}},onClick:function(event) +{var element=Event.findElement(event,'LI');this.index=element.autocompleteIndex;this.selectEntry();this.hide();Event.fireEvent(this.element,"change");},getUpdatedChoices:function() +{options=new Array(this.getToken(),"__TAutoComplete_onSuggest__");Prado.Callback(this.options.EventTarget,options,null,this.options);},onComplete:function(request,boundary) +{result=Prado.Element.extractContent(request.transport.responseText,boundary);if(typeof(result)=="string"&&result.length>0) +this.updateChoices(result);}});Prado.WebUI.TTimeTriggeredCallback=Base.extend({count:0,timeout:0,constructor:function(options) +{this.options=Object.extend({Interval:1,DecayRate:0},options||{}) +this.onComplete=this.options.onComplete;Prado.WebUI.TTimeTriggeredCallback.register(this);},startTimer:function() +{this.options.onComplete=this.onRequestComplete.bind(this);setTimeout(this.onTimerEvent.bind(this),200);},stopTimer:function() +{(this.onComplete||Prototype.emptyFunction).apply(this,arguments);this.options.onComplete=undefined;clearTimeout(this.timer);this.timer=undefined;this.count=0;},onTimerEvent:function() +{this.options.params=this.timeout/1000;request=new Prado.CallbackRequest(this.options.ID,this.options);request.dispatch();},onRequestComplete:function() +{(this.onComplete||Prototype.emptyFunction).apply(this,arguments);this.timer=setTimeout(this.onTimerEvent.bind(this),this.getNewTimeout())},getNewTimeout:function() +{switch(this.options.DecayType) +{case'Exponential':t=(Math.exp(this.options.DecayRate*this.count*this.options.Interval))-1;break;case'Linear':t=this.options.DecayRate*this.count*this.options.Interval;break;case'Quadratic':t=this.options.DecayRate*this.count*this.count*this.options.Interval;break;case'Cubic':t=this.options.DecayRate*this.count*this.count*this.count*this.options.Interval;break;default:t=0;} +this.timeout=(t+this.options.Interval)*1000;this.count++;return parseInt(this.timeout);}},{timers:{},register:function(timer) +{this.timers[timer.options.ID]=timer;},start:function(id) +{if(this.timers[id]) +this.timers[id].startTimer();},stop:function(id) +{if(this.timers[id]) +this.timers[id].stopTimer();}});Prado.WebUI.ActiveListControl=Base.extend({constructor:function(options) +{this.element=$(options.ID);this.options=options;Event.observe(this.element,"change",this.doCallback.bind(this));},doCallback:function(event) +{request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.dispatch();Event.stop(event);}});Prado.WebUI.TActiveDropDownList=Prado.WebUI.ActiveListControl;Prado.WebUI.TActiveListBox=Prado.WebUI.ActiveListControl;Prado.WebUI.TEventTriggeredCallback=Base.extend({constructor:function(options) +{this.options=options;element=$(options['ControlID']);if(element) +Event.observe(element,this.getEventName(element),this.doCallback.bind(this));},getEventName:function(element) +{name=this.options.EventName;if(typeof(name)=="undefined"&&element.type) +{switch(element.type.toLowerCase()) +{case'password':case'text':case'textarea':case'select-one':case'select-multiple':return'change';}} +return typeof(name)=="undefined"||name=="undefined"?'click':name;},doCallback:function(event) +{request=new Prado.CallbackRequest(this.options.ID,this.options);request.dispatch();if(this.options.StopEvent==true) +Event.stop(event);}});Prado.WebUI.TValueTriggeredCallback=Base.extend({count:1,observing:true,constructor:function(options) +{this.options=options;this.options.PropertyName=this.options.PropertyName||'value';element=$(options['ControlID']);this.value=element?element[this.options.PropertyName]:undefined;Prado.WebUI.TValueTriggeredCallback.register(this);this.startObserving();},stopObserving:function() +{clearTimeout(this.timer);this.observing=false;},startObserving:function() +{this.timer=setTimeout(this.checkChanges.bind(this),this.options.Interval*1000);},checkChanges:function() +{element=$(this.options.ControlID);if(element) +{value=element[this.options.PropertyName];if(this.value!=value) +{this.doCallback(this.value,value);this.value=value;this.count=1;} +else +this.count=this.count+this.options.Decay;if(this.observing) +this.time=setTimeout(this.checkChanges.bind(this),parseInt(this.options.Interval*1000*this.count));}},doCallback:function(oldValue,newValue) +{request=new Prado.CallbackRequest(this.options.ID,this.options);param={'OldValue':oldValue,'NewValue':newValue};request.setParameter(param);request.dispatch();}},{timers:{},register:function(timer) +{this.timers[timer.options.ID]=timer;},stop:function(id) +{if(this.timers[id]) +this.timers[id].stopObserving();}});Prado.WebUI.TInPlaceTextBox=Base.extend({isSaving:false,isEditing:false,editField:null,constructor:function(options) +{this.options=Object.extend({LoadTextFromSource:false,TextMode:'SingleLine'},options||{});this.element=$(this.options.ID);this.initializeListeners();},initializeListeners:function() +{this.onclickListener=this.enterEditMode.bindAsEventListener(this);Event.observe(this.element,'click',this.onclickListener);if(this.options.ExternalControl) +Event.observe($(this.options.ExternalControl),'click',this.onclickListener);},enterEditMode:function(evt) +{if(this.isSaving)return;if(this.isEditing)return;this.isEditing=true;this.onEnterEditMode();this.createEditorInput();this.showTextBox();this.editField.disabled=false;if(this.options.LoadTextOnEdit) +this.loadExternalText();Prado.Element.focus(this.editField);if(evt) +Event.stop(evt);return false;},showTextBox:function() +{Element.hide(this.element);Element.show(this.editField);},showLabel:function() +{Element.show(this.element);Element.hide(this.editField);},createEditorInput:function() +{if(this.editField==null) +this.createTextBox();this.editField.value=this.getText();},loadExternalText:function() +{this.editField.disabled=true;this.onLoadingText();options=new Array('__InlineEditor_loadExternalText__',this.getText());request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.setCausesValidation(false);request.setParameter(options);request.options.onSuccess=this.onloadExternalTextSuccess.bind(this);request.options.onFailure=this.onloadExternalTextFailure.bind(this);request.dispatch();},createTextBox:function() +{cssClass=this.element.className||'';inputName=this.options.EventTarget;options={'className':cssClass,name:inputName,id:this.options.TextBoxID};if(this.options.TextMode=='SingleLine') +{if(this.options.MaxLength>0) +options['maxlength']=this.options.MaxLength;this.editField=INPUT(options);} +else +{if(this.options.Rows>0) +options['rows']=this.options.Rows;if(this.options.Columns>0) +options['cols']=this.options.Columns;if(this.options.Wrap) +options['wrap']='off';this.editField=TEXTAREA(options);} +this.editField.style.display="none";this.element.parentNode.insertBefore(this.editField,this.element) +if(this.options.TextMode=='SingleLine') +{Event.observe(this.editField,"keydown",function(e) +{if(Event.keyCode(e)==Event.KEY_RETURN) +{var target=Event.element(e);if(target) +{Event.fireEvent(target,"blur");Event.stop(e);}}});} +Event.observe(this.editField,"blur",this.onTextBoxBlur.bind(this));},getText:function() +{return this.element.innerHTML;},onEnterEditMode:function() +{if(typeof(this.options.onEnterEditMode)=="function") +this.options.onEnterEditMode(this,null);},onTextBoxBlur:function(e) +{text=this.element.innerHTML;if(this.options.AutoPostBack&&text!=this.editField.value) +this.onTextChanged(text);else +{this.element.innerHTML=this.editField.value;this.isEditing=false;if(this.options.AutoHide) +this.showLabel();}},onTextChanged:function(text) +{request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.setParameter(text);request.options.onSuccess=this.onTextChangedSuccess.bind(this);request.options.onFailure=this.onTextChangedFailure.bind(this);if(request.dispatch()) +{this.isSaving=true;this.editField.disabled=true;}},onLoadingText:function() +{},onloadExternalTextSuccess:function(request,parameter) +{this.isEditing=true;this.editField.disabled=false;this.editField.value=this.getText();Prado.Element.focus(this.editField);},onloadExternalTextFailure:function(request,parameter) +{this.isSaving=false;this.isEditing=false;this.showLabel();},onTextChangedSuccess:function(sender,parameter) +{this.isSaving=false;this.isEditing=false;if(this.options.AutoHide) +this.showLabel();this.element.innerHTML=parameter==null?this.editField.value:parameter;this.editField.disabled=false;},onTextChangedFailure:function(sender,parameter) +{this.editField.disabled=false;this.isSaving=false;this.isEditing=false;}});
\ No newline at end of file diff --git a/framework/Web/Javascripts/js/compressed/prado.js b/framework/Web/Javascripts/js/compressed/prado.js index 1ec69786..9744f6c0 100644 --- a/framework/Web/Javascripts/js/compressed/prado.js +++ b/framework/Web/Javascripts/js/compressed/prado.js @@ -15,7 +15,10 @@ Function.prototype.bindEvent=function()  Class.extend=function(base,definition)  {var component=Class.create();Object.extend(component.prototype,base.prototype);if(definition)  Object.extend(component.prototype,definition);return component;} -Object.extend(String.prototype,{gsub:function(pattern,replacement){var result='',source=this,match;replacement=arguments.callee.prepareReplacement(replacement);while(source.length>0){if(match=source.match(pattern)){result+=source.slice(0,match.index);result+=(replacement(match)||'').toString();source=source.slice(match.index+match[0].length);}else{result+=source,source='';}} +var Base=function(){if(arguments.length){if(this==window){Base.prototype.extend.call(arguments[0],arguments.callee.prototype);}else{this.extend(arguments[0]);}}};Base.version="1.0.2";Base.prototype={extend:function(source,value){var extend=Base.prototype.extend;if(arguments.length==2){var ancestor=this[source];if((ancestor instanceof Function)&&(value instanceof Function)&&ancestor.valueOf()!=value.valueOf()&&/\bbase\b/.test(value)){var method=value;value=function(){var previous=this.base;this.base=ancestor;var returnValue=method.apply(this,arguments);this.base=previous;return returnValue;};value.valueOf=function(){return method;};value.toString=function(){return String(method);};} +return this[source]=value;}else if(source){var _prototype={toSource:null};var _protected=["toString","valueOf"];if(Base._prototyping)_protected[2]="constructor";for(var i=0;(name=_protected[i]);i++){if(source[name]!=_prototype[name]){extend.call(this,name,source[name]);}} +for(var name in source){if(!_prototype[name]){extend.call(this,name,source[name]);}}} +return this;},base:function(){}};Base.extend=function(_instance,_static){var extend=Base.prototype.extend;if(!_instance)_instance={};Base._prototyping=true;var _prototype=new this;extend.call(_prototype,_instance);var constructor=_prototype.constructor;_prototype.constructor=this;delete Base._prototyping;var klass=function(){if(!Base._prototyping)constructor.apply(this,arguments);this.constructor=klass;};klass.prototype=_prototype;klass.extend=this.extend;klass.implement=this.implement;klass.toString=function(){return String(constructor);};extend.call(klass,_static);var object=constructor?klass:_prototype;if(object.init instanceof Function)object.init();return object;};Base.implement=function(_interface){if(_interface instanceof Function)_interface=_interface.prototype;this.prototype.extend(_interface);};*/Object.extend(String.prototype,{gsub:function(pattern,replacement){var result='',source=this,match;replacement=arguments.callee.prepareReplacement(replacement);while(source.length>0){if(match=source.match(pattern)){result+=source.slice(0,match.index);result+=(replacement(match)||'').toString();source=source.slice(match.index+match[0].length);}else{result+=source,source='';}}  return result;},sub:function(pattern,replacement,count){replacement=this.gsub.prepareReplacement(replacement);count=count===undefined?1:count;return this.gsub(pattern,function(match){if(--count<0)return match[0];return replacement(match);});},scan:function(pattern,iterator){this.gsub(pattern,iterator);return this;},truncate:function(length,truncation){length=length||30;truncation=truncation===undefined?'...':truncation;return this.length>length?this.slice(0,length-truncation.length)+truncation:this;},strip:function(){return this.replace(/^\s+/,'').replace(/\s+$/,'');},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,'');},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'');},extractScripts:function(){var matchAll=new RegExp(Prototype.ScriptFragment,'img');var matchOne=new RegExp(Prototype.ScriptFragment,'im');return(this.match(matchAll)||[]).map(function(scriptTag){return(scriptTag.match(matchOne)||['',''])[1];});},evalScripts:function(){return this.extractScripts().map(function(script){return eval(script)});},escapeHTML:function(){var div=document.createElement('div');var text=document.createTextNode(this);div.appendChild(text);return div.innerHTML;},unescapeHTML:function(){var div=document.createElement('div');div.innerHTML=this.stripTags();return div.childNodes[0]?div.childNodes[0].nodeValue:'';},toQueryParams:function(){var pairs=this.match(/^\??(.*)$/)[1].split('&');return pairs.inject({},function(params,pairString){var pair=pairString.split('=');params[pair[0]]=pair[1];return params;});},toArray:function(){return this.split('');},camelize:function(){var oStringList=this.split('-');if(oStringList.length==1)return oStringList[0];var camelizedString=this.indexOf('-')==0?oStringList[0].charAt(0).toUpperCase()+oStringList[0].substring(1):oStringList[0];for(var i=1,len=oStringList.length;i<len;i++){var s=oStringList[i];camelizedString+=s.charAt(0).toUpperCase()+s.substring(1);}  return camelizedString;},inspect:function(){return"'"+this.replace(/\\/g,'\\\\').replace(/'/g,'\\\'')+"'";}});String.prototype.gsub.prepareReplacement=function(replacement){if(typeof replacement=='function')return replacement;var template=new Template(replacement);return function(match){return template.evaluate(match)};}  String.prototype.parseQuery=String.prototype.toQueryParams;var Template=Class.create();Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;Template.prototype={initialize:function(template,pattern){this.template=template.toString();this.pattern=pattern||Template.Pattern;},evaluate:function(object){return this.template.gsub(this.pattern,function(match){var before=match[1];if(before=='\\')return match[2];return before+(object[match[3]]||'').toString();});}} @@ -49,7 +52,12 @@ results.push(iterable[i]);return results;}}  Object.extend(Array.prototype,Enumerable);if(!Array.prototype._reverse)  Array.prototype._reverse=Array.prototype.reverse;Object.extend(Array.prototype,{_each:function(iterator){for(var i=0;i<this.length;i++)  iterator(this[i]);},clear:function(){this.length=0;return this;},first:function(){return this[0];},last:function(){return this[this.length-1];},compact:function(){return this.select(function(value){return value!=undefined||value!=null;});},flatten:function(){return this.inject([],function(array,value){return array.concat(value&&value.constructor==Array?value.flatten():[value]);});},without:function(){var values=$A(arguments);return this.select(function(value){return!values.include(value);});},indexOf:function(object){for(var i=0;i<this.length;i++) -if(this[i]==object)return i;return-1;},reverse:function(inline){return(inline!==false?this:this.toArray())._reverse();},inspect:function(){return'['+this.map(Object.inspect).join(', ')+']';}});var Hash={_each:function(iterator){for(var key in this){var value=this[key];if(typeof value=='function')continue;var pair=[key,value];pair.key=key;pair.value=value;iterator(pair);}},keys:function(){return this.pluck('key');},values:function(){return this.pluck('value');},merge:function(hash){return $H(hash).inject($H(this),function(mergedHash,pair){mergedHash[pair.key]=pair.value;return mergedHash;});},toQueryString:function(){return this.map(function(pair){return pair.map(encodeURIComponent).join('=');}).join('&');},inspect:function(){return'#<Hash:{'+this.map(function(pair){return pair.map(Object.inspect).join(': ');}).join(', ')+'}>';}} +if(this[i]==object)return i;return-1;},reverse:function(inline){return(inline!==false?this:this.toArray())._reverse();},inspect:function(){return'['+this.map(Object.inspect).join(', ')+']';}});var Hash={_each:function(iterator){for(var key in this){var value=this[key];if(typeof value=='function')continue;var pair=[key,value];pair.key=key;pair.value=value;iterator(pair);}},keys:function(){return this.pluck('key');},values:function(){return this.pluck('value');},merge:function(hash){return $H(hash).inject($H(this),function(mergedHash,pair){mergedHash[pair.key]=pair.value;return mergedHash;});},toQueryString:function(){return this.map(function(pair) +{if(typeof(pair[1])=='object'||typeof(pair[1])=='array') +{return $A(pair[1]).collect(function(value) +{return encodeURIComponent(pair[0])+'='+encodeURIComponent(value);}).join('&');} +else +return pair.map(encodeURIComponent).join('=');}).join('&');},inspect:function(){return'#<Hash:{'+this.map(function(pair){return pair.map(Object.inspect).join(': ');}).join(', ')+'}>';}}  function $H(object){var hash=Object.extend({},object||{});Object.extend(hash,Enumerable);Object.extend(hash,Hash);return hash;}  ObjectRange=Class.create();Object.extend(ObjectRange.prototype,Enumerable);Object.extend(ObjectRange.prototype,{initialize:function(start,end,exclusive){this.start=start;this.end=end;this.exclusive=exclusive;},_each:function(iterator){var value=this.start;do{iterator(value);value=value.succ();}while(this.include(value));},include:function(value){if(value<this.start)  return false;if(this.exclusive) @@ -97,7 +105,8 @@ return matchingInputs;},disable:function(form){var elements=Form.getElements(for  Form.Element={serialize:function(element){element=$(element);var method=element.tagName.toLowerCase();var parameter=Form.Element.Serializers[method](element);if(parameter){var key=encodeURIComponent(parameter[0]);if(key.length==0)return;if(parameter[1].constructor!=Array)  parameter[1]=[parameter[1]];return parameter[1].map(function(value){return key+'='+encodeURIComponent(value);}).join('&');}},getValue:function(element){element=$(element);var method=element.tagName.toLowerCase();var parameter=Form.Element.Serializers[method](element);if(parameter)  return parameter[1];}} -Form.Element.Serializers={input:function(element){switch(element.type.toLowerCase()){case'submit':case'hidden':case'password':case'text':return Form.Element.Serializers.textarea(element);case'checkbox':case'radio':return Form.Element.Serializers.inputSelector(element);} +Form.Element.Serializers={input:function(element){if(typeof(element.type)=="undefined") +return false;switch(element.type.toLowerCase()){case'submit':case'hidden':case'password':case'text':return Form.Element.Serializers.textarea(element);case'checkbox':case'radio':return Form.Element.Serializers.inputSelector(element);}  return false;},inputSelector:function(element){if(element.checked)  return[element.name,element.value];},textarea:function(element){return[element.name,element.value];},select:function(element){return Form.Element.Serializers[element.type=='select-one'?'selectOne':'selectMany'](element);},selectOne:function(element){var value='',opt,index=element.selectedIndex;if(index>=0){opt=element.options[index];value=opt.value||opt.text;}  return[element.name,value];},selectMany:function(element){var value=[];for(var i=0;i<element.length;i++){var opt=element.options[i];if(opt.selected) @@ -246,51 +255,99 @@ lastFocus.value=options['EventTarget'];}}  $('PRADO_POSTBACK_TARGET').value=options['EventTarget'];$('PRADO_POSTBACK_PARAMETER').value=options['EventParameter'];Event.stop(event);Event.fireEvent(form,"submit");}  Prado.Element={setValue:function(element,value)  {var el=$(element);if(el&&typeof(el.value)!="undefined") -el.value=value;},select:function(element,method,value) -{var el=$(element);var isList=element.indexOf('[]')>-1;if(!el&&!isList)return;method=isList?'check'+method:el.tagName.toLowerCase()+method;var selection=Prado.Element.Selection;if(isFunction(selection[method])) -selection[method](isList?element:el,value);},click:function(element) +el.value=value;},select:function(element,method,value,total) +{var el=$(element);var selection=Prado.Element.Selection;if(typeof(selection[method])=="function") +{control=selection.isSelectable(el)?[el]:selection.getListElements(element,total);selection[method](control,value);}},click:function(element)  {var el=$(element);if(el)  Event.fireEvent(el,'click');},setAttribute:function(element,attribute,value) -{var el=$(element);if(attribute=="disabled"&&value==false) -el.removeAttribute(attribute);else +{var el=$(element);if((attribute=="disabled"||attribute=="multiple")&&value==false) +el.removeAttribute(attribute);else if(attribute.match(/^on/i)) +{try +{eval("(func = function(event){"+value+"})");el[attribute]=func;} +catch(e) +{throw"Error in evaluating '"+value+"' for attribute "+attribute+" for element "+element.id;}} +else  el.setAttribute(attribute,value);},setOptions:function(element,options)  {var el=$(element);if(el&&el.tagName.toLowerCase()=="select") -{while(el.length>0) -el.remove(0);for(var i=0;i<options.length;i++) -el.options[el.options.length]=new Option(options[i][0],options[i][1]);}},focus:function(element) +{el.options.length=options.length;for(var i=0;i<options.length;i++) +el.options[i]=new Option(options[i][0],options[i][1]);}},focus:function(element)  {var obj=$(element);if(typeof(obj)!="undefined"&&typeof(obj.focus)!="undefined") -setTimeout(function(){obj.focus();},100);return false;}} -Prado.Element.Selection={inputValue:function(el,value) +setTimeout(function(){obj.focus();},100);return false;},replace:function(element,method,content,boundary,transport) +{if(boundary) +{result=Prado.Element.extractContent(transport.responseText,boundary);if(result!=null) +content=result;} +if(typeof(element)=="string") +{if($(element)) +method.toFunction().apply(this,[element,content]);} +else +{method.toFunction().apply(this,[content]);}},extractContent:function(text,boundary) +{f=RegExp('(<!--'+boundary+'-->)([\\s\\S\\w\\W]*)(<!--//'+boundary+'-->)',"m");result=text.match(f);if(result&&result.length>=2) +return result[2];else +return null;},evaluateScript:function(content) +{content.evalScripts();}} +Prado.Element.Selection={isSelectable:function(el) +{if(el&&el.type)  {switch(el.type.toLowerCase()) -{case'checkbox':case'radio':return el.checked=value;}},selectValue:function(el,value) +{case'checkbox':case'radio':case'select':case'select-multiple':case'select-one':return true;}} +return false;},inputValue:function(el,value) +{switch(el.type.toLowerCase()) +{case'checkbox':case'radio':return el.checked=value;}},selectValue:function(elements,value) +{elements.each(function(el)  {$A(el.options).each(function(option) -{option.selected=option.value==value;});},selectIndex:function(el,index) -{if(el.type=='select-one') +{if(typeof(value)=="boolean") +options.selected=value;else if(option.value==value) +option.selected=true;});})},selectValues:function(elements,values) +{selection=this;values.each(function(value) +{selection.selectValue(elements,value);})},selectIndex:function(elements,index) +{elements.each(function(el) +{if(el.type.toLowerCase()=='select-one')  el.selectedIndex=index;else  {for(var i=0;i<el.length;i++)  {if(i==index) -el.options[i].selected=true;}}},selectClear:function(el) -{el.selectedIndex=-1;},selectAll:function(el) +el.options[i].selected=true;}}})},selectAll:function(elements) +{elements.each(function(el) +{if(el.type.toLowerCase()!='select-one')  {$A(el.options).each(function(option) -{option.selected=true;Logger.warn(option.value);});},selectInvert:function(el) +{option.selected=true;})}})},selectInvert:function(elements) +{elements.each(function(el) +{if(el.type.toLowerCase()!='select-one')  {$A(el.options).each(function(option) -{option.selected=!option.selected;});},checkValue:function(name,value) -{$A(document.getElementsByName(name)).each(function(el) -{el.checked=el.value==value});},checkIndex:function(name,index) -{var elements=$A(document.getElementsByName(name));for(var i=0;i<elements.length;i++) +{option.selected=!options.selected;})}})},selectIndices:function(elements,indices) +{selection=this;indices.each(function(index) +{selection.selectIndex(elements,index);})},selectClear:function(elements) +{elements.each(function(el) +{el.selectedIndex=-1;})},getListElements:function(element,total) +{elements=new Array();for(i=0;i<total;i++) +{el=$(element+"_c"+i);if(el) +elements.push(el);} +return elements;},checkValue:function(elements,value) +{elements.each(function(el) +{if(typeof(value)=="boolean") +el.checked=value;else if(el.value==value) +el.checked=true;});},checkValues:function(elements,values) +{selection=this;values.each(function(value) +{selection.checkValue(elements,value);})},checkIndex:function(elements,index) +{for(var i=0;i<elements.length;i++)  {if(i==index) -elements[i].checked=true;}},checkClear:function(name) -{$A(document.getElementsByName(name)).each(function(el) -{el.checked=false;});},checkAll:function(name) -{$A(document.getElementsByName(name)).each(function(el) -{el.checked=true;});},checkInvert:function(name) -{$A(document.getElementsByName(name)).each(function(el) -{el.checked=!el.checked;});}};Prado.WebUI=Class.create();Prado.WebUI.PostBackControl=Class.create();Prado.WebUI.PostBackControl.prototype={_elementOnClick:null,initialize:function(options) +elements[i].checked=true;}},checkIndices:function(elements,indices) +{selection=this;indices.each(function(index) +{selection.checkIndex(elements,index);})},checkClear:function(elements) +{elements.each(function(el) +{el.checked=false;});},checkAll:function(elements) +{elements.each(function(el) +{el.checked=true;})},checkInvert:function(elements) +{elements.each(function(el) +{el.checked!=el.checked;})}};Prado.Element.Insert={append:function(element,content) +{new Insertion.Bottom(element,content);},prepend:function(element,content) +{new Insertion.Top(element,content);},after:function(element,content) +{new Insertion.After(element,content);},before:function(element,content) +{new Insertion.Before(element,content);}} +Prado.WebUI=Class.create();Prado.WebUI.PostBackControl=Class.create();Prado.WebUI.PostBackControl.prototype={_elementOnClick:null,initialize:function(options)  {this.element=$(options.ID);if(this.onInit)  this.onInit(options);},onInit:function(options)  {if(typeof(this.element.onclick)=="function")  {this._elementOnClick=this.element.onclick;this.element.onclick=null;} -Event.observe(this.element,"click",this.onClick.bindEvent(this,options));},onClick:function(event,options) +Event.observe(this.element,"click",this.elementClicked.bindEvent(this,options));},elementClicked:function(event,options)  {var src=Event.element(event);var doPostBack=true;var onclicked=null;if(this._elementOnClick)  {var onclicked=this._elementOnClick(event);if(typeof(onclicked)=="boolean")  doPostBack=onclicked;} @@ -301,7 +358,14 @@ Event.stop(event);},onPostBack:function(event,options)  {if(!this.hasXYInput)  {this.addXYInput(event,options);this.hasXYInput=true;}  Prado.PostBack(event,options);},addXYInput:function(event,options) -{var imagePos=Position.cumulativeOffset(this.element);var clickedPos=[event.clientX,event.clientY];var x=clickedPos[0]-imagePos[0]+1;var y=clickedPos[1]-imagePos[1]+1;var id=options['EventTarget'];var x_input=INPUT({type:'hidden',name:id+'_x',value:x});var y_input=INPUT({type:'hidden',name:id+'_y',value:y});this.element.parentNode.appendChild(x_input);this.element.parentNode.appendChild(y_input);}});Prado.WebUI.TRadioButton=Class.extend(Prado.WebUI.PostBackControl);Prado.WebUI.TRadioButton.prototype.onRadioButtonInitialize=Prado.WebUI.TRadioButton.prototype.initialize;Object.extend(Prado.WebUI.TRadioButton.prototype,{initialize:function(options) +{imagePos=Position.cumulativeOffset(this.element);clickedPos=[event.clientX,event.clientY];x=clickedPos[0]-imagePos[0]+1;y=clickedPos[1]-imagePos[1]+1;x=x<0?0:x;y=y<0?0:y;id=options['EventTarget'];x_input=$(id+"_x");y_input=$(id+"_y");if(x_input) +{x_input.value=x;} +else +{x_input=INPUT({type:'hidden',name:id+'_x','id':id+'_x',value:x});this.element.parentNode.appendChild(x_input);} +if(y_input) +{y_input.value=y;} +else +{y_input=INPUT({type:'hidden',name:id+'_y','id':id+'_y',value:y});this.element.parentNode.appendChild(y_input);}}});Prado.WebUI.TRadioButton=Class.extend(Prado.WebUI.PostBackControl);Prado.WebUI.TRadioButton.prototype.onRadioButtonInitialize=Prado.WebUI.TRadioButton.prototype.initialize;Object.extend(Prado.WebUI.TRadioButton.prototype,{initialize:function(options)  {this.element=$(options['ID']);if(!this.element.checked)  this.onRadioButtonInitialize(options);}});Prado.WebUI.TTextBox=Class.extend(Prado.WebUI.PostBackControl,{onInit:function(options)  {if(options['TextMode']!='MultiLine') diff --git a/framework/Web/Javascripts/js/compressed/validator.js b/framework/Web/Javascripts/js/compressed/validator.js index d3d8c53e..037abfeb 100644 --- a/framework/Web/Javascripts/js/compressed/validator.js +++ b/framework/Web/Javascripts/js/compressed/validator.js @@ -3,7 +3,8 @@ Prado.Validation=Class.create();Object.extend(Prado.Validation,{managers:{},vali  {if(this.managers[formID])  {return this.managers[formID].validate(groupID,invoker);}  else -{throw new Error("Form '"+form+"' is not registered with Prado.Validation");}},isValid:function(formID,groupID) +{throw new Error("Form '"+form+"' is not registered with Prado.Validation");}},getForm:function() +{var keys=$H(this.managers).keys();return keys[0];},isValid:function(formID,groupID)  {if(this.managers[formID])  return this.managers[formID].isValid(groupID);return true;},addValidator:function(formID,validator)  {if(this.managers[formID]) @@ -94,7 +95,10 @@ Prado.Element.focus(this.options.FocusElementID);this.visible=true;},updateContr  control.removeClassName(CssClass);else  control.addClassName(CssClass);}},hide:function()  {this.isValid=true;this.updateControl();this.visible=false;},validate:function(invoker) -{if(typeof(this.options.OnValidate)=="function") +{if(!this.control) +this.control=$(this.options.ControlToValidate);if(!this.control) +{this.isValid=true;return this.isValid;} +if(typeof(this.options.OnValidate)=="function")  this.options.OnValidate(this,invoker);if(this.enabled)  this.isValid=this.evaluateIsValid();else  this.isValid=true;if(this.isValid) diff --git a/framework/Web/Javascripts/js/debug/ajax.js b/framework/Web/Javascripts/js/debug/ajax.js index 9a61cabb..61881bf9 100644 --- a/framework/Web/Javascripts/js/debug/ajax.js +++ b/framework/Web/Javascripts/js/debug/ajax.js @@ -116,7 +116,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {      var requestHeaders =         ['X-Requested-With', 'XMLHttpRequest',         'X-Prototype-Version', Prototype.Version, -       'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; +       'Accept', 'text/javascript, text/html, application/xml, text/xml'];      if (this.options.method == 'post') {        requestHeaders.push('Content-type', this.options.contentType); @@ -287,432 +287,540 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {  /**
 - * Prado AJAX service. The default service provider is JPSpan.
 + * Override Prototype's response implementation.
   */
 -Prado.AJAX = { Service : 'Prototype' };
 -
 -/**
 - * Parse and execute javascript embedded in html.
 - */
 -Prado.AJAX.EvalScript = function(output)
 +Object.extend(Ajax.Request.prototype,
  {
 -
 -	var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
 -	var scripts  = output.match(match);
 -	if (scripts)
 +	/**
 +	 * Customize the response, dispatch onXXX response code events, and
 +	 * tries to execute response actions (javascript statements).
 +	 */
 +	respondToReadyState : function(readyState)
  	{
 -		match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
 -		setTimeout((function()
 -		{
 -			for (var i = 0; i < scripts.length; i++)
 -				eval(scripts[i].match(match)[1]);
 -		}).bind(this), 50);
 -	}
 -}
 +	    var event = Ajax.Request.Events[readyState];
 +	    var transport = this.transport, json = this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);
 +	    if (event == 'Complete')
 +	    {
 +	      try
 +	      {
 +	      	Prado.CallbackRequest.updatePageState(this,transport);
 +			Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
 +			Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));
 +
 +	        (this.options['on' + this.transport.status]
 +	         || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
 +	         || Prototype.emptyFunction)(this, json);
 +	  	      } catch (e) {
 +	        this.dispatchException(e);
 +	      }
 +	      if ((this.header('Content-type') || '').match(/^text\/javascript/i))
 +	        this.evalResponse();
 +	    }
 +
 +	    try {
 +	      (this.options['on' + event] || Prototype.emptyFunction)(this, json);
 +	      Ajax.Responders.dispatch('on' + event, this, transport, json);
 +	    } catch (e) {
 +	      this.dispatchException(e);
 +	    }
 +
 +	    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
 +	    if (event == 'Complete')
 +	      this.transport.onreadystatechange = Prototype.emptyFunction;
 +	},
 -/**
 - * AJAX service request using Prototype's AJAX request class.
 - */
 -Prado.AJAX.Request = Class.create();
 -Prado.AJAX.Request.prototype = Object.extend(Ajax.Request.prototype,
 -{
  	/**
 -	 * Evaluate the respond JSON data, override parent implementing.
 -	 * If default eval fails, try parsing the JSON data (slower).
 +	 * Gets header data assuming JSON encoding.
 +	 * @param string header name
 +	 * @return object header data as javascript structures.
  	 */
 -	evalJSON: function()
 +	getHeaderData : function(name)
  	{
  		try
  		{
 -			var json = this.transport.getResponseHeader('X-JSON'), object;
 -			object = eval(json);
 -			return object;
 +			var json = this.header(name);
 +			return eval('(' + json + ')');
  		}
  		catch (e)
  		{
 -			if(isString(json))
 -			{
 -				return Prado.AJAX.JSON.parse(json);
 -			}
 +			if(typeof(json) == "string")
 +				return Prado.CallbackRequest.decode(json);
  		}
 -	},
 -
 -	respondToReadyState: function(readyState) {
 -    var event = Ajax.Request.Events[readyState];
 -    var transport = this.transport, json = this.evalJSON();
 -
 -
 -	if(event == 'Complete' && transport.status)
 -    	Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
 -
 -   (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
 -    Ajax.Responders.dispatch('on' + event, this, transport, json);
 -
 -	if (event == 'Complete')
 -      (this.options['on' + this.transport.status]
 -       || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
 -       || Prototype.emptyFunction)(transport, json);
 -
 -
 -    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
 -    if (event == 'Complete')
 -      this.transport.onreadystatechange = Prototype.emptyFunction;
 -  }
 -
 +	}
  });
 -Prado.AJAX.Error = function(e, code)
 -{
 -    e.name = 'Prado.AJAX.Error';
 -    e.code = code;
 -    return e;
 -}
 +/**
 + * Prado Callback client-side request handler.
 + */
 +Prado.CallbackRequest = Class.create();
  /**
 - * Post data builder, serialize the data using JSON.
 + * Static definitions.
   */
 -Prado.AJAX.RequestBuilder = Class.create();
 -Prado.AJAX.RequestBuilder.prototype =
 +Object.extend(Prado.CallbackRequest,
  {
 -	initialize : function()
 +	/**
 +	 * Callback request target POST field name.
 +	 */
 +	FIELD_CALLBACK_TARGET : 'PRADO_CALLBACK_TARGET',
 +	/**
 +	 * Callback request parameter POST field name.
 +	 */
 +	FIELD_CALLBACK_PARAMETER : 'PRADO_CALLBACK_PARAMETER',
 +	/**
 +	 * Callback request page state field name,
 +	 */
 +	FIELD_CALLBACK_PAGESTATE : 'PRADO_PAGESTATE',
 +
 +	FIELD_POSTBACK_TARGET : 'PRADO_POSTBACK_TARGET',
 +
 +	FIELD_POSTBACK_PARAMETER : 'PRADO_POSTBACK_PARAMETER',
 +
 +	/**
 +	 * List of form fields that will be collected during callback.
 +	 */
 +	PostDataLoaders : [],
 +	/**
 +	 * Response data header name.
 +	 */
 +	DATA_HEADER : 'X-PRADO-DATA',
 +	/**
 +	 * Response javascript execution statement header name.
 +	 */
 +	ACTION_HEADER : 'X-PRADO-ACTIONS',
 +	/**
 +	 * Response errors/exceptions header name.
 +	 */
 +	ERROR_HEADER : 'X-PRADO-ERROR',
 +	/**
 +	 * Page state header name.
 +	 */
 +	PAGESTATE_HEADER : 'X-PRADO-PAGESTATE',
 +	/**
 +	 * Current requests in progress.
 +	 */
 +	requestInProgress : null,
 +
 +	/**
 +	 * Add ids of inputs element to post in the request.
 +	 */
 +	addPostLoaders : function(ids)
  	{
 -		this.body = '';
 -		this.data = [];
 +		this.PostDataLoaders = this.PostDataLoaders.concat(ids);
 +		list = [];
 +		this.PostDataLoaders.each(function(id)
 +		{
 +			if(list.indexOf(id) < 0)
 +				list.push(id);
 +		});
 +		this.PostDataLoaders = list;
  	},
 -	encode : function(data)
 +
 +	/**
 +	 * Dispatch callback response actions.
 +	 */
 +	dispatchActions : function(transport,actions)
  	{
 -		return Prado.AJAX.JSON.stringify(data);
 +		if(actions && actions.length > 0)
 +			actions.each(this.__run.bind(this,transport));
  	},
 -	build : function(data)
 +
 +	/**
 +	 * Prase and evaluate a Callback clien-side action
 +	 */
 +	__run : function(transport, command)
  	{
 -		var sep = '';
 -        for ( var argName in data)
 +		for(var method in command)
  		{
 -			if(isFunction(data[argName])) continue;
 -            try
 +			try
  			{
 -                this.body += sep + argName + '=';
 -                this.body += encodeURIComponent(this.encode(data[argName]));
 -            } catch (e) {
 -                throw Prado.AJAX.Error(e, 1006);
 -            }
 -            sep = '&';
 -        }
 -    },
 +				method.toFunction().apply(this,command[method].concat(transport));
 +			}
 +			catch(e)
 +			{
 +				if(typeof(Logger) != "undefined")
 +					Prado.CallbackRequest.Exception.onException(null,e);
 +			}
 +		}
 +	},
 -	getAll : function()
 +	/**
 +	 * Respond to Prado Callback request exceptions.
 +	 */
 +	Exception :
  	{
 -		this.build(this.data);
 -		return this.body;
 -	}
 -}
 +		/**
 +		 * Server returns 500 exception. Just log it.
 +		 */
 +		"on500" : function(request, transport, data)
 +		{
 +			var e = request.getHeaderData(Prado.CallbackRequest.ERROR_HEADER);
 +			Logger.error("Callback Server Error "+e.code, this.formatException(e));
 +		},
 +		/**
 +		 * Callback OnComplete event,logs reponse and data to console.
 +		 */
 +		'on200' : function(request, transport, data)
 +		{
 +			if(transport.status < 500)
 +			{
 +				var msg = 'HTTP '+transport.status+" with response : \n";
 +				msg += transport.responseText + "\n";
 +				msg += "Data : \n"+inspect(data)+"\n";
 +				msg += "Actions : \n";
 +				data = request.getHeaderData(Prado.CallbackRequest.ACTION_HEADER);
 +				if(data && data.length > 0)
 +				{
 +					data.each(function(action)
 +					{
 +						msg += inspect(action)+"\n";
 +					});
 +				}
 +				Logger.warn(msg);
 +			}
 +		},
 -Prado.AJAX.RemoteObject = function(){};
 +		/**
 +		 * Uncaught exceptions during callback response.
 +		 */
 +		onException : function(request,e)
 +		{
 +			msg = "";
 +			$H(e).each(function(item)
 +			{
 +				msg += item.key+": "+item.value+"\n";
 +			})
 +			Logger.error('Uncaught Callback Client Exception:', msg);
 +		},
 +
 +		/**
 +		 * Formats the exception message for display in console.
 +		 */
 +		formatException : function(e)
 +		{
 +			var msg = e.type + " with message \""+e.message+"\"";
 +			msg += " in "+e.file+"("+e.line+")\n";
 +			msg += "Stack trace:\n";
 +			var trace = e.trace;
 +			for(var i = 0; i<trace.length; i++)
 +			{
 +				msg += "  #"+i+" "+trace[i].file;
 +				msg += "("+trace[i].line+"): ";
 +				msg += trace[i]["class"]+"->"+trace[i]["function"]+"()"+"\n";
 +			}
 +			msg += e.version+" "+e.time+"\n";
 +			return msg;
 +		}
 +	},
 -/**
 - * AJAX service request for Prado RemoteObjects
 - */
 -Prado.AJAX.RemoteObject.Request = Class.create();
 -Prado.AJAX.RemoteObject.Request.prototype = Object.extend(Prado.AJAX.Request.prototype,
 -{
  	/**
 -	 * Initialize the RemoteObject Request, overrides parent
 -	 * implementation by delaying the request to invokeRemoteObject.
 +	 * @return string JSON encoded data.
  	 */
 -	initialize : function(options)
 +	encode : function(data)
  	{
 -	    this.transport = Ajax.getTransport();
 -		this.setOptions(options);
 -		this.post = new Prado.AJAX.RequestBuilder();
 +		return Prado.JSON.stringify(data);
  	},
  	/**
 -	 * Call the remote object,
 -	 * @param string the remote server url
 -	 * @param array additional arguments
 +	 * @return mixed javascript data decoded from string using JSON decoding.
  	 */
 -	invokeRemoteObject : function(url, args)
 +	decode : function(data)
  	{
 -		this.initParameters(args);
 -		this.options.postBody = this.post.getAll();
 -		this.request(url);
 +		if(typeof(data) == "string" && data.trim().length > 0)
 +			return Prado.JSON.parse(data);
 +		else
 +			return null;
  	},
  	/**
 -	 * Set the additional arguments as post data with key '__parameters'
 +	 * Dispatch a priority request, it will call abortRequestInProgress first.
  	 */
 -	initParameters : function(args)
 +	dispatchPriorityRequest : function(callback)
  	{
 -		this.post.data['__parameters'] = [];
 -		for(var i = 0; i<args.length; i++)
 -			this.post.data['__parameters'][i] = args[i];
 -	}
 -});
 +		//Logger.info("priority request "+callback.id)
 +		this.abortRequestInProgress();
 -/**
 - * Base proxy class for Prado RemoteObjects via AJAX.
 - * e.g.
 - * <code>
 - *	var TestObject1 = Class.create();
 - *	TestObject1.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
 - *	{
 - * 		initialize : function(handlers, options)
 - *      {
 - *           this.__serverurl = 'http://127.0.0.1/.....';
 - *           this.baseInitialize(handlers, options);
 - *	    }
 - *
 - *		method1 : function()
 - *		{
 - *			return this.__call(this.__serverurl, 'method1', arguments);
 - *		}
 - *	});
 - *</code>
 - * And client usage,
 - * <code>
 - *	var test1 = new TestObject1(); //create new remote object
 - *	test1.method1(); //call the method, no onComplete hook
 - *
 - *  var onComplete = { method1 : function(result){ alert(result) } };
 - *  //create new remote object with onComplete callback
 - *  var test2 = new TestObject1(onComplete);
 - *  test2.method1(); //call it, on success, onComplete's method1 is called.
 - * </code>
 - */
 -Prado.AJAX.RemoteObject.prototype =
 -{
 -	baseInitialize : function(handlers, options)
 -	{
 -		this.__handlers = handlers || {};
 -		this.__service = new Prado.AJAX.RemoteObject.Request(options);
 -	},
 +		callback.request = new Ajax.Request(callback.url, callback.options);
 +		callback.timeout = setTimeout(function()
 +		{
 +		//	Logger.warn("priority timeout");
 +			Prado.CallbackRequest.abortRequestInProgress();
 +		},callback.options.RequestTimeOut);
 -	__call : function(url, method, args)
 -	{
 -		this.__service.options.onSuccess = this.__onSuccess.bind(this);
 -		this.__callback = method;
 -		return this.__service.invokeRemoteObject(url+"/"+method, args);
 +		this.requestInProgress = callback;
 +		return true;
 +		//Logger.info("dispatched "+this.requestInProgress)
  	},
 -	__onSuccess : function(transport, json)
 -	{
 -		if(this.__handlers[this.__callback])
 -			this.__handlers[this.__callback](json, transport.responseText);
 -	}
 -};
 -
 -/**
 - * Respond to Prado AJAX request exceptions.
 - */
 -Prado.AJAX.Exception =
 -{
  	/**
 -	 * Server returns 505 exception. Just log it.
 +	 * Dispatch a normal request, no timeouts or aborting of requests.
  	 */
 -	"on505" : function(request, transport, e)
 +	dispatchNormalRequest : function(callback)
  	{
 -		var msg = 'HTTP '+transport.status+" with response";
 -		Logger.error(msg, transport.responseText);
 -		Logger.exception(e);
 +	//	Logger.info("dispatching normal request");
 +		new Ajax.Request(callback.url, callback.options);
 +		return true;
  	},
 -	onComplete : function(request, transport, e)
 +	/**
 +	 * Abort the current priority request in progress.
 +	 */
 +	abortRequestInProgress : function()
  	{
 -		if(transport.status != 505)
 +		inProgress = Prado.CallbackRequest.requestInProgress;
 +		//Logger.info("aborting ... "+inProgress);
 +		if(inProgress)
  		{
 -			var msg = 'HTTP '+transport.status+" with response : \n";
 -			msg += transport.responseText + "\n";
 -			msg += "Data : \n"+inspect(e);
 -			Logger.warn(msg);
 +		//	Logger.warn("aborted "+inProgress.id)
 +			inProgress.request.transport.abort();
 +			clearTimeout(inProgress.timeout);
 +			Prado.CallbackRequest.requestInProgress = null;
 +			return true;
  		}
 +		return false;
  	},
 -	format : function(e)
 +	/**
 +	 * Updates the page state. It will update only if EnablePageStateUpdate and
 +	 * HasPriority options are both true.
 +	 */
 +	updatePageState : function(request, transport)
  	{
 -		var msg = e.type + " with message \""+e.message+"\"";
 -		msg += " in "+e.file+"("+e.line+")\n";
 -		msg += "Stack trace:\n";
 -		var trace = e.trace;
 -		for(var i = 0; i<trace.length; i++)
 +		pagestate = $(this.FIELD_CALLBACK_PAGESTATE);
 +		if(request.options.EnablePageStateUpdate && request.options.HasPriority && pagestate)
  		{
 -			msg += "  #"+i+" "+trace[i].file;
 -			msg += "("+trace[i].line+"): ";
 -			msg += trace[i]["class"]+"->"+trace[i]["function"]+"()"+"\n";
 +			data = request.header(this.PAGESTATE_HEADER);
 +			if(typeof(data) == "string" && data.length > 0)
 +				pagestate.value = data;
 +			else
 +			{
 +				if(typeof(Logger) != "undefined")
 +					Logger.debug("Bad page state:"+data);
 +			}
  		}
 -		return msg;
 -	},
 -
 -	logException : function(e)
 -	{
 -		var msg = Prado.AJAX.Exception.format(e);
 -		Logger.error("Server Error "+e.code, msg);
  	}
 -}
 +})
 +
 +/**
 + * Automatically aborts the current request when a priority request has returned.
 + */
 +Ajax.Responders.register({onComplete : function(request)
 +{
 +	if(request.options.HasPriority)
 +		Prado.CallbackRequest.abortRequestInProgress();
 +}});
  //Add HTTP exception respones when logger is enabled.
  Event.OnLoad(function()
  {
  	if(typeof Logger != "undefined")
 -	{
 -		Logger.exception = Prado.AJAX.Exception.logException;
 -		Ajax.Responders.register(Prado.AJAX.Exception);
 -	}
 +		Ajax.Responders.register(Prado.CallbackRequest.Exception);
  });
  /**
 - * Prado Callback service that provides component intergration,
 - * viewstate (read only), and automatic form data serialization.
 - * Usage: <code>new Prado.AJAX.Callback('MyPage.MyComponentID.raiseCallbackEvent', options)</code>
 - * These classes should be called by the components developers.
 - * For inline callback service, use <t>Prado.Callback(callbackID, params)</t>.
 + * Create and prepare a new callback request.
 + * Call the dispatch() method to start the callback request.
 + * <code>
 + * request = new Prado.CallbackRequest(UniqueID, callback);
 + * request.dispatch();
 + * </code>
   */
 -Prado.AJAX.Callback = Class.create();
 -Prado.AJAX.Callback.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
 +Prado.CallbackRequest.prototype =
  {
 +	/**
 +	 * Callback URL, same url as the current page.
 +	 */
 +	url : window.location.href,
 +
 +	/**
 +	 * Callback options, including onXXX events.
 +	 */
 +	options : {	},
 +
 +	/**
 +	 * Callback target ID. E.g. $control->getUniqueID();
 +	 */
 +	id : null,
 +
 +	/**
 +	 * Current callback request.
 +	 */
 +	request : null,
  	/**
 -	 * Create and request a new Prado callback service.
 -	 * @param string|element the callback ID, must be of the form, <t>ClassName.ComponentID.MethodName</t>
 -	 * @param list options with list key onCallbackReturn, and more.
 -	 *
 +	 * Prepare and inititate a callback request.
  	 */
 -	initialize : function(ID, options)
 +	initialize : function(id, options)
  	{
 -		if(!isString(ID) && typeof(ID.id) != "undefined")
 -			ID = ID.id;
 -		if(!isString(ID))
 -			throw new Error('A Control ID must be specified');
 -		this.baseInitialize(this, options);
 -		this.options = options || [];
 -		this.__service.post.data['__ID'] = ID;
 -		this.requestCallback();
 +		this.id = id;
 +		this.options = Object.extend(
 +		{
 +			RequestTimeOut : 30000, // 30 second timeout.
 +			EnablePageStateUpdate : true,
 +			HasPriority : true,
 +			CausesValidation : true,
 +			ValidationGroup : null,
 +			PostInputs : true
 +		}, options || {});
  	},
  	/**
 -	 * Get form data for components that implements IPostBackHandler.
 +	 * Sets the request parameter
 +	 * @param {Object} parameter value
  	 */
 -	collectPostData : function()
 +	setParameter : function(value)
  	{
 -		var IDs = Prado.AJAX.Callback.IDs;
 -		this.__service.post.data['__data'] = {};
 -		for(var i = 0; i<IDs.length; i++)
 -		{
 -			var id = IDs[i];
 -			if(id.indexOf("[]") > -1)
 -				this.__service.post.data['__data'][id] =
 -					this.collectArrayPostData(id);
 -			else if(isObject($(id)))
 -				this.__service.post.data['__data'][id] = $F(id);
 -		}
 +		this.options['params'] = value;
  	},
 -	collectArrayPostData : function(name)
 +	/**
 +	 * @return {Object} request paramater value.
 +	 */
 +	getParameter : function()
  	{
 -		var elements = document.getElementsByName(name);
 -		var data = [];
 -		$A(elements).each(function(el)
 -		{
 -			if($F(el)) data.push($F(el));
 -		});
 -		return data;
 +		return this.options['params'];
  	},
  	/**
 -	 * Prepares and calls the AJAX request.
 -	 * Collects the data from components that implements IPostBackHandler
 -	 * and the viewstate as part of the request payload.
 +	 * Sets the callback request timeout.
 +	 * @param {integer} timeout in  milliseconds
  	 */
 -	requestCallback : function()
 +	setRequestTimeOut : function(timeout)
  	{
 -		this.collectPostData();
 -		if(Prado.AJAX.Validate(this.options))
 -			return this.__call(Prado.AJAX.Callback.Server, 'handleCallback', this.options.params);
 +		this.options['RequestTimeOut'] = timeout;
  	},
  	/**
 -	 * On callback request return, call the onSuccess function.
 +	 * @return {integer} request timeout in milliseconds
  	 */
 -	handleCallback : function(result, output)
 +	getRequestTimeOut : function()
  	{
 -		if(typeof(result) != "undefined" && !isNull(result))
 -		{
 -			this.options.onSuccess(result['data'], output);
 -			if(result['actions'])
 -				result.actions.each(Prado.AJAX.Callback.Action.__run);
 -		}
 -	}
 -});
 +		return this.options['RequestTimeOut'];
 +	},
 -/**
 - * Prase and evaluate Callback clien-side actions.
 - */
 -Prado.AJAX.Callback.Action =
 -{
 -	__run : function(command)
 +	/**
 +	 * Set true to enable validation on callback dispatch.
 +	 * @param {boolean} true to validate
 +	 */
 +	setCausesValidation : function(validate)
  	{
 -		for(var name in command)
 -		{
 -			//first parameter must be a valid element or begins with '@'
 -			if(command[name][0] && ($(command[name][0]) || command[name][0].indexOf("[]") > -1))
 -			{
 -				name.toFunction().apply(this,command[name]);
 -			}
 -		}
 -	}
 -};
 +		this.options['CausesValidation'] = validate;
 +	},
 +
 +	/**
 +	 * @return {boolean} validate on request dispatch
 +	 */
 +	getCausesValidation : function()
 +	{
 +		return this.options['CausesValidation'];
 +	},
 +	/**
 +	 * Sets the validation group to validate during request dispatch.
 +	 * @param {string} validation group name
 +	 */
 +	setValidationGroup : function(group)
 +	{
 +		this.options['ValidationGroup'] = group;
 +	},
 -/**
 - * Returns false if validation required and validates to false,
 - * returns true otherwise.
 - * @return boolean true if validation passes.
 - */
 -Prado.AJAX.Validate = function(options)
 -{
 -	if(options.CausesValidation)
 +	/**
 +	 * @return {string} validation group name.
 +	 */
 +	getValidationGroup : function()
  	{
 -		if(options.ValidatorGroup)
 -			return Prado.Validation.ValidateValidatorGroup(options.ValidatorGroup);
 -		else if(options.ValidationGroup)
 -			return Prado.Validation.ValidateValidationGroup(options.ValidationGroup);
 -		else
 -			return Prado.Validation.ValidateNonGroup(options.ValidationForm);
 -	}
 -	else
 -		return true;
 -};
 +		return this.options['ValidationGroup'];
 +	},
 +
 +	/**
 +	 * Dispatch the callback request.
 +	 */
 +	dispatch : function()
 +	{
 +		//override parameter and postBody options.
 +		Object.extend(this.options,
 +		{
 +			postBody : this._getPostData(),
 +			parameters : ''
 +		});
 +		if(this.options.CausesValidation && typeof(Prado.Validation) != "undefined")
 +		{
 +			var form =  this.options.Form || Prado.Validation.getForm();
 +			if(Prado.Validation.validate(form,this.options.ValidationGroup,this) == false)
 +				return false;
 +		}
 -//Available callback service
 -Prado.AJAX.Callback.Server = '';
 +		if(this.options.HasPriority)
 +			return Prado.CallbackRequest.dispatchPriorityRequest(this);
 +		else
 +			return Prado.CallbackRequest.dispatchNormalRequest(this);
 +	},
 -//List of IDs that implements IPostBackHandler
 -Prado.AJAX.Callback.IDs = [];
 +	/**
 +	 * Collects the form inputs, encode the parameters, and sets the callback
 +	 * target id. The resulting string is the request content body.
 +	 * @return string request body content containing post data.
 +	 */
 +	_getPostData : function()
 +	{
 +		var data = {};
 +		var callback = Prado.CallbackRequest;
 +		if(this.options.PostInputs != false)
 +		{
 +			callback.PostDataLoaders.each(function(name)
 +			{
 +				$A(document.getElementsByName(name)).each(function(element)
 +				{
 +					//IE will try to get elements with ID == name as well.
 +					if(element.type && element.name == name)
 +					{
 +						value = $F(element);
 +						if(typeof(value) != "undefined")
 +							data[name] = value;
 +					}
 +				})
 +			})
 +		}
 +		if(typeof(this.options.params) != "undefined")
 +			data[callback.FIELD_CALLBACK_PARAMETER] = callback.encode(this.options.params);
 +		var pageState = $F(callback.FIELD_CALLBACK_PAGESTATE);
 +		if(typeof(pageState) != "undefined")
 +			data[callback.FIELD_CALLBACK_PAGESTATE] = pageState;
 +		data[callback.FIELD_CALLBACK_TARGET] = this.id;
 +		if(this.options.EventTarget)
 +			data[callback.FIELD_POSTBACK_TARGET] = this.options.EventTarget;
 +		if(this.options.EventParameter)
 +			data[callback.FIELD_POSTBACK_PARAMETER] = this.options.EventParameter;
 +		return $H(data).toQueryString();
 +	}
 +}
  /**
 - * Simple AJAX callback interface, suitable for inline javascript.
 - * e.g., <code><a href="..." onclick="Prado.Callback('..', 'Hello');">Click me</a></code>
 - * @param {String} callback ID
 - * @param {Array} parameters to pass to the callback service
 - * @param {Function} on callback success handler method
 - * @param {Object} additional callback options
 + * Create a new callback request using default settings.
 + * @param string callback handler unique ID.
 + * @param mixed parameter to pass to callback handler on the server side.
 + * @param function client side onSuccess event handler.
 + * @param object additional request options.
 + * @return boolean always false.
   */
 -Prado.Callback = function(ID, params, onSuccess, options)
 +Prado.Callback = function(UniqueID, parameter, onSuccess, options)
  {
  	var callback =
  	{
 -		'params' : [params] || [],
 -		'onSuccess' : onSuccess || Prototype.emptyFunction,
 -		'CausesValidation' : true
 +		'params' : parameter || '',
 +		'onSuccess' : onSuccess || Prototype.emptyFunction
  	};
  	Object.extend(callback, options || {});
 -	new Prado.AJAX.Callback(ID, callback);
 +	request = new Prado.CallbackRequest(UniqueID, callback);
 +	request.dispatch();
  	return false;
 -} +}
 +  /*
  Copyright (c) 2005 JSON.org
 @@ -737,7 +845,7 @@ SOFTWARE.  Array.prototype.______array = '______array';
 -Prado.AJAX.JSON = {
 +Prado.JSON = {
      org: 'http://www.JSON.org',
      copyright: '(c)2005 JSON.org',
      license: 'http://www.crockford.com/JSON/license.html',
 @@ -1878,1426 +1986,583 @@ Form.Element.DelayedObserver.prototype = {  }; -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -//           (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) -//  -// See scriptaculous.js for full license. - -/*--------------------------------------------------------------------------*/ - -if(typeof Effect == 'undefined') -  throw("dragdrop.js requires including script.aculo.us' effects.js library"); - -var Droppables = { -  drops: [], - -  remove: function(element) { -    this.drops = this.drops.reject(function(d) { return d.element==$(element) }); -  }, - -  add: function(element) { -    element = $(element); -    var options = Object.extend({ -      greedy:     true, -      hoverclass: null, -      tree:       false -    }, arguments[1] || {}); - -    // cache containers -    if(options.containment) { -      options._containers = []; -      var containment = options.containment; -      if((typeof containment == 'object') &&  -        (containment.constructor == Array)) { -        containment.each( function(c) { options._containers.push($(c)) }); -      } else { -        options._containers.push($(containment)); -      } -    } -     -    if(options.accept) options.accept = [options.accept].flatten(); - -    Element.makePositioned(element); // fix IE -    options.element = element; - -    this.drops.push(options); -  }, -   -  findDeepestChild: function(drops) { -    deepest = drops[0]; -       -    for (i = 1; i < drops.length; ++i) -      if (Element.isParent(drops[i].element, deepest.element)) -        deepest = drops[i]; -     -    return deepest; -  }, - -  isContained: function(element, drop) { -    var containmentNode; -    if(drop.tree) { -      containmentNode = element.treeNode;  -    } else { -      containmentNode = element.parentNode; -    } -    return drop._containers.detect(function(c) { return containmentNode == c }); -  }, -   -  isAffected: function(point, element, drop) { -    return ( -      (drop.element!=element) && -      ((!drop._containers) || -        this.isContained(element, drop)) && -      ((!drop.accept) || -        (Element.classNames(element).detect(  -          function(v) { return drop.accept.include(v) } ) )) && -      Position.within(drop.element, point[0], point[1]) ); -  }, - -  deactivate: function(drop) { -    if(drop.hoverclass) -      Element.removeClassName(drop.element, drop.hoverclass); -    this.last_active = null; -  }, - -  activate: function(drop) { -    if(drop.hoverclass) -      Element.addClassName(drop.element, drop.hoverclass); -    this.last_active = drop; -  }, - -  show: function(point, element) { -    if(!this.drops.length) return; -    var affected = []; -     -    if(this.last_active) this.deactivate(this.last_active); -    this.drops.each( function(drop) { -      if(Droppables.isAffected(point, element, drop)) -        affected.push(drop); -    }); -         -    if(affected.length>0) { -      drop = Droppables.findDeepestChild(affected); -      Position.within(drop.element, point[0], point[1]); -      if(drop.onHover) -        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); -       -      Droppables.activate(drop); -    } -  }, - -  fire: function(event, element) { -    if(!this.last_active) return; -    Position.prepare(); - -    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) -      if (this.last_active.onDrop)  -        this.last_active.onDrop(element, this.last_active.element, event); -  }, - -  reset: function() { -    if(this.last_active) -      this.deactivate(this.last_active); -  } -} - -var Draggables = { -  drags: [], -  observers: [], -   -  register: function(draggable) { -    if(this.drags.length == 0) { -      this.eventMouseUp   = this.endDrag.bindAsEventListener(this); -      this.eventMouseMove = this.updateDrag.bindAsEventListener(this); -      this.eventKeypress  = this.keyPress.bindAsEventListener(this); -       -      Event.observe(document, "mouseup", this.eventMouseUp); -      Event.observe(document, "mousemove", this.eventMouseMove); -      Event.observe(document, "keypress", this.eventKeypress); -    } -    this.drags.push(draggable); -  }, -   -  unregister: function(draggable) { -    this.drags = this.drags.reject(function(d) { return d==draggable }); -    if(this.drags.length == 0) { -      Event.stopObserving(document, "mouseup", this.eventMouseUp); -      Event.stopObserving(document, "mousemove", this.eventMouseMove); -      Event.stopObserving(document, "keypress", this.eventKeypress); -    } -  }, -   -  activate: function(draggable) { -    window.focus(); // allows keypress events if window isn't currently focused, fails for Safari -    this.activeDraggable = draggable; -  }, -   -  deactivate: function() { -    this.activeDraggable = null; -  }, -   -  updateDrag: function(event) { -    if(!this.activeDraggable) return; -    var pointer = [Event.pointerX(event), Event.pointerY(event)]; -    // Mozilla-based browsers fire successive mousemove events with -    // the same coordinates, prevent needless redrawing (moz bug?) -    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; -    this._lastPointer = pointer; -    this.activeDraggable.updateDrag(event, pointer); -  }, -   -  endDrag: function(event) { -    if(!this.activeDraggable) return; -    this._lastPointer = null; -    this.activeDraggable.endDrag(event); -    this.activeDraggable = null; -  }, -   -  keyPress: function(event) { -    if(this.activeDraggable) -      this.activeDraggable.keyPress(event); -  }, -   -  addObserver: function(observer) { -    this.observers.push(observer); -    this._cacheObserverCallbacks(); -  }, -   -  removeObserver: function(element) {  // element instead of observer fixes mem leaks -    this.observers = this.observers.reject( function(o) { return o.element==element }); -    this._cacheObserverCallbacks(); -  }, -   -  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag' -    if(this[eventName+'Count'] > 0) -      this.observers.each( function(o) { -        if(o[eventName]) o[eventName](eventName, draggable, event); -      }); -  }, -   -  _cacheObserverCallbacks: function() { -    ['onStart','onEnd','onDrag'].each( function(eventName) { -      Draggables[eventName+'Count'] = Draggables.observers.select( -        function(o) { return o[eventName]; } -      ).length; -    }); -  } -} - -/*--------------------------------------------------------------------------*/ - -var Draggable = Class.create(); -Draggable._revertCache = {}; -Draggable._dragging    = {}; - -Draggable.prototype = { -  initialize: function(element) { -    var options = Object.extend({ -      handle: false, -      starteffect: function(element) { -        element._opacity = Element.getOpacity(element); -        Draggable._dragging[element] = true; -        new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});  -      }, -      reverteffect: function(element, top_offset, left_offset) { -        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; -        Draggable._revertCache[element] = -          new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, -            queue: {scope:'_draggable', position:'end'} -          }); -      }, -      endeffect: function(element) { -        var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; -        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,  -          queue: {scope:'_draggable', position:'end'}, -          afterFinish: function(){ Draggable._dragging[element] = false } -        });  -      }, -      zindex: 1000, -      revert: false, -      scroll: false, -      scrollSensitivity: 20, -      scrollSpeed: 15, -      snap: false   // false, or xy or [x,y] or function(x,y){ return [x,y] } -    }, arguments[1] || {}); - -    this.element = $(element); -     -    if(options.handle && (typeof options.handle == 'string')) { -      var h = Element.childrenWithClassName(this.element, options.handle, true); -      if(h.length>0) this.handle = h[0]; -    } -    if(!this.handle) this.handle = $(options.handle); -    if(!this.handle) this.handle = this.element; -     -    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) -      options.scroll = $(options.scroll); - -    Element.makePositioned(this.element); // fix IE     - -    this.delta    = this.currentDelta(); -    this.options  = options; -    this.dragging = false;    - -    this.eventMouseDown = this.initDrag.bindAsEventListener(this); -    Event.observe(this.handle, "mousedown", this.eventMouseDown); -     -    Draggables.register(this); -  }, -   -  destroy: function() { -    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); -    Draggables.unregister(this); -  }, -   -  currentDelta: function() { -    return([ -      parseInt(Element.getStyle(this.element,'left') || '0'), -      parseInt(Element.getStyle(this.element,'top') || '0')]); -  }, -   -  initDrag: function(event) { -    if(typeof Draggable._dragging[this.element] != undefined && -      Draggable._dragging[this.element]) return; -    if(Event.isLeftClick(event)) {     -      // abort on form elements, fixes a Firefox issue -      var src = Event.element(event); -      if(src.tagName && ( -        src.tagName=='INPUT' || -        src.tagName=='SELECT' || -        src.tagName=='OPTION' || -        src.tagName=='BUTTON' || -        src.tagName=='TEXTAREA')) return; -         -      if(Draggable._revertCache[this.element]) { -        Draggable._revertCache[this.element].cancel(); -        Draggable._revertCache[this.element] = null; -      } -       -      var pointer = [Event.pointerX(event), Event.pointerY(event)]; -      var pos     = Position.cumulativeOffset(this.element); -      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); -       -      Draggables.activate(this); -      Event.stop(event); -    } -  }, -   -  startDrag: function(event) { -    this.dragging = true; -     -    if(this.options.zindex) { -      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); -      this.element.style.zIndex = this.options.zindex; -    } -     -    if(this.options.ghosting) { -      this._clone = this.element.cloneNode(true); -      Position.absolutize(this.element); -      this.element.parentNode.insertBefore(this._clone, this.element); -    } -     -    if(this.options.scroll) { -      if (this.options.scroll == window) { -        var where = this._getWindowScroll(this.options.scroll); -        this.originalScrollLeft = where.left; -        this.originalScrollTop = where.top; -      } else { -        this.originalScrollLeft = this.options.scroll.scrollLeft; -        this.originalScrollTop = this.options.scroll.scrollTop; -      } -    } -     -    Draggables.notify('onStart', this, event); -    if(this.options.starteffect) this.options.starteffect(this.element); -  }, -   -  updateDrag: function(event, pointer) { -    if(!this.dragging) this.startDrag(event); -    Position.prepare(); -    Droppables.show(pointer, this.element); -    Draggables.notify('onDrag', this, event); -    this.draw(pointer); -    if(this.options.change) this.options.change(this); -     -    if(this.options.scroll) { -      this.stopScrolling(); -       -      var p; -      if (this.options.scroll == window) { -        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } -      } else { -        p = Position.page(this.options.scroll); -        p[0] += this.options.scroll.scrollLeft; -        p[1] += this.options.scroll.scrollTop; -        p.push(p[0]+this.options.scroll.offsetWidth); -        p.push(p[1]+this.options.scroll.offsetHeight); -      } -      var speed = [0,0]; -      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); -      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); -      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); -      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); -      this.startScrolling(speed); -    } -     -    // fix AppleWebKit rendering -    if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); -     -    Event.stop(event); -  }, -   -  finishDrag: function(event, success) { -    this.dragging = false; - -    if(this.options.ghosting) { -      Position.relativize(this.element); -      Element.remove(this._clone); -      this._clone = null; -    } - -    if(success) Droppables.fire(event, this.element); -    Draggables.notify('onEnd', this, event); - -    var revert = this.options.revert; -    if(revert && typeof revert == 'function') revert = revert(this.element); -     -    var d = this.currentDelta(); -    if(revert && this.options.reverteffect) { -      this.options.reverteffect(this.element,  -        d[1]-this.delta[1], d[0]-this.delta[0]); -    } else { -      this.delta = d; -    } - -    if(this.options.zindex) -      this.element.style.zIndex = this.originalZ; - -    if(this.options.endeffect)  -      this.options.endeffect(this.element); - -    Draggables.deactivate(this); -    Droppables.reset(); -  }, -   -  keyPress: function(event) { -    if(event.keyCode!=Event.KEY_ESC) return; -    this.finishDrag(event, false); -    Event.stop(event); -  }, -   -  endDrag: function(event) { -    if(!this.dragging) return; -    this.stopScrolling(); -    this.finishDrag(event, true); -    Event.stop(event); -  }, -   -  draw: function(point) { -    var pos = Position.cumulativeOffset(this.element); -    var d = this.currentDelta(); -    pos[0] -= d[0]; pos[1] -= d[1]; -     -    if(this.options.scroll && (this.options.scroll != window)) { -      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; -      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; -    } -     -    var p = [0,1].map(function(i){  -      return (point[i]-pos[i]-this.offset[i])  -    }.bind(this)); -     -    if(this.options.snap) { -      if(typeof this.options.snap == 'function') { -        p = this.options.snap(p[0],p[1],this); -      } else { -      if(this.options.snap instanceof Array) { -        p = p.map( function(v, i) { -          return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) -      } else { -        p = p.map( function(v) { -          return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) -      } -    }} -     -    var style = this.element.style; -    if((!this.options.constraint) || (this.options.constraint=='horizontal')) -      style.left = p[0] + "px"; -    if((!this.options.constraint) || (this.options.constraint=='vertical')) -      style.top  = p[1] + "px"; -    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering -  }, -   -  stopScrolling: function() { -    if(this.scrollInterval) { -      clearInterval(this.scrollInterval); -      this.scrollInterval = null; -      Draggables._lastScrollPointer = null; -    } -  }, -   -  startScrolling: function(speed) { -    if(!(speed[0] || speed[1])) return; -    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; -    this.lastScrolled = new Date(); -    this.scrollInterval = setInterval(this.scroll.bind(this), 10); -  }, -   -  scroll: function() { -    var current = new Date(); -    var delta = current - this.lastScrolled; -    this.lastScrolled = current; -    if(this.options.scroll == window) { -      with (this._getWindowScroll(this.options.scroll)) { -        if (this.scrollSpeed[0] || this.scrollSpeed[1]) { -          var d = delta / 1000; -          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); -        } -      } -    } else { -      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; -      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000; -    } -     -    Position.prepare(); -    Droppables.show(Draggables._lastPointer, this.element); -    Draggables.notify('onDrag', this); -    Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); -    Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; -    Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; -    if (Draggables._lastScrollPointer[0] < 0) -      Draggables._lastScrollPointer[0] = 0; -    if (Draggables._lastScrollPointer[1] < 0) -      Draggables._lastScrollPointer[1] = 0; -    this.draw(Draggables._lastScrollPointer); -     -    if(this.options.change) this.options.change(this); -  }, -   -  _getWindowScroll: function(w) { -    var T, L, W, H; -    with (w.document) { -      if (w.document.documentElement && documentElement.scrollTop) { -        T = documentElement.scrollTop; -        L = documentElement.scrollLeft; -      } else if (w.document.body) { -        T = body.scrollTop; -        L = body.scrollLeft; -      } -      if (w.innerWidth) { -        W = w.innerWidth; -        H = w.innerHeight; -      } else if (w.document.documentElement && documentElement.clientWidth) { -        W = documentElement.clientWidth; -        H = documentElement.clientHeight; -      } else { -        W = body.offsetWidth; -        H = body.offsetHeight -      } -    } -    return { top: T, left: L, width: W, height: H }; -  } -} - -/*--------------------------------------------------------------------------*/ - -var SortableObserver = Class.create(); -SortableObserver.prototype = { -  initialize: function(element, observer) { -    this.element   = $(element); -    this.observer  = observer; -    this.lastValue = Sortable.serialize(this.element); -  }, -   -  onStart: function() { -    this.lastValue = Sortable.serialize(this.element); -  }, -   -  onEnd: function() { -    Sortable.unmark(); -    if(this.lastValue != Sortable.serialize(this.element)) -      this.observer(this.element) -  } -} - -var Sortable = { -  sortables: {}, -   -  _findRootElement: function(element) { -    while (element.tagName != "BODY") {   -      if(element.id && Sortable.sortables[element.id]) return element; -      element = element.parentNode; -    } -  }, - -  options: function(element) { -    element = Sortable._findRootElement($(element)); -    if(!element) return; -    return Sortable.sortables[element.id]; -  }, -   -  destroy: function(element){ -    var s = Sortable.options(element); -     -    if(s) { -      Draggables.removeObserver(s.element); -      s.droppables.each(function(d){ Droppables.remove(d) }); -      s.draggables.invoke('destroy'); -       -      delete Sortable.sortables[s.element.id]; -    } -  }, - -  create: function(element) { -    element = $(element); -    var options = Object.extend({  -      element:     element, -      tag:         'li',       // assumes li children, override with tag: 'tagname' -      dropOnEmpty: false, -      tree:        false, -      treeTag:     'ul', -      overlap:     'vertical', // one of 'vertical', 'horizontal' -      constraint:  'vertical', // one of 'vertical', 'horizontal', false -      containment: element,    // also takes array of elements (or id's); or false -      handle:      false,      // or a CSS class -      only:        false, -      hoverclass:  null, -      ghosting:    false, -      scroll:      false, -      scrollSensitivity: 20, -      scrollSpeed: 15, -      format:      /^[^_]*_(.*)$/, -      onChange:    Prototype.emptyFunction, -      onUpdate:    Prototype.emptyFunction -    }, arguments[1] || {}); - -    // clear any old sortable with same element -    this.destroy(element); - -    // build options for the draggables -    var options_for_draggable = { -      revert:      true, -      scroll:      options.scroll, -      scrollSpeed: options.scrollSpeed, -      scrollSensitivity: options.scrollSensitivity, -      ghosting:    options.ghosting, -      constraint:  options.constraint, -      handle:      options.handle }; - -    if(options.starteffect) -      options_for_draggable.starteffect = options.starteffect; - -    if(options.reverteffect) -      options_for_draggable.reverteffect = options.reverteffect; -    else -      if(options.ghosting) options_for_draggable.reverteffect = function(element) { -        element.style.top  = 0; -        element.style.left = 0; -      }; - -    if(options.endeffect) -      options_for_draggable.endeffect = options.endeffect; - -    if(options.zindex) -      options_for_draggable.zindex = options.zindex; - -    // build options for the droppables   -    var options_for_droppable = { -      overlap:     options.overlap, -      containment: options.containment, -      tree:        options.tree, -      hoverclass:  options.hoverclass, -      onHover:     Sortable.onHover -      //greedy:      !options.dropOnEmpty -    } -     -    var options_for_tree = { -      onHover:      Sortable.onEmptyHover, -      overlap:      options.overlap, -      containment:  options.containment, -      hoverclass:   options.hoverclass -    } - -    // fix for gecko engine -    Element.cleanWhitespace(element);  - -    options.draggables = []; -    options.droppables = []; - -    // drop on empty handling -    if(options.dropOnEmpty || options.tree) { -      Droppables.add(element, options_for_tree); -      options.droppables.push(element); -    } - -    (this.findElements(element, options) || []).each( function(e) { -      // handles are per-draggable -      var handle = options.handle ?  -        Element.childrenWithClassName(e, options.handle)[0] : e;     -      options.draggables.push( -        new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); -      Droppables.add(e, options_for_droppable); -      if(options.tree) e.treeNode = element; -      options.droppables.push(e);       -    }); -     -    if(options.tree) { -      (Sortable.findTreeElements(element, options) || []).each( function(e) { -        Droppables.add(e, options_for_tree); -        e.treeNode = element; -        options.droppables.push(e); -      }); -    } - -    // keep reference -    this.sortables[element.id] = options; - -    // for onupdate -    Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - -  }, - -  // return all suitable-for-sortable elements in a guaranteed order -  findElements: function(element, options) { -    return Element.findChildren( -      element, options.only, options.tree ? true : false, options.tag); -  }, -   -  findTreeElements: function(element, options) { -    return Element.findChildren( -      element, options.only, options.tree ? true : false, options.treeTag); -  }, - -  onHover: function(element, dropon, overlap) { -    if(Element.isParent(dropon, element)) return; - -    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { -      return; -    } else if(overlap>0.5) { -      Sortable.mark(dropon, 'before'); -      if(dropon.previousSibling != element) { -        var oldParentNode = element.parentNode; -        element.style.visibility = "hidden"; // fix gecko rendering -        dropon.parentNode.insertBefore(element, dropon); -        if(dropon.parentNode!=oldParentNode)  -          Sortable.options(oldParentNode).onChange(element); -        Sortable.options(dropon.parentNode).onChange(element); -      } -    } else { -      Sortable.mark(dropon, 'after'); -      var nextElement = dropon.nextSibling || null; -      if(nextElement != element) { -        var oldParentNode = element.parentNode; -        element.style.visibility = "hidden"; // fix gecko rendering -        dropon.parentNode.insertBefore(element, nextElement); -        if(dropon.parentNode!=oldParentNode)  -          Sortable.options(oldParentNode).onChange(element); -        Sortable.options(dropon.parentNode).onChange(element); -      } -    } -  }, -   -  onEmptyHover: function(element, dropon, overlap) { -    var oldParentNode = element.parentNode; -    var droponOptions = Sortable.options(dropon); -         -    if(!Element.isParent(dropon, element)) { -      var index; -       -      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); -      var child = null; -             -      if(children) { -        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); -         -        for (index = 0; index < children.length; index += 1) { -          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { -            offset -= Element.offsetSize (children[index], droponOptions.overlap); -          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { -            child = index + 1 < children.length ? children[index + 1] : null; -            break; -          } else { -            child = children[index]; -            break; -          } -        } -      } -       -      dropon.insertBefore(element, child); -       -      Sortable.options(oldParentNode).onChange(element); -      droponOptions.onChange(element); -    } -  }, - -  unmark: function() { -    if(Sortable._marker) Element.hide(Sortable._marker); -  }, - -  mark: function(dropon, position) { -    // mark on ghosting only -    var sortable = Sortable.options(dropon.parentNode); -    if(sortable && !sortable.ghosting) return;  - -    if(!Sortable._marker) { -      Sortable._marker = $('dropmarker') || document.createElement('DIV'); -      Element.hide(Sortable._marker); -      Element.addClassName(Sortable._marker, 'dropmarker'); -      Sortable._marker.style.position = 'absolute'; -      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); -    }     -    var offsets = Position.cumulativeOffset(dropon); -    Sortable._marker.style.left = offsets[0] + 'px'; -    Sortable._marker.style.top = offsets[1] + 'px'; -     -    if(position=='after') -      if(sortable.overlap == 'horizontal')  -        Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; -      else -        Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; -     -    Element.show(Sortable._marker); -  }, -   -  _tree: function(element, options, parent) { -    var children = Sortable.findElements(element, options) || []; -   -    for (var i = 0; i < children.length; ++i) { -      var match = children[i].id.match(options.format); - -      if (!match) continue; -       -      var child = { -        id: encodeURIComponent(match ? match[1] : null), -        element: element, -        parent: parent, -        children: new Array, -        position: parent.children.length, -        container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) -      } -       -      /* Get the element containing the children and recurse over it */ -      if (child.container) -        this._tree(child.container, options, child) -       -      parent.children.push (child); -    } - -    return parent;  -  }, - -  /* Finds the first element of the given tag type within a parent element. -    Used for finding the first LI[ST] within a L[IST]I[TEM].*/ -  _findChildrenElement: function (element, containerTag) { -    if (element && element.hasChildNodes) -      for (var i = 0; i < element.childNodes.length; ++i) -        if (element.childNodes[i].tagName == containerTag) -          return element.childNodes[i]; -   -    return null; -  }, - -  tree: function(element) { -    element = $(element); -    var sortableOptions = this.options(element); -    var options = Object.extend({ -      tag: sortableOptions.tag, -      treeTag: sortableOptions.treeTag, -      only: sortableOptions.only, -      name: element.id, -      format: sortableOptions.format -    }, arguments[1] || {}); -     -    var root = { -      id: null, -      parent: null, -      children: new Array, -      container: element, -      position: 0 -    } -     -    return Sortable._tree (element, options, root); -  }, - -  /* Construct a [i] index for a particular node */ -  _constructIndex: function(node) { -    var index = ''; -    do { -      if (node.id) index = '[' + node.position + ']' + index; -    } while ((node = node.parent) != null); -    return index; -  }, - -  sequence: function(element) { -    element = $(element); -    var options = Object.extend(this.options(element), arguments[1] || {}); -     -    return $(this.findElements(element, options) || []).map( function(item) { -      return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; -    }); -  }, - -  setSequence: function(element, new_sequence) { -    element = $(element); -    var options = Object.extend(this.options(element), arguments[2] || {}); -     -    var nodeMap = {}; -    this.findElements(element, options).each( function(n) { -        if (n.id.match(options.format)) -            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; -        n.parentNode.removeChild(n); -    }); -    -    new_sequence.each(function(ident) { -      var n = nodeMap[ident]; -      if (n) { -        n[1].appendChild(n[0]); -        delete nodeMap[ident]; -      } -    }); -  }, -   -  serialize: function(element) { -    element = $(element); -    var options = Object.extend(Sortable.options(element), arguments[1] || {}); -    var name = encodeURIComponent( -      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); -     -    if (options.tree) { -      return Sortable.tree(element, arguments[1]).children.map( function (item) { -        return [name + Sortable._constructIndex(item) + "[id]=" +  -                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); -      }).flatten().join('&'); -    } else { -      return Sortable.sequence(element, arguments[1]).map( function(item) { -        return name + "[]=" + encodeURIComponent(item); -      }).join('&'); -    } -  } -} - -/* Returns true if child is contained within element */ -Element.isParent = function(child, element) { -  if (!child.parentNode || child == element) return false; - -  if (child.parentNode == element) return true; - -  return Element.isParent(child.parentNode, element); -} - -Element.findChildren = function(element, only, recursive, tagName) {     -  if(!element.hasChildNodes()) return null; -  tagName = tagName.toUpperCase(); -  if(only) only = [only].flatten(); -  var elements = []; -  $A(element.childNodes).each( function(e) { -    if(e.tagName && e.tagName.toUpperCase()==tagName && -      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) -        elements.push(e); -    if(recursive) { -      var grandchildren = Element.findChildren(e, only, recursive, tagName); -      if(grandchildren) elements.push(grandchildren); -    } -  }); - -  return (elements.length>0 ? elements.flatten() : []); -} - -Element.offsetSize = function (element, type) { -  if (type == 'vertical' || type == 'height') -    return element.offsetHeight; -  else -    return element.offsetWidth; -} - -// Copyright (c) 2005 Marty Haught, Thomas Fuchs  -// -// See http://script.aculo.us for more info -//  -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -//  -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -if(!Control) var Control = {}; -Control.Slider = Class.create(); - -// options: -//  axis: 'vertical', or 'horizontal' (default) -// -// callbacks: -//  onChange(value) -//  onSlide(value) -Control.Slider.prototype = { -  initialize: function(handle, track, options) { -    var slider = this; -     -    if(handle instanceof Array) { -      this.handles = handle.collect( function(e) { return $(e) }); -    } else { -      this.handles = [$(handle)]; -    } -     -    this.track   = $(track); -    this.options = options || {}; - -    this.axis      = this.options.axis || 'horizontal'; -    this.increment = this.options.increment || 1; -    this.step      = parseInt(this.options.step || '1'); -    this.range     = this.options.range || $R(0,1); -     -    this.value     = 0; // assure backwards compat -    this.values    = this.handles.map( function() { return 0 }); -    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; -    this.options.startSpan = $(this.options.startSpan || null); -    this.options.endSpan   = $(this.options.endSpan || null); - -    this.restricted = this.options.restricted || false; - -    this.maximum   = this.options.maximum || this.range.end; -    this.minimum   = this.options.minimum || this.range.start; - -    // Will be used to align the handle onto the track, if necessary -    this.alignX = parseInt(this.options.alignX || '0'); -    this.alignY = parseInt(this.options.alignY || '0'); -     -    this.trackLength = this.maximumOffset() - this.minimumOffset(); - -    this.handleLength = this.isVertical() ?  -      (this.handles[0].offsetHeight != 0 ?  -        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :  -      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :  -        this.handles[0].style.width.replace(/px$/,"")); - -    this.active   = false; -    this.dragging = false; -    this.disabled = false; - -    if(this.options.disabled) this.setDisabled(); - -    // Allowed values array -    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; -    if(this.allowedValues) { -      this.minimum = this.allowedValues.min(); -      this.maximum = this.allowedValues.max(); -    } - -    this.eventMouseDown = this.startDrag.bindAsEventListener(this); -    this.eventMouseUp   = this.endDrag.bindAsEventListener(this); -    this.eventMouseMove = this.update.bindAsEventListener(this); - -    // Initialize handles in reverse (make sure first handle is active) -    this.handles.each( function(h,i) { -      i = slider.handles.length-1-i; -      slider.setValue(parseFloat( -        (slider.options.sliderValue instanceof Array ?  -          slider.options.sliderValue[i] : slider.options.sliderValue) ||  -         slider.range.start), i); -      Element.makePositioned(h); // fix IE -      Event.observe(h, "mousedown", slider.eventMouseDown); -    }); -     -    Event.observe(this.track, "mousedown", this.eventMouseDown); -    Event.observe(document, "mouseup", this.eventMouseUp); -    Event.observe(document, "mousemove", this.eventMouseMove); -     -    this.initialized = true; -  }, -  dispose: function() { -    var slider = this;     -    Event.stopObserving(this.track, "mousedown", this.eventMouseDown); -    Event.stopObserving(document, "mouseup", this.eventMouseUp); -    Event.stopObserving(document, "mousemove", this.eventMouseMove); -    this.handles.each( function(h) { -      Event.stopObserving(h, "mousedown", slider.eventMouseDown); -    }); -  }, -  setDisabled: function(){ -    this.disabled = true; -  }, -  setEnabled: function(){ -    this.disabled = false; -  },   -  getNearestValue: function(value){ -    if(this.allowedValues){ -      if(value >= this.allowedValues.max()) return(this.allowedValues.max()); -      if(value <= this.allowedValues.min()) return(this.allowedValues.min()); -       -      var offset = Math.abs(this.allowedValues[0] - value); -      var newValue = this.allowedValues[0]; -      this.allowedValues.each( function(v) { -        var currentOffset = Math.abs(v - value); -        if(currentOffset <= offset){ -          newValue = v; -          offset = currentOffset; -        }  -      }); -      return newValue; -    } -    if(value > this.range.end) return this.range.end; -    if(value < this.range.start) return this.range.start; -    return value; -  }, -  setValue: function(sliderValue, handleIdx){ -    if(!this.active) { -      this.activeHandleIdx = handleIdx || 0; -      this.activeHandle    = this.handles[this.activeHandleIdx]; -      this.updateStyles(); -    } -    handleIdx = handleIdx || this.activeHandleIdx || 0; -    if(this.initialized && this.restricted) { -      if((handleIdx>0) && (sliderValue<this.values[handleIdx-1])) -        sliderValue = this.values[handleIdx-1]; -      if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1])) -        sliderValue = this.values[handleIdx+1]; -    } -    sliderValue = this.getNearestValue(sliderValue); -    this.values[handleIdx] = sliderValue; -    this.value = this.values[0]; // assure backwards compat -     -    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =  -      this.translateToPx(sliderValue); -     -    this.drawSpans(); -    if(!this.dragging || !this.event) this.updateFinished(); -  }, -  setValueBy: function(delta, handleIdx) { -    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,  -      handleIdx || this.activeHandleIdx || 0); -  }, -  translateToPx: function(value) { -    return Math.round( -      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *  -      (value - this.range.start)) + "px"; -  }, -  translateToValue: function(offset) { -    return ((offset/(this.trackLength-this.handleLength) *  -      (this.range.end-this.range.start)) + this.range.start); -  }, -  getRange: function(range) { -    var v = this.values.sortBy(Prototype.K);  -    range = range || 0; -    return $R(v[range],v[range+1]); -  }, -  minimumOffset: function(){ -    return(this.isVertical() ? this.alignY : this.alignX); -  }, -  maximumOffset: function(){ -    return(this.isVertical() ?  -      (this.track.offsetHeight != 0 ? this.track.offsetHeight : -        this.track.style.height.replace(/px$/,"")) - this.alignY :  -      (this.track.offsetWidth != 0 ? this.track.offsetWidth :  -        this.track.style.width.replace(/px$/,"")) - this.alignY); -  },   -  isVertical:  function(){ -    return (this.axis == 'vertical'); -  }, -  drawSpans: function() { -    var slider = this; -    if(this.spans) -      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); -    if(this.options.startSpan) -      this.setSpan(this.options.startSpan, -        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); -    if(this.options.endSpan) -      this.setSpan(this.options.endSpan,  -        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); -  }, -  setSpan: function(span, range) { -    if(this.isVertical()) { -      span.style.top = this.translateToPx(range.start); -      span.style.height = this.translateToPx(range.end - range.start + this.range.start); -    } else { -      span.style.left = this.translateToPx(range.start); -      span.style.width = this.translateToPx(range.end - range.start + this.range.start); -    } -  }, -  updateStyles: function() { -    this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); -    Element.addClassName(this.activeHandle, 'selected'); -  }, -  startDrag: function(event) { -    if(Event.isLeftClick(event)) { -      if(!this.disabled){ -        this.active = true; -         -        var handle = Event.element(event); -        var pointer  = [Event.pointerX(event), Event.pointerY(event)]; -        var track = handle; -        if(track==this.track) { -          var offsets  = Position.cumulativeOffset(this.track);  -          this.event = event; -          this.setValue(this.translateToValue(  -           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) -          )); -          var offsets  = Position.cumulativeOffset(this.activeHandle); -          this.offsetX = (pointer[0] - offsets[0]); -          this.offsetY = (pointer[1] - offsets[1]); -        } else { -          // find the handle (prevents issues with Safari) -          while((this.handles.indexOf(handle) == -1) && handle.parentNode)  -            handle = handle.parentNode; -         -          this.activeHandle    = handle; -          this.activeHandleIdx = this.handles.indexOf(this.activeHandle); -          this.updateStyles(); -         -          var offsets  = Position.cumulativeOffset(this.activeHandle); -          this.offsetX = (pointer[0] - offsets[0]); -          this.offsetY = (pointer[1] - offsets[1]); -        } -      } -      Event.stop(event); -    } -  }, -  update: function(event) { -   if(this.active) { -      if(!this.dragging) this.dragging = true; -      this.draw(event); -      // fix AppleWebKit rendering -      if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); -      Event.stop(event); -   } -  }, -  draw: function(event) { -    var pointer = [Event.pointerX(event), Event.pointerY(event)]; -    var offsets = Position.cumulativeOffset(this.track); -    pointer[0] -= this.offsetX + offsets[0]; -    pointer[1] -= this.offsetY + offsets[1]; -    this.event = event; -    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); -    if(this.initialized && this.options.onSlide) -      this.options.onSlide(this.values.length>1 ? this.values : this.value, this); -  }, -  endDrag: function(event) { -    if(this.active && this.dragging) { -      this.finishDrag(event, true); -      Event.stop(event); -    } -    this.active = false; -    this.dragging = false; -  },   -  finishDrag: function(event, success) { -    this.active = false; -    this.dragging = false; -    this.updateFinished(); -  }, -  updateFinished: function() { -    if(this.initialized && this.options.onChange)  -      this.options.onChange(this.values.length>1 ? this.values : this.value, this); -    this.event = null; -  } -} -  /**
 - * Auto complete textbox via AJAX.
 + * Generic postback control.
   */
 -Prado.AutoCompleter = Class.create();
 +Prado.WebUI.CallbackControl = Class.extend(Prado.WebUI.PostBackControl,
 +{
 +	onPostBack : function(event, options)
 +	{
 +		request = new Prado.CallbackRequest(options.EventTarget, options);
 +		request.dispatch();
 +		Event.stop(event);
 +	}
 +});
 +/**
 + * TActiveButton control.
 + */
 +Prado.WebUI.TActiveButton = Class.extend(Prado.WebUI.CallbackControl);
 +/**
 + * TActiveLinkButton control.
 + */
 +Prado.WebUI.TActiveLinkButton = Class.extend(Prado.WebUI.CallbackControl);
 +Prado.WebUI.TActiveImageButton = Class.extend(Prado.WebUI.TImageButton,
 +{
 +	onPostBack : function(event, options)
 +	{
 +		this.addXYInput(event,options);
 +		request = new Prado.CallbackRequest(options.EventTarget, options);
 +		request.dispatch();
 +		Event.stop(event);
 +	}
 +});
  /**
 - * Overrides parent implementation of updateElement by trimming the value.
 + * Active check box.
   */
 -Prado.AutoCompleter.Base = function(){};
 -Prado.AutoCompleter.Base.prototype = Object.extend(Autocompleter.Base.prototype,
 +Prado.WebUI.TActiveCheckBox = Class.extend(Prado.WebUI.CallbackControl,
  {
 -  updateElement: function(selectedElement) 
 -  {
 -    if (this.options.updateElement) {
 -      this.options.updateElement(selectedElement);
 -      return;
 -    }
 +	onPostBack : function(event, options)
 +	{
 +		request = new Prado.CallbackRequest(options.EventTarget, options);
 +		request.dispatch();
 +	}
 +});
 -    var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
 -    var lastTokenPos = this.findLastToken();
 -    if (lastTokenPos != -1) {
 -      var newValue = this.element.value.substr(0, lastTokenPos + 1);
 -      var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
 -      if (whitespace)
 -        newValue += whitespace[0];
 -      this.element.value = (newValue + value).trim();
 -    } else {
 -      this.element.value = value.trim();
 -    }
 -    this.element.focus();
 -    
 -    if (this.options.afterUpdateElement)
 -      this.options.afterUpdateElement(this.element, selectedElement);
 -  }
 +/**
 + * TActiveRadioButton control.
 + */
 +Prado.WebUI.TActiveRadioButton = Class.extend(Prado.WebUI.TActiveCheckBox);
 +
 +
 +/**
 + * TActiveTextBox control, handles onchange event.
 + */
 +Prado.WebUI.TActiveTextBox = Class.extend(Prado.WebUI.TTextBox,
 +{
 +	onInit : function(options)
 +	{
 +		if(options['TextMode'] != 'MultiLine')
 +			Event.observe(this.element, "keydown", this.handleReturnKey.bind(this));
 +		Event.observe(this.element, "change", this.doCallback.bindEvent(this,options));
 +	},
 +
 +	doCallback : function(event, options)
 +	{
 +		request = new Prado.CallbackRequest(options.EventTarget, options);
 +		request.dispatch();
 +		Event.stop(event);
 +	}
  });
  /**
 - * Based on the Prototype Autocompleter class.
 - * This client-side component should be instantiated from a Prado component.
 - * Usage: <t>new Prado.AutoCompleter('textboxID', 'updateDivID', {callbackID : '...'});
 + * TAutoComplete control.
   */
 -Prado.AutoCompleter.prototype = Object.extend(new Autocompleter.Base(),
 +Prado.WebUI.TAutoComplete = Class.extend(Autocompleter.Base, Prado.WebUI.TActiveTextBox.prototype);
 +Prado.WebUI.TAutoComplete = Class.extend(Prado.WebUI.TAutoComplete,
  {
 -	/**
 -	 * This component is initialized by
 -	 * <code>new Prado.AutoCompleter(...)</code>
 -	 * @param string the ID of the textbox element to observe
 -	 * @param string the ID of the div to display the auto-complete options
 -	 * @param array a hash of options, e.g. auto-completion token separator.
 -	 */
 -	initialize : function(element, update, options)
 +	initialize : function(options)
  	{
 -		this.baseInitialize(element, update, options);
 +		this.options = options;
 +		this.baseInitialize(options.ID, options.ResultPanel, options);
 +		Object.extend(this.options,
 +		{
 +			onSuccess : this.onComplete.bind(this)
 +		});
 +
 +		if(options.AutoPostBack)
 +			this.onInit(options);
  	},
 -	/**
 -	 * The callback function, i.e., function called on successful AJAX return.
 -	 * Calls update choices in the Autocompleter.
 -	 * @param string new auto-complete options for display
 -	 */
 -	onUpdateReturn : function(result)
 +	doCallback : function(event, options)
  	{
 -		if(isString(result) && result.length > 0)
 -			this.updateChoices(result);
 +		if(!this.active)
 +		{
 +			request = new Prado.CallbackRequest(options.EventTarget, options);
 +			request.dispatch();
 +			Event.stop(event);
 +		}
 +	},
 +
 +	 //Overrides parent implementation, fires onchange event.
 +	onClick: function(event)
 +	{
 +	    var element = Event.findElement(event, 'LI');
 +	    this.index = element.autocompleteIndex;
 +	    this.selectEntry();
 +	    this.hide();
 +		Event.fireEvent(this.element, "change");
  	},
 -	/**
 -	 * Requesting new choices using Prado's client-side callback scheme.
 -	 */
  	getUpdatedChoices : function()
  	{
 -		Prado.Callback(this.element.id, this.getToken(), this.onUpdateReturn.bind(this));
 +		options = new Array(this.getToken(),"__TAutoComplete_onSuggest__");
 +		Prado.Callback(this.options.EventTarget, options, null, this.options);
 +	},
 +
 +  	onComplete : function(request, boundary)
 +  	{
 +  		result = Prado.Element.extractContent(request.transport.responseText, boundary);
 +  		if(typeof(result) == "string" && result.length > 0)
 +			this.updateChoices(result);
  	}
  });
  /**
 - * Prado TActivePanel client javascript. Usage
 - * <code>
 - * Prado.ActivePanel.register("id", options);
 - * Prado.ActivePanel.update("id", "hello");
 - * </code>
 + * Time Triggered Callback class.
   */
 -Prado.ActivePanel =
 +Prado.WebUI.TTimeTriggeredCallback = Base.extend(
  {
 -	callbacks : {},
 +	count : 0,
 +	timeout : 0,
 +
 +	constructor : function(options)
 +	{
 +		this.options = Object.extend(
 +		{
 +			Interval : 1,
 +			DecayRate : 0
 +		}, options || {})
 +
 +		this.onComplete = this.options.onComplete;
 +		Prado.WebUI.TTimeTriggeredCallback.register(this);
 +	},
 +
 +	startTimer : function()
 +	{
 +		this.options.onComplete = this.onRequestComplete.bind(this);
 +		setTimeout(this.onTimerEvent.bind(this), 200);
 +	},
 +
 +	stopTimer : function()
 +	{
 +		(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
 +		this.options.onComplete = undefined;
 +		clearTimeout(this.timer);
 +		this.timer = undefined;
 +		this.count = 0;
 +	},
 +
 +	onTimerEvent : function()
 +	{
 +		this.options.params = this.timeout/1000;
 +		request = new Prado.CallbackRequest(this.options.ID, this.options);
 +		request.dispatch();
 +	},
 -	register : function(id, options)
 +	onRequestComplete : function()
  	{
 -		Prado.ActivePanel.callbacks[id] = options;
 +		(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
 +		this.timer = setTimeout(this.onTimerEvent.bind(this), this.getNewTimeout())
  	},
 -	update : function(id, param)
 +	getNewTimeout : function()
  	{
 -		var request = new Prado.ActivePanel.Request(id,
 -						Prado.ActivePanel.callbacks[id]);
 -		request.callback(param);
 +		switch(this.options.DecayType)
 +		{
 +			case 'Exponential':
 +				t = (Math.exp(this.options.DecayRate*this.count*this.options.Interval))-1;
 +			break;
 +			case 'Linear':
 +				t = this.options.DecayRate*this.count*this.options.Interval;
 +			break;
 +			case 'Quadratic':
 +				t = this.options.DecayRate*this.count*this.count*this.options.Interval;
 +			break;
 +			case 'Cubic':
 +				t = this.options.DecayRate*this.count*this.count*this.count*this.options.Interval;
 +			break;
 +			default : t = 0;
 +		}
 +		this.timeout = (t + this.options.Interval)*1000;
 +		this.count++;
 +		return parseInt(this.timeout);
  	}
 -}
 +},
 +//class methods
 +{
 +	timers : {},
 +
 +	register : function(timer)
 +	{
 +		this.timers[timer.options.ID] = timer;
 +	},
 +
 +	start : function(id)
 +	{
 +		if(this.timers[id])
 +			this.timers[id].startTimer();
 +	},
 +
 +	stop : function(id)
 +	{
 +		if(this.timers[id])
 +			this.timers[id].stopTimer();
 +	}
 +});
 +
 +Prado.WebUI.ActiveListControl = Base.extend(
 +{
 +	constructor : function(options)
 +	{
 +		this.element = $(options.ID);
 +		this.options = options;
 +		Event.observe(this.element, "change", this.doCallback.bind(this));
 +	},
 +
 +	doCallback : function(event)
 +	{
 +		request = new Prado.CallbackRequest(this.options.EventTarget, this.options);
 +		request.dispatch();
 +		Event.stop(event);
 +	}
 +});
 +
 +Prado.WebUI.TActiveDropDownList = Prado.WebUI.ActiveListControl;
 +Prado.WebUI.TActiveListBox = Prado.WebUI.ActiveListControl;
  /**
 - * Client-script for TActivePanel. Uses Callback to notify the server
 - * for updates, if update option is set, the innerHTML of the update ID
 - * is set to the returned output.
 + * Observe event of a particular control to trigger a callback request.
   */
 -Prado.ActivePanel.Request = Class.create();
 -Prado.ActivePanel.Request.prototype =
 +Prado.WebUI.TEventTriggeredCallback = Base.extend(
 +{
 +	constructor : function(options)
 +	{
 +		this.options = options;
 +		element = $(options['ControlID']);
 +		if(element)
 +			Event.observe(element, this.getEventName(element), this.doCallback.bind(this));
 +	},
 +
 +	getEventName : function(element)
 +	{
 +		name = this.options.EventName;
 +   		if(typeof(name) == "undefined" && element.type)
 +		{
 +      		switch (element.type.toLowerCase())
 +			{
 +          		case 'password':
 +		        case 'text':
 +		        case 'textarea':
 +		        case 'select-one':
 +		        case 'select-multiple':
 +          			return 'change';
 +      		}
 +		}
 +		return typeof(name) == "undefined"  || name == "undefined" ? 'click' : name;
 +    },
 +
 +	doCallback : function(event)
 +	{
 +		request = new Prado.CallbackRequest(this.options.ID, this.options);
 +		request.dispatch();
 +		if(this.options.StopEvent == true)
 +			Event.stop(event);
 +	}
 +});
 +
 +/**
 + * Observe changes to a property of a particular control to trigger a callback.
 + */
 +Prado.WebUI.TValueTriggeredCallback = Base.extend(
 +{
 +	count : 1,
 +
 +	observing : true,
 +
 +	constructor : function(options)
 +	{
 +		this.options = options;
 +		this.options.PropertyName = this.options.PropertyName || 'value';
 +		element = $(options['ControlID']);
 +		this.value = element ? element[this.options.PropertyName] : undefined;
 +		Prado.WebUI.TValueTriggeredCallback.register(this);
 +		this.startObserving();
 +	},
 +
 +	stopObserving : function()
 +	{
 +		clearTimeout(this.timer);
 +		this.observing = false;
 +	},
 +
 +	startObserving : function()
 +	{
 +		this.timer = setTimeout(this.checkChanges.bind(this), this.options.Interval*1000);
 +	},
 +
 +	checkChanges : function()
 +	{
 +		element = $(this.options.ControlID);
 +		if(element)
 +		{
 +			value = element[this.options.PropertyName];
 +			if(this.value != value)
 +			{
 +				this.doCallback(this.value, value);
 +				this.value = value;
 +				this.count=1;
 +			}
 +			else
 +				this.count = this.count + this.options.Decay;
 +			if(this.observing)
 +				this.time = setTimeout(this.checkChanges.bind(this),
 +					parseInt(this.options.Interval*1000*this.count));
 +		}
 +	},
 +
 +	doCallback : function(oldValue, newValue)
 +	{
 +		request = new Prado.CallbackRequest(this.options.ID, this.options);
 +		param = {'OldValue' : oldValue, 'NewValue' : newValue};
 +		request.setParameter(param);
 +		request.dispatch();
 +	}
 +},
 +//class methods
  {
 -	initialize : function(element, options)
 +	timers : {},
 +
 +	register : function(timer)
  	{
 -		this.element = element;
 -		this.setOptions(options);
 +		this.timers[timer.options.ID] = timer;
 +	},
 +
 +	stop : function(id)
 +	{
 +		if(this.timers[id])
 +			this.timers[id].stopObserving();
 +	}
 +});
 + + +Prado.WebUI.TInPlaceTextBox = Base.extend(
 +{
 +	isSaving : false,
 +	isEditing : false,
 +	editField : null,
 +
 +	constructor : function(options)
 +	{
 +		this.options = Object.extend(
 +		{
 +			LoadTextFromSource : false,
 +			TextMode : 'SingleLine'
 +
 +		}, options || {});
 +		this.element = $(this.options.ID);
 +
 +		this.initializeListeners();
 +	},
 +
 +	/**
 +	 * Initialize the listeners.
 +	 */
 +	initializeListeners : function()
 +	{
 +		this.onclickListener = this.enterEditMode.bindAsEventListener(this);
 +	    Event.observe(this.element, 'click', this.onclickListener);
 +	    if (this.options.ExternalControl)
 +			Event.observe($(this.options.ExternalControl), 'click', this.onclickListener);
 +	},
 +
 +	/**
 +	 * Changes the panel to an editable input.
 +	 * @param {Event} evt event source
 +	 */
 +	enterEditMode :  function(evt)
 +	{
 +	    if (this.isSaving) return;
 +	    if (this.isEditing) return;
 +	    this.isEditing = true;
 +		this.onEnterEditMode();
 +		this.createEditorInput();
 +		this.showTextBox();
 +		this.editField.disabled = false;
 +		if(this.options.LoadTextOnEdit)
 +			this.loadExternalText();
 +		Prado.Element.focus(this.editField);
 +		if (evt)
 +			Event.stop(evt);
 +    	return false;
 +	},
 +
 +	showTextBox : function()
 +	{
 +		Element.hide(this.element);
 +		Element.show(this.editField);
 +	},
 +
 +	showLabel : function()
 +	{
 +		Element.show(this.element);
 +		Element.hide(this.editField);
  	},
  	/**
 -	 * Set some options.
 +	 * Create the edit input field.
  	 */
 -	setOptions : function(options)
 +	createEditorInput : function()
 +	{
 +		if(this.editField == null)
 +			this.createTextBox();
 +
 +		this.editField.value = this.getText();
 +	},
 +
 +	loadExternalText : function()
  	{
 -		this.options =
 +		this.editField.disabled = true;
 +		this.onLoadingText();
 +		options = new Array('__InlineEditor_loadExternalText__', this.getText());
 +		request = new Prado.CallbackRequest(this.options.EventTarget, this.options);
 +		request.setCausesValidation(false);
 +		request.setParameter(options);
 +		request.options.onSuccess = this.onloadExternalTextSuccess.bind(this);
 +		request.options.onFailure = this.onloadExternalTextFailure.bind(this);
 +		request.dispatch();
 +	},
 +
 +	/**
 +	 * Create a new input textbox or textarea
 +	 */
 +	createTextBox : function()
 +	{
 +		cssClass= this.element.className || '';
 +		inputName = this.options.EventTarget;
 +		options = {'className' : cssClass, name : inputName, id : this.options.TextBoxID};
 +		if(this.options.TextMode == 'SingleLine')
 +		{
 +			if(this.options.MaxLength > 0)
 +				options['maxlength'] = this.options.MaxLength;
 +			this.editField = INPUT(options);
 +		}
 +		else
 +		{
 +			if(this.options.Rows > 0)
 +				options['rows'] = this.options.Rows;
 +			if(this.options.Columns > 0)
 +				options['cols'] = this.options.Columns;
 +			if(this.options.Wrap)
 +				options['wrap'] = 'off';
 +			this.editField = TEXTAREA(options);
 +		}
 +
 +		this.editField.style.display="none";
 +		this.element.parentNode.insertBefore(this.editField,this.element)
 +
 +		//handle return key within single line textbox
 +		if(this.options.TextMode == 'SingleLine')
  		{
 -			onSuccess : this.onSuccess.bind(this)
 +			Event.observe(this.editField, "keydown", function(e)
 +			{
 +				 if(Event.keyCode(e) == Event.KEY_RETURN)
 +		        {
 +					var target = Event.element(e);
 +					if(target)
 +					{
 +						Event.fireEvent(target, "blur");
 +						Event.stop(e);
 +					}
 +				}
 +			});
  		}
 -		Object.extend(this.options, options || {});
 +
 +		Event.observe(this.editField, "blur", this.onTextBoxBlur.bind(this));
  	},
  	/**
 -	 * Make the callback request
 +	 * @return {String} panel inner html text.
  	 */
 -	callback : function(param)
 +	getText: function()
  	{
 -		this.options.params = [param];
 -		new Prado.AJAX.Callback(this.element, this.options);
 -	},
 +    	return this.element.innerHTML;
 +  	},
  	/**
 -	 * Callback onSuccess handler, update the element innerHTML if necessary
 +	 * Edit mode entered, calls optional event handlers.
  	 */
 -	onSuccess : function(result, output)
 +	onEnterEditMode : function()
 +	{
 +		if(typeof(this.options.onEnterEditMode) == "function")
 +			this.options.onEnterEditMode(this,null);
 +	},
 +
 +	onTextBoxBlur : function(e)
  	{
 -		if(this.options.update)
 +		text = this.element.innerHTML;
 +		if(this.options.AutoPostBack && text != this.editField.value)
 +			this.onTextChanged(text);
 +		else
  		{
 -			if (!this.options.evalScripts)
 -				output = output.stripScripts();
 -			Element.update(this.options.update, output);
 +			this.element.innerHTML = this.editField.value;
 +			this.isEditing = false;
 +			if(this.options.AutoHide)
 +				this.showLabel();
  		}
 -	}
 -}
 +	},
 -/**
 - * Drop container to accept draggable component drops.
 - */
 -Prado.DropContainer = Class.create();
 -Prado.DropContainer.prototype = Object.extend(new Prado.ActivePanel.Request(),
 -{
 -	initialize : function(element, options)
 +	/**
 +	 * When the text input value has changed.
 +	 * @param {String} original text
 +	 */
 +	onTextChanged : function(text)
  	{
 -		this.element = element;
 -		this.setOptions(options);
 -		Object.extend(this.options,
 +		request = new Prado.CallbackRequest(this.options.EventTarget, this.options);
 +		request.setParameter(text);
 +		request.options.onSuccess = this.onTextChangedSuccess.bind(this);
 +		request.options.onFailure = this.onTextChangedFailure.bind(this);
 +		if(request.dispatch())
  		{
 -			onDrop : this.onDrop.bind(this),
 -			evalScripts : true,
 -			onSuccess : options.onSuccess || this.onSuccess.bind(this)
 -		});
 -		Droppables.add(element, this.options);
 +			this.isSaving = true;
 +			this.editField.disabled = true;
 +		}
  	},
 -	onDrop : function(draggable, droppable)
 +	/**
 +	 * When loading external text.
 +	 */
 +	onLoadingText : function()
  	{
 -		this.callback(draggable.id)
 -	}
 -});
 +		//Logger.info("on loading text");
 +	},
 -Prado.ActiveImageButton = Class.create();
 -Prado.ActiveImageButton.prototype = 
 -{
 -	initialize : function(element, options)
 +	onloadExternalTextSuccess : function(request, parameter)
  	{
 -		this.element = $(element);
 -		this.options = options;
 -		Event.observe(this.element, "click", this.click.bind(this));
 +		this.isEditing = true;
 +		this.editField.disabled = false;
 +		this.editField.value = this.getText();
 +		Prado.Element.focus(this.editField);
  	},
 -	click : function(e)
 +	onloadExternalTextFailure : function(request, parameter)
  	{
 -		var el = $('{$this->ClientID}');
 -		var imagePos = Position.cumulativeOffset(this.element);
 -		var clickedPos = [e.clientX, e.clientY];
 -		var param = (clickedPos[0]-imagePos[0]+1)+","+(clickedPos[1]-imagePos[1]+1);
 -		Prado.Callback(this.element, param, null, this.options);
 -		Event.stop(e);
 -	}
 -}
 +		this.isSaving = false;
 +		this.isEditing = false;
 +		this.showLabel();
 +	},
 +	/**
 +	 * Text change successfully.
 +	 * @param {Object} sender
 +	 * @param {Object} parameter
 +	 */
 +	onTextChangedSuccess : function(sender, parameter)
 +	{
 +		this.isSaving = false;
 +		this.isEditing = false;
 +		if(this.options.AutoHide)
 +			this.showLabel();
 +		this.element.innerHTML = parameter == null ? this.editField.value : parameter;
 +		this.editField.disabled = false;
 +	},
 - +	onTextChangedFailure : function(sender, parameter)
 +	{
 +		this.editField.disabled = false;
 +		this.isSaving = false;
 +		this.isEditing = false;
 +	}
 +}); diff --git a/framework/Web/Javascripts/js/debug/prado.js b/framework/Web/Javascripts/js/debug/prado.js index 9a610de9..736a7f7e 100644 --- a/framework/Web/Javascripts/js/debug/prado.js +++ b/framework/Web/Javascripts/js/debug/prado.js @@ -131,10 +131,10 @@ PeriodicalExecuter.prototype = {  /**
   * Similar to bindAsEventLister, but takes additional arguments.
   */
 -Function.prototype.bindEvent = function() 
 +Function.prototype.bindEvent = function()
  {
  	var __method = this, args = $A(arguments), object = args.shift();
 -	return function(event) 
 +	return function(event)
  	{
  		return __method.apply(object, [event || window.event].concat(args));
  	}
 @@ -152,10 +152,315 @@ Class.extend = function(base, definition)  {
  		var component = Class.create();
  		Object.extend(component.prototype, base.prototype);
 -		if(definition) 
 +		if(definition)
  			Object.extend(component.prototype, definition);
  		return component;
 -} +}
 +
 +/*
 +	Base, version 1.0.2
 +	Copyright 2006, Dean Edwards
 +	License: http://creativecommons.org/licenses/LGPL/2.1/
 +*/
 +
 +var Base = function() {
 +	if (arguments.length) {
 +		if (this == window) { // cast an object to this class
 +			Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
 +		} else {
 +			this.extend(arguments[0]);
 +		}
 +	}
 +};
 +
 +Base.version = "1.0.2";
 +
 +Base.prototype = {
 +	extend: function(source, value) {
 +		var extend = Base.prototype.extend;
 +		if (arguments.length == 2) {
 +			var ancestor = this[source];
 +			// overriding?
 +			if ((ancestor instanceof Function) && (value instanceof Function) &&
 +				ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
 +				var method = value;
 +			//	var _prototype = this.constructor.prototype;
 +			//	var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
 +				value = function() {
 +					var previous = this.base;
 +				//	this.base = fromPrototype ? _prototype[source] : ancestor;
 +					this.base = ancestor;
 +					var returnValue = method.apply(this, arguments);
 +					this.base = previous;
 +					return returnValue;
 +				};
 +				// point to the underlying method
 +				value.valueOf = function() {
 +					return method;
 +				};
 +				value.toString = function() {
 +					return String(method);
 +				};
 +			}
 +			return this[source] = value;
 +		} else if (source) {
 +			var _prototype = {toSource: null};
 +			// do the "toString" and other methods manually
 +			var _protected = ["toString", "valueOf"];
 +			// if we are prototyping then include the constructor
 +			if (Base._prototyping) _protected[2] = "constructor";
 +			for (var i = 0; (name = _protected[i]); i++) {
 +				if (source[name] != _prototype[name]) {
 +					extend.call(this, name, source[name]);
 +				}
 +			}
 +			// copy each of the source object's properties to this object
 +			for (var name in source) {
 +				if (!_prototype[name]) {
 +					extend.call(this, name, source[name]);
 +				}
 +			}
 +		}
 +		return this;
 +	},
 +
 +	base: function() {
 +		// call this method from any other method to invoke that method's ancestor
 +	}
 +};
 +
 +Base.extend = function(_instance, _static) {
 +	var extend = Base.prototype.extend;
 +	if (!_instance) _instance = {};
 +	// build the prototype
 +	Base._prototyping = true;
 +	var _prototype = new this;
 +	extend.call(_prototype, _instance);
 +	var constructor = _prototype.constructor;
 +	_prototype.constructor = this;
 +	delete Base._prototyping;
 +	// create the wrapper for the constructor function
 +	var klass = function() {
 +		if (!Base._prototyping) constructor.apply(this, arguments);
 +		this.constructor = klass;
 +	};
 +	klass.prototype = _prototype;
 +	// build the class interface
 +	klass.extend = this.extend;
 +	klass.implement = this.implement;
 +	klass.toString = function() {
 +		return String(constructor);
 +	};
 +	extend.call(klass, _static);
 +	// single instance
 +	var object = constructor ? klass : _prototype;
 +	// class initialisation
 +	if (object.init instanceof Function) object.init();
 +	return object;
 +};
 +
 +Base.implement = function(_interface) {
 +	if (_interface instanceof Function) _interface = _interface.prototype;
 +	this.prototype.extend(_interface);
 +};
 +
 +/*
 + * Signals and Slots for Prototype: Easy custom javascript events
 + * http://tetlaw.id.au/view/blog/signals-and-slots-for-prototype-easy-custom-javascript-events
 + * Andrew Tetlaw
 + * Version 1.2 (2006-06-19)
 + *
 + * http://creativecommons.org/licenses/by-sa/2.5/
 + *
 +Signal = {
 +	throwErrors : true,
 +	MT : function(){ return true },
 +	connect : function(obj1, func1, obj2, func2, options) {
 +		var options = Object.extend({
 +			connectOnce : false,
 +			before : false,
 +			mutate : function() {return arguments;}
 +		}, options || {});
 +		if(typeof func1 != 'string' || typeof func2 != 'string') return;
 +
 +		var sigObj = obj1 || window;
 +		var slotObj = obj2 || window;
 +		var signame = func1+'__signal_';
 +		var slotsname = func1+'__slots_';
 +		if(!sigObj[signame]) {
 +			// having the slotFunc in a var and setting it by using an anonymous function in this way
 +			// is apparently a good way to prevent memory leaks in IE if the objects are DOM nodes.
 +			var slotFunc = function() {
 +				var args = [];
 +				for(var x = 0; x < arguments.length; x++){
 +					args.push(arguments[x]);
 +				}
 +				args = options.mutate.apply(null,args)
 +				var result;
 +				if(!options.before) result = sigObj[signame].apply(sigObj,arguments); //default: call sign before slot
 +				sigObj[slotsname].each(function(slot){
 +					try {
 +						if(slot && slot[0]) { // testing for null, a disconnect may have nulled this slot
 +							slot[0][slot[1]].apply(slot[0],args); //[0] = obj, [1] = func name
 +						}
 +					} catch(e) {
 +						if(Signal.throwErrors) throw e;
 +					}
 +				});
 +				if(options.before) result = sigObj[signame].apply(sigObj,arguments); //call slot before sig
 +				return result; //return sig result
 +			};
 +			(function() {
 +				sigObj[slotsname] = $A([]);
 +				sigObj[signame] = sigObj[func1] || Signal.MT;
 +				sigObj[func1] = slotFunc;
 +			})();
 +		}
 +		var con = (sigObj[slotsname].length > 0) ?
 +					(options.connectOnce ? !sigObj[slotsname].any(function(slot) { return (slot[0] == slotObj && slot[1] == func2) }) : true) :
 +					true;
 +		if(con) {
 +			sigObj[slotsname].push([slotObj,func2]);
 +		}
 +	},
 +	connectOnce : function(obj1, func1, obj2, func2, options) {
 +		Signal.connect(obj1, func1, obj2, func2, Object.extend(options || {}, {connectOnce : true}))
 +	},
 +	disconnect : function(obj1, func1, obj2, func2, options) {
 +		var options = Object.extend({
 +			disconnectAll : false
 +		}, options || {});
 +		if(typeof func1 != 'string' || typeof func2 != 'string') return;
 +
 +		var sigObj = obj1 || window;
 +		var slotObj = obj2 || window;
 +		var signame = func1+'__signal_';
 +		var slotsname = func1+'__slots_';
 +
 +		// I null them in this way so that any currectly active signal will read a null slot,
 +		// otherwise the slot will be applied even though it's been disconnected
 +		if(sigObj[slotsname]) {
 +			if(options.disconnectAll) {
 +				sigObj[slotsname] = sigObj[slotsname].collect(function(slot) {
 +					if(slot[0] == slotObj && slot[1] == func2) {
 +						slot[0] = null;
 +						return null;
 +					} else {
 +						return slot;
 +					}
 +				}).compact();
 +			} else {
 +				var idx = -1;
 +				sigObj[slotsname] = sigObj[slotsname].collect(function(slot, index) {
 +					if(slot[0] == slotObj && slot[1] == func2 && idx < 0) {  //disconnect first match
 +						idx = index;
 +						slot[0] = null;
 +						return null;
 +					} else {
 +						return slot;
 +					}
 +				}).compact();
 +			}
 +		}
 +	},
 +	disconnectAll : function(obj1, func1, obj2, func2, options) {
 +		Signal.disconnect(obj1, func1, obj2, func2, Object.extend(options || {}, {disconnectAll : true}))
 +	}
 +}
 +*/
 +
 +/*
 + Tests
 +
 +//   1. Simple Test 1 "hello Fred" should trigger "Fred is a stupid head"
 +
 +
 +      sayHello = function(n) {
 +      	alert("Hello! " + n);
 +      }
 +      moron = function(n) {
 +      	alert(n + " is a stupid head");
 +      }
 +      Signal.connect(null,'sayHello',null,'moron');
 +
 +      onclick="sayHello('Fred')"
 +
 +
 +//   2. Simple Test 2 repeated insults about Fred
 +
 +
 +      Signal.connect(null,'sayHello2',null,'moron2');
 +      Signal.connect(null,'sayHello2',null,'moron2');
 +      Signal.connect(null,'sayHello2',null,'moron2');
 +
 +
 +//   3. Simple Test 3 multiple insults about Fred
 +
 +
 +      Signal.connect(null,'sayHello3',null,'moron3');
 +      Signal.connect(null,'sayHello3',null,'bonehead3');
 +      Signal.connect(null,'sayHello3',null,'idiot3');
 +
 +
 +//   4. Simple Test 4 3 insults about Fred first - 3 then none
 +
 +
 +      Signal.connect(null,'sayHello4',null,'moron4');
 +      Signal.connect(null,'sayHello4',null,'moron4');
 +      Signal.connect(null,'sayHello4',null,'moron4');
 +      Signal.disconnect(null,'sayHello4',null,'moron4');
 +      Signal.disconnect(null,'sayHello4',null,'moron4');
 +      Signal.disconnect(null,'sayHello4',null,'moron4');
 +
 +
 +//   5. Simple Test 5 connect 3 insults about Fred first - only one, then none
 +
 +
 +      Signal.connect(null,'sayHello5',null,'moron5');
 +      Signal.connect(null,'sayHello5',null,'moron5');
 +      Signal.connect(null,'sayHello5',null,'moron5');
 +      Signal.disconnectAll(null,'sayHello5',null,'moron5');
 +
 +
 +//   6. Simple Test 6 connect 3 insults but only one comes out
 +
 +
 +      Signal.connectOnce(null,'sayHello6',null,'moron6');
 +      Signal.connectOnce(null,'sayHello6',null,'moron6');
 +      Signal.connectOnce(null,'sayHello6',null,'moron6');
 +
 +
 +//   7. Simple Test 7 connect via objects
 +
 +
 +      var o = {};
 +      o.sayHello = function(n) {
 +      	alert("Hello! " + n + " (from object o)");
 +      }
 +      var m = {};
 +      m.moron = function(n) {
 +      	alert(n + " is a stupid head (from object m)");
 +      }
 +
 +      Signal.connect(o,'sayHello',m,'moron');
 +
 +      onclick="o.sayHello('Fred')"
 +
 +
 +//   8. Simple Test 8 connect but the insult comes first using {before:true}
 +
 +
 +      Signal.connect(null,'sayHello8',null,'moron8', {before:true});
 +
 +
 +//   9. Simple Test 9 connect but the insult is mutated
 +
 +
 +      Signal.connect(null,'sayHello9',null,'moron9', {mutate:function() { return ['smelly ' + arguments[0]] }});
 +
 +
 +*/
 + */  Object.extend(String.prototype, {    gsub: function(pattern, replacement) { @@ -726,35 +1031,45 @@ var Hash = {      for (var key in this) {        var value = this[key];        if (typeof value == 'function') continue; -       +        var pair = [key, value];        pair.key = key;        pair.value = value;        iterator(pair);      }    }, -   +    keys: function() {      return this.pluck('key');    }, -   +    values: function() {      return this.pluck('value');    }, -   +    merge: function(hash) {      return $H(hash).inject($H(this), function(mergedHash, pair) {        mergedHash[pair.key] = pair.value;        return mergedHash;      });    }, -   +    toQueryString: function() { -    return this.map(function(pair) { -      return pair.map(encodeURIComponent).join('='); +    return this.map(function(pair) +	{ +	  //special case for PHP, array post data. +	  if(typeof(pair[1]) == 'object' || typeof(pair[1]) == 'array') +	  { +	  	return $A(pair[1]).collect(function(value) +		{ +			return encodeURIComponent(pair[0])+'='+encodeURIComponent(value);
 +		}).join('&');
 +	  } +	  else + 	     return pair.map(encodeURIComponent).join('=');      }).join('&');    }, -   +    inspect: function() {      return '#<Hash:{' + this.map(function(pair) {        return pair.map(Object.inspect).join(': '); @@ -1209,17 +1524,17 @@ var Field = {    focus: function(element) {      $(element).focus();    }, -   +    present: function() {      for (var i = 0; i < arguments.length; i++)        if ($(arguments[i]).value == '') return false;      return true;    }, -   +    select: function(element) {      $(element).select();    }, -    +    activate: function(element) {      element = $(element);      element.focus(); @@ -1234,16 +1549,16 @@ var Form = {    serialize: function(form) {      var elements = Form.getElements($(form));      var queryComponents = new Array(); -     +      for (var i = 0; i < elements.length; i++) {        var queryComponent = Form.Element.serialize(elements[i]);        if (queryComponent)          queryComponents.push(queryComponent);      } -     +      return queryComponents.join('&');    }, -   +    getElements: function(form) {      form = $(form);      var elements = new Array(); @@ -1255,19 +1570,19 @@ var Form = {      }      return elements;    }, -   +    getInputs: function(form, typeName, name) {      form = $(form);      var inputs = form.getElementsByTagName('input'); -     +      if (!typeName && !name)        return inputs; -       +      var matchingInputs = new Array();      for (var i = 0; i < inputs.length; i++) {        var input = inputs[i];        if ((typeName && input.type != typeName) || -          (name && input.name != name))  +          (name && input.name != name))          continue;        matchingInputs.push(input);      } @@ -1313,25 +1628,25 @@ Form.Element = {      element = $(element);      var method = element.tagName.toLowerCase();      var parameter = Form.Element.Serializers[method](element); -     +      if (parameter) {        var key = encodeURIComponent(parameter[0]);        if (key.length == 0) return; -       +        if (parameter[1].constructor != Array)          parameter[1] = [parameter[1]]; -       +        return parameter[1].map(function(value) {          return key + '=' + encodeURIComponent(value);        }).join('&');      }    }, -   +    getValue: function(element) {      element = $(element);      var method = element.tagName.toLowerCase();      var parameter = Form.Element.Serializers[method](element); -     +      if (parameter)        return parameter[1];    } @@ -1339,13 +1654,15 @@ Form.Element = {  Form.Element.Serializers = {    input: function(element) { +  	if(typeof(element.type) == "undefined") +		return false;      switch (element.type.toLowerCase()) {        case 'submit':        case 'hidden':        case 'password':        case 'text':          return Form.Element.Serializers.textarea(element); -      case 'checkbox':   +      case 'checkbox':        case 'radio':          return Form.Element.Serializers.inputSelector(element);      } @@ -1360,12 +1677,12 @@ Form.Element.Serializers = {    textarea: function(element) {      return [element.name, element.value];    }, -   +    select: function(element) { -    return Form.Element.Serializers[element.type == 'select-one' ?  +    return Form.Element.Serializers[element.type == 'select-one' ?        'selectOne' : 'selectMany'](element);    }, -   +    selectOne: function(element) {      var value = '', opt, index = element.selectedIndex;      if (index >= 0) { @@ -1374,7 +1691,7 @@ Form.Element.Serializers = {      }      return [element.name, value];    }, -   +    selectMany: function(element) {      var value = [];      for (var i = 0; i < element.length; i++) { @@ -1398,15 +1715,15 @@ Abstract.TimedObserver.prototype = {      this.frequency = frequency;      this.element   = $(element);      this.callback  = callback; -     +      this.lastValue = this.getValue();      this.registerCallback();    }, -   +    registerCallback: function() {      setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);    }, -   +    onTimerEvent: function() {      var value = this.getValue();      if (this.lastValue != value) { @@ -1437,14 +1754,14 @@ Abstract.EventObserver.prototype = {    initialize: function(element, callback) {      this.element  = $(element);      this.callback = callback; -     +      this.lastValue = this.getValue();      if (this.element.tagName.toLowerCase() == 'form')        this.registerFormCallbacks();      else        this.registerCallback(this.element);    }, -   +    onElementEvent: function() {      var value = this.getValue();      if (this.lastValue != value) { @@ -1452,17 +1769,17 @@ Abstract.EventObserver.prototype = {        this.lastValue = value;      }    }, -   +    registerFormCallbacks: function() {      var elements = Form.getElements(this.element);      for (var i = 0; i < elements.length; i++)        this.registerCallback(elements[i]);    }, -   +    registerCallback: function(element) {      if (element.type) {        switch (element.type.toLowerCase()) { -        case 'checkbox':   +        case 'checkbox':          case 'radio':            Event.observe(element, 'click', this.onElementEvent.bind(this));            break; @@ -1474,7 +1791,7 @@ Abstract.EventObserver.prototype = {            Event.observe(element, 'change', this.onElementEvent.bind(this));            break;        } -    }     +    }    }  } @@ -2600,7 +2917,7 @@ Prado.doPostBack = function(formID, eventTarget, eventParameter, performValidati  }
  */ -Prado.Element = 
 +Prado.Element =
  {
  	/**
  	 * Set the value of a particular element.
 @@ -2614,29 +2931,41 @@ Prado.Element =  			el.value = value;
  	},
 -	select : function(element, method, value)
 +	select : function(element, method, value, total)
  	{
  		var el = $(element);
 -		var isList = element.indexOf('[]') > -1;
 -		if(!el && !isList) return;
 -		method = isList ? 'check'+method : el.tagName.toLowerCase()+method;
  		var selection = Prado.Element.Selection;
 -		if(isFunction(selection[method])) 
 -			selection[method](isList ? element : el,value);
 +		if(typeof(selection[method]) == "function")
 +		{
 +			control = selection.isSelectable(el) ? [el] : selection.getListElements(element,total);
 +			selection[method](control, value);
 +		}
  	},
  	click : function(element)
  	{
  		var el = $(element);
 -		if(el) 
 +		if(el)
  			Event.fireEvent(el,'click');
  	},
 -	
 +
  	setAttribute : function(element, attribute, value)
  	{
  		var el = $(element);
 -		if(attribute == "disabled" && value==false)
 +		if((attribute == "disabled" || attribute == "multiple") && value==false)
  			el.removeAttribute(attribute);
 +		else if(attribute.match(/^on/i)) //event methods
 +		{
 +			try
 +			{
 +				eval("(func = function(event){"+value+"})");
 +				el[attribute] = func;
 +			}
 +			catch(e)
 +			{
 +				throw "Error in evaluating '"+value+"' for attribute "+attribute+" for element "+element.id;
 +			}
 +		}
  		else
  			el.setAttribute(attribute, value);
  	},
 @@ -2646,10 +2975,9 @@ Prado.Element =  		var el = $(element);
  		if(el && el.tagName.toLowerCase() == "select")
  		{
 -			while(el.length > 0)
 -				el.remove(0);
 +			el.options.length = options.length;
  			for(var i = 0; i<options.length; i++)
 -				el.options[el.options.length] = new Option(options[i][0],options[i][1]);
 +				el.options[i] = new Option(options[i][0],options[i][1]);
  		}
  	},
 @@ -2663,76 +2991,191 @@ Prado.Element =  		if(typeof(obj) != "undefined" && typeof(obj.focus) != "undefined")
  			setTimeout(function(){ obj.focus(); }, 100);
  		return false;
 +	},
 +
 +	replace : function(element, method, content, boundary, transport)
 +	{
 +		if(boundary)
 +		{
 +			result = Prado.Element.extractContent(transport.responseText, boundary);
 +			if(result != null)
 +				content = result;
 +		}
 +		if(typeof(element) == "string")
 +		{
 +			if($(element))
 +				method.toFunction().apply(this,[element,content]);
 +		}
 +		else
 +		{
 +			method.toFunction().apply(this,[content]);
 +		}
 +	},
 +
 +	extractContent : function(text, boundary)
 +	{
 +		f = RegExp('(<!--'+boundary+'-->)([\\s\\S\\w\\W]*)(<!--//'+boundary+'-->)',"m");
 +		result = text.match(f);
 +		if(result && result.length >= 2)
 +			return result[2];
 +		else
 +			return null;
 +	},
 +
 +	evaluateScript : function(content)
 +	{
 +		content.evalScripts();
  	}
  }
 -Prado.Element.Selection = 
 +Prado.Element.Selection =
  {
 +	isSelectable : function(el)
 +	{
 +		if(el && el.type)
 +		{
 +			switch(el.type.toLowerCase())
 +			{
 +				case 'checkbox':
 +				case 'radio':
 +				case 'select':
 +				case 'select-multiple':
 +				case 'select-one':
 +				return true;
 +			}
 +		}
 +		return false;
 +	},
 +
  	inputValue : function(el, value)
  	{
 -		switch(el.type.toLowerCase()) 
 +		switch(el.type.toLowerCase())
  		{
 -			case 'checkbox':  
 +			case 'checkbox':
  			case 'radio':
  			return el.checked = value;
  		}
  	},
 -	selectValue : function(el, value)
 +	selectValue : function(elements, value)
  	{
 -		$A(el.options).each(function(option)
 +		elements.each(function(el)
  		{
 -			option.selected = option.value == value;
 -		});
 +			$A(el.options).each(function(option)
 +			{
 +				if(typeof(value) == "boolean")
 +					options.selected = value;
 +				else if(option.value == value)
 +					option.selected = true;
 +			});
 +		})
  	},
 -	selectIndex : function(el, index)
 +	selectValues : function(elements, values)
  	{
 -		if(el.type == 'select-one')
 -			el.selectedIndex = index;
 -		else
 +		selection = this;
 +		values.each(function(value)
 +		{
 +			selection.selectValue(elements,value);
 +		})
 +	},
 +
 +	selectIndex : function(elements, index)
 +	{
 +		elements.each(function(el)
  		{
 -			for(var i = 0; i<el.length; i++)
 +			if(el.type.toLowerCase() == 'select-one')
 +				el.selectedIndex = index;
 +			else
  			{
 -				if(i == index)
 -					el.options[i].selected = true;
 +				for(var i = 0; i<el.length; i++)
 +				{
 +					if(i == index)
 +						el.options[i].selected = true;
 +				}
  			}
 -		}
 +		})
  	},
 -	selectClear : function(el)
 +	selectAll : function(elements)
  	{
 -		el.selectedIndex = -1;
 +		elements.each(function(el)
 +		{
 +			if(el.type.toLowerCase() != 'select-one')
 +			{
 +				$A(el.options).each(function(option)
 +				{
 +					option.selected = true;
 +				})
 +			}
 +		})
  	},
 -	selectAll : function(el)
 +	selectInvert : function(elements)
  	{
 -		$A(el.options).each(function(option)
 +		elements.each(function(el)
  		{
 -			option.selected = true;
 -			Logger.warn(option.value);
 -		});
 +			if(el.type.toLowerCase() != 'select-one')
 +			{
 +				$A(el.options).each(function(option)
 +				{
 +					option.selected = !options.selected;
 +				})
 +			}
 +		})
  	},
 -	selectInvert : function(el)
 +	selectIndices : function(elements, indices)
  	{
 -		$A(el.options).each(function(option)
 +		selection = this;
 +		indices.each(function(index)
  		{
 -			option.selected = !option.selected;
 -		});
 +			selection.selectIndex(elements,index);
 +		})
 +	},
 +
 +	selectClear : function(elements)
 +	{
 +		elements.each(function(el)
 +		{
 +			el.selectedIndex = -1;
 +		})
 +	},
 +
 +	getListElements : function(element, total)
 +	{
 +		elements = new Array();
 +		for(i = 0; i < total; i++)
 +		{
 +			el = $(element+"_c"+i);
 +			if(el)
 +				elements.push(el);
 +		}
 +		return elements;
  	},
 -	checkValue : function(name, value)
 +	checkValue : function(elements, value)
  	{
 -		$A(document.getElementsByName(name)).each(function(el)
 +		elements.each(function(el)
  		{
 -			el.checked = el.value == value
 +			if(typeof(value) == "boolean")
 +				el.checked = value;
 +			else if(el.value == value)
 +				el.checked = true;
  		});
  	},
 -	checkIndex : function(name, index)
 +	checkValues : function(elements, values)
 +	{
 +		selection = this;
 +		values.each(function(value)
 +		{
 +			selection.checkValue(elements, value);
 +		})
 +	},
 +
 +	checkIndex : function(elements, index)
  	{
 -		var elements = $A(document.getElementsByName(name));
  		for(var i = 0; i<elements.length; i++)
  		{
  			if(i == index)
 @@ -2740,29 +3183,63 @@ Prado.Element.Selection =  		}
  	},
 -	checkClear : function(name)
 +	checkIndices : function(elements, indices)
 +	{
 +		selection = this;
 +		indices.each(function(index)
 +		{
 +			selection.checkIndex(elements, index);
 +		})
 +	},
 +
 +	checkClear : function(elements)
  	{
 -		$A(document.getElementsByName(name)).each(function(el)
 +		elements.each(function(el)
  		{
  			el.checked = false;
  		});
  	},
 -	checkAll : function(name)
 +	checkAll : function(elements)
  	{
 -		$A(document.getElementsByName(name)).each(function(el)
 +		elements.each(function(el)
  		{
  			el.checked = true;
 -		});
 +		})
  	},
 -	checkInvert : function(name)
 +
 +	checkInvert : function(elements)
  	{
 -		$A(document.getElementsByName(name)).each(function(el)
 +		elements.each(function(el)
  		{
 -			el.checked = !el.checked;
 -		});
 +			el.checked != el.checked;
 +		})
  	}
 -}; +};
 +
 +
 +Prado.Element.Insert =
 +{
 +	append: function(element, content)
 +	{
 +		new Insertion.Bottom(element, content);
 +	},
 +
 +	prepend: function(element, content)
 +	{
 +		new Insertion.Top(element, content);
 +	},
 +
 +	after: function(element, content)
 +	{
 +		new Insertion.After(element, content);
 +	},
 +
 +	before: function(element, content)
 +	{
 +		new Insertion.Before(element, content);
 +	}
 +}  Prado.WebUI = Class.create();
 @@ -2773,12 +3250,12 @@ Prado.WebUI.PostBackControl.prototype =  	initialize : function(options)
  	{
  		this.element = $(options['ID']);
 -		
 +
  /*		if(options.CausesValidation && typeof(Prado.Validation) != 'undefined')
  		{
  			Prado.Validation.registerTarget(options);
  		}
 -		
 +
  		//TODO: what do the following options do?
  		//options['PostBackUrl']
  		//options['ClientSubmit']
 @@ -2801,7 +3278,7 @@ Prado.WebUI.TButton = Prado.WebUI.createPostBackComponent();  */
  Prado.WebUI.PostBackControl = Class.create();
 -Prado.WebUI.PostBackControl.prototype = 
 +Prado.WebUI.PostBackControl.prototype =
  {
  	_elementOnClick : null, //capture the element's onclick function
 @@ -2811,7 +3288,7 @@ Prado.WebUI.PostBackControl.prototype =  		if(this.onInit)
  			this.onInit(options);
  	},
 -	
 +
  	onInit : function(options)
  	{
  		if(typeof(this.element.onclick)=="function")
 @@ -2819,10 +3296,10 @@ Prado.WebUI.PostBackControl.prototype =  			this._elementOnClick = this.element.onclick;
  			this.element.onclick = null;
  		}
 -		Event.observe(this.element, "click", this.onClick.bindEvent(this,options));		
 +		Event.observe(this.element, "click", this.elementClicked.bindEvent(this,options));
  	},
 -	onClick : function(event, options)
 +	elementClicked : function(event, options)
  	{
  		var src = Event.element(event);
  		var doPostBack = true;
 @@ -2853,7 +3330,7 @@ Prado.WebUI.TBulletedList = Class.extend(Prado.WebUI.PostBackControl);  Prado.WebUI.TImageMap = Class.extend(Prado.WebUI.PostBackControl);
  /**
 - * TImageButton client-side behaviour. With validation, Firefox needs 
 + * TImageButton client-side behaviour. With validation, Firefox needs
   * to capture the x,y point of the clicked image in hidden form fields.
   */
  Prado.WebUI.TImageButton = Class.extend(Prado.WebUI.PostBackControl);
 @@ -2863,7 +3340,7 @@ Object.extend(Prado.WebUI.TImageButton.prototype,  	 * Only add the hidden inputs once.
  	 */
  	hasXYInput : false,
 -	
 +
  	/**
  	 * Override parent onPostBack function, tried to add hidden forms
  	 * inputs to capture x,y clicked point.
 @@ -2877,7 +3354,7 @@ Object.extend(Prado.WebUI.TImageButton.prototype,  		}
  		Prado.PostBack(event, options);
  	},
 -	
 +
  	/**
  	 * Add hidden inputs to capture the x,y point clicked on the image.
  	 * @param event DOM click event.
 @@ -2885,15 +3362,33 @@ Object.extend(Prado.WebUI.TImageButton.prototype,  	 */
  	addXYInput : function(event,options)
  	{
 -		var imagePos = Position.cumulativeOffset(this.element);
 -		var clickedPos = [event.clientX, event.clientY];
 -		var x = clickedPos[0]-imagePos[0]+1;
 -		var y = clickedPos[1]-imagePos[1]+1;
 -		var id = options['EventTarget'];
 -		var x_input = INPUT({type:'hidden',name:id+'_x',value:x});
 -		var y_input = INPUT({type:'hidden',name:id+'_y',value:y});
 -		this.element.parentNode.appendChild(x_input);
 -		this.element.parentNode.appendChild(y_input);		
 +		imagePos = Position.cumulativeOffset(this.element);
 +		clickedPos = [event.clientX, event.clientY];
 +		x = clickedPos[0]-imagePos[0]+1;
 +		y = clickedPos[1]-imagePos[1]+1;
 +		x = x < 0 ? 0 : x;
 +		y = y < 0 ? 0 : y;
 +		id = options['EventTarget'];
 +		x_input = $(id+"_x");
 +		y_input = $(id+"_y");
 +		if(x_input)
 +		{
 +			x_input.value = x;
 +		}
 +		else
 +		{
 +			x_input = INPUT({type:'hidden',name:id+'_x','id':id+'_x',value:x});
 +			this.element.parentNode.appendChild(x_input);
 +		}
 +		if(y_input)
 +		{
 +			y_input.value = y;
 +		}
 +		else
 +		{
 +			y_input = INPUT({type:'hidden',name:id+'_y','id':id+'_y',value:y});
 +			this.element.parentNode.appendChild(y_input);
 +		}
  	}
  });
 @@ -2949,7 +3444,7 @@ Prado.WebUI.TListBox = Class.extend(Prado.WebUI.TListControl);  Prado.WebUI.TDropDownList = Class.extend(Prado.WebUI.TListControl);
  Prado.WebUI.DefaultButton = Class.create();
 -Prado.WebUI.DefaultButton.prototype = 
 +Prado.WebUI.DefaultButton.prototype =
  {
  	initialize : function(options)
  	{
 diff --git a/framework/Web/Javascripts/js/debug/validator.js b/framework/Web/Javascripts/js/debug/validator.js index 7a963f82..ec57e876 100644 --- a/framework/Web/Javascripts/js/debug/validator.js +++ b/framework/Web/Javascripts/js/debug/validator.js @@ -90,6 +90,15 @@ Object.extend(Prado.Validation,  	},
  	/**
 +	 * @return string first form ID.
 +	 */
 +	getForm : function()
 +	{
 +		var keys = $H(this.managers).keys();
 +		return keys[0];
 +	},
 +
 +	/**
  	 * Check if the validators are valid for a particular form (and group).
  	 * The validators states will not be changed.
  	 * The <tt>validate</tt> function should be called first.
 @@ -647,6 +656,16 @@ Prado.WebUI.TBaseValidator.prototype =  	 */
  	validate : function(invoker)
  	{
 +		//try to find the control.
 +		if(!this.control)
 +			this.control = $(this.options.ControlToValidate);
 +
 +		if(!this.control)
 +		{
 +			this.isValid = true;
 +			return this.isValid;
 +		}
 +
  		if(typeof(this.options.OnValidate) == "function")
  			this.options.OnValidate(this, invoker);
 diff --git a/framework/Web/Javascripts/prado/inlineeditor.js b/framework/Web/Javascripts/prado/inlineeditor.js index 4eb33d5c..24cc9b70 100644 --- a/framework/Web/Javascripts/prado/inlineeditor.js +++ b/framework/Web/Javascripts/prado/inlineeditor.js @@ -90,10 +90,26 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  	 */
  	createTextBox : function()
  	{
 -		cssClass= this.options.TextBoxCssClass || 'editor_field';
 +		cssClass= this.element.className || '';
  		inputName = this.options.EventTarget;
  		options = {'className' : cssClass, name : inputName, id : this.options.TextBoxID};
 -		this.editField = this.options.TextMode == 'SingleLine' ? INPUT(options) : TEXTAREA(options);
 +		if(this.options.TextMode == 'SingleLine')
 +		{
 +			if(this.options.MaxLength > 0)
 +				options['maxlength'] = this.options.MaxLength;
 +			this.editField = INPUT(options);
 +		}
 +		else
 +		{
 +			if(this.options.Rows > 0)
 +				options['rows'] = this.options.Rows;
 +			if(this.options.Columns > 0)
 +				options['cols'] = this.options.Columns;
 +			if(this.options.Wrap)
 +				options['wrap'] = 'off';
 +			this.editField = TEXTAREA(options);
 +		}
 +
  		this.editField.style.display="none";
  		this.element.parentNode.insertBefore(this.editField,this.element)
 @@ -137,12 +153,14 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  	onTextBoxBlur : function(e)
  	{
  		text = this.element.innerHTML;
 -		if(text != this.editField.value)
 +		if(this.options.AutoPostBack && text != this.editField.value)
  			this.onTextChanged(text);
  		else
  		{
 +			this.element.innerHTML = this.editField.value;
  			this.isEditing = false;
 -			this.showLabel();
 +			if(this.options.AutoHide)
 +				this.showLabel();
  		}
  	},
 @@ -195,8 +213,10 @@ Prado.WebUI.TInPlaceTextBox = Base.extend(  	{
  		this.isSaving = false;
  		this.isEditing = false;
 -		this.showLabel();
 +		if(this.options.AutoHide)
 +			this.showLabel();
  		this.element.innerHTML = parameter == null ? this.editField.value : parameter;
 +		this.editField.disabled = false;
  	},
  	onTextChangedFailure : function(sender, parameter)
 diff --git a/framework/Web/Javascripts/prado/validation3.js b/framework/Web/Javascripts/prado/validation3.js index c88aa661..8df3864c 100644 --- a/framework/Web/Javascripts/prado/validation3.js +++ b/framework/Web/Javascripts/prado/validation3.js @@ -660,6 +660,12 @@ Prado.WebUI.TBaseValidator.prototype =  		if(!this.control)
  			this.control = $(this.options.ControlToValidate);
 +		if(!this.control)
 +		{
 +			this.isValid = true;
 +			return this.isValid;
 +		}
 +
  		if(typeof(this.options.OnValidate) == "function")
  			this.options.OnValidate(this, invoker);
  | 
