From 1b9b64637fe08848f610bbd19b80c031cb7dba63 Mon Sep 17 00:00:00 2001 From: wei <> Date: Tue, 27 Mar 2007 02:23:20 +0000 Subject: set prado trunk to use prototype.js v1.5.1rc2, script.aculo.us to v1.7.1beta --- framework/Web/Javascripts/js/compressed/ajax.js | 318 +++ .../Javascripts/js/compressed/clientscripts.php | 2 +- framework/Web/Javascripts/js/compressed/effects.js | 45 +- framework/Web/Javascripts/js/compressed/prado.js | 109 +- .../Web/Javascripts/js/compressed/validator.js | 53 +- framework/Web/Javascripts/js/debug/ajax.js | 2474 ++++++++++++++++++++ .../Web/Javascripts/js/debug/clientscripts.php | 2 +- framework/Web/Javascripts/js/debug/effects.js | 126 +- framework/Web/Javascripts/js/debug/prado.js | 280 ++- framework/Web/Javascripts/js/debug/validator.js | 158 +- .../prado/activecontrols/activecontrols3.js | 332 +++ .../Web/Javascripts/prado/activecontrols/ajax3.js | 659 ++++++ .../prado/activecontrols/inlineeditor.js | 267 +++ .../Web/Javascripts/prado/activecontrols/json.js | 340 +++ framework/Web/Javascripts/prado/activecontrols3.js | 332 --- framework/Web/Javascripts/prado/ajax3.js | 654 ------ framework/Web/Javascripts/prado/inlineeditor.js | 267 --- .../Web/Javascripts/prado/scriptaculous-adapter.js | 263 ++- .../Web/Javascripts/prado/validator/validation3.js | 158 +- framework/Web/Javascripts/scriptaculous/builder.js | 17 +- .../Web/Javascripts/scriptaculous/controls.js | 57 +- .../Web/Javascripts/scriptaculous/dragdrop.js | 43 +- framework/Web/Javascripts/scriptaculous/effects.js | 126 +- framework/Web/Javascripts/scriptaculous/slider.js | 7 +- 24 files changed, 5434 insertions(+), 1655 deletions(-) create mode 100644 framework/Web/Javascripts/js/compressed/ajax.js create mode 100644 framework/Web/Javascripts/js/debug/ajax.js create mode 100644 framework/Web/Javascripts/prado/activecontrols/activecontrols3.js create mode 100644 framework/Web/Javascripts/prado/activecontrols/ajax3.js create mode 100644 framework/Web/Javascripts/prado/activecontrols/inlineeditor.js create mode 100644 framework/Web/Javascripts/prado/activecontrols/json.js delete mode 100644 framework/Web/Javascripts/prado/activecontrols3.js delete mode 100644 framework/Web/Javascripts/prado/ajax3.js delete mode 100644 framework/Web/Javascripts/prado/inlineeditor.js (limited to 'framework/Web/Javascripts') diff --git a/framework/Web/Javascripts/js/compressed/ajax.js b/framework/Web/Javascripts/js/compressed/ajax.js new file mode 100644 index 00000000..7f08d38c --- /dev/null +++ b/framework/Web/Javascripts/js/compressed/ajax.js @@ -0,0 +1,318 @@ + +if(typeof Effect=='undefined') +throw("controls.js requires including script.aculo.us' effects.js library");var Autocompleter={} +Autocompleter.Base=function(){};Autocompleter.Base.prototype={baseInitialize:function(element,update,options){this.element=$(element);this.update=$(update);this.hasFocus=false;this.changed=false;this.active=false;this.index=0;this.entryCount=0;if(this.setOptions) +this.setOptions(options);else +this.options=options||{};this.options.paramName=this.options.paramName||this.element.name;this.options.tokens=this.options.tokens||[];this.options.frequency=this.options.frequency||0.4;this.options.minChars=this.options.minChars||1;this.options.onShow=this.options.onShow||function(element,update){if(!update.style.position||update.style.position=='absolute'){update.style.position='absolute';Position.clone(element,update,{setHeight:false,offsetTop:element.offsetHeight});} +Effect.Appear(update,{duration:0.15});};this.options.onHide=this.options.onHide||function(element,update){new Effect.Fade(update,{duration:0.15})};if(typeof(this.options.tokens)=='string') +this.options.tokens=new Array(this.options.tokens);this.observer=null;this.element.setAttribute('autocomplete','off');Element.hide(this.update);Event.observe(this.element,"blur",this.onBlur.bindAsEventListener(this));Event.observe(this.element,"keypress",this.onKeyPress.bindAsEventListener(this));},show:function(){if(Element.getStyle(this.update,'display')=='none')this.options.onShow(this.element,this.update);if(!this.iefix&&(Prototype.Browser.IE)&&(Element.getStyle(this.update,'position')=='absolute')){new Insertion.After(this.update,'');this.iefix=$(this.update.id+'_iefix');} +if(this.iefix)setTimeout(this.fixIEOverlapping.bind(this),50);},fixIEOverlapping:function(){Position.clone(this.update,this.iefix,{setTop:(!this.update.style.height)});this.iefix.style.zIndex=1;this.update.style.zIndex=2;Element.show(this.iefix);},hide:function(){this.stopIndicator();if(Element.getStyle(this.update,'display')!='none')this.options.onHide(this.element,this.update);if(this.iefix)Element.hide(this.iefix);},startIndicator:function(){if(this.options.indicator)Element.show(this.options.indicator);},stopIndicator:function(){if(this.options.indicator)Element.hide(this.options.indicator);},onKeyPress:function(event){if(this.active) +switch(event.keyCode){case Event.KEY_TAB:case Event.KEY_RETURN:this.selectEntry();Event.stop(event);case Event.KEY_ESC:this.hide();this.active=false;Event.stop(event);return;case Event.KEY_LEFT:case Event.KEY_RIGHT:return;case Event.KEY_UP:this.markPrevious();this.render();if(Prototype.Browser.WebKit)Event.stop(event);return;case Event.KEY_DOWN:this.markNext();this.render();if(Prototype.Browser.WebKit)Event.stop(event);return;} +else +if(event.keyCode==Event.KEY_TAB||event.keyCode==Event.KEY_RETURN||(Prototype.Browser.WebKit>0&&event.keyCode==0))return;this.changed=true;this.hasFocus=true;if(this.observer)clearTimeout(this.observer);this.observer=setTimeout(this.onObserverEvent.bind(this),this.options.frequency*1000);},activate:function(){this.changed=false;this.hasFocus=true;this.getUpdatedChoices();},onHover:function(event){var element=Event.findElement(event,'LI');if(this.index!=element.autocompleteIndex) +{this.index=element.autocompleteIndex;this.render();} +Event.stop(event);},onClick:function(event){var element=Event.findElement(event,'LI');this.index=element.autocompleteIndex;this.selectEntry();this.hide();},onBlur:function(event){setTimeout(this.hide.bind(this),250);this.hasFocus=false;this.active=false;},render:function(){if(this.entryCount>0){for(var i=0;i0)this.index-- +else this.index=this.entryCount-1;this.getEntry(this.index).scrollIntoView(true);},markNext:function(){if(this.index0)value=Element.collectTextNodes(nodes[0],this.options.select);}else +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;}else{this.element.value=value;} +this.element.focus();if(this.options.afterUpdateElement) +this.options.afterUpdateElement(this.element,selectedElement);},updateChoices:function(choices){if(!this.changed&&this.hasFocus){this.update.innerHTML=choices;Element.cleanWhitespace(this.update);Element.cleanWhitespace(this.update.down());if(this.update.firstChild&&this.update.down().childNodes){this.entryCount=this.update.down().childNodes.length;for(var i=0;i=this.options.minChars){this.startIndicator();this.getUpdatedChoices();}else{this.active=false;this.hide();}},getToken:function(){var tokenPos=this.findLastToken();if(tokenPos!=-1) +var ret=this.element.value.substr(tokenPos+1).replace(/^\s+/,'').replace(/\s+$/,'');else +var ret=this.element.value;return/\n/.test(ret)?'':ret;},findLastToken:function(){var lastTokenPos=-1;for(var i=0;ilastTokenPos) +lastTokenPos=thisTokenPos;} +return lastTokenPos;}} +Ajax.Autocompleter=Class.create();Object.extend(Object.extend(Ajax.Autocompleter.prototype,Autocompleter.Base.prototype),{initialize:function(element,update,url,options){this.baseInitialize(element,update,options);this.options.asynchronous=true;this.options.onComplete=this.onComplete.bind(this);this.options.defaultParams=this.options.parameters||null;this.url=url;},getUpdatedChoices:function(){entry=encodeURIComponent(this.options.paramName)+'='+ +encodeURIComponent(this.getToken());this.options.parameters=this.options.callback?this.options.callback(this.element,entry):entry;if(this.options.defaultParams) +this.options.parameters+='&'+this.options.defaultParams;new Ajax.Request(this.url,this.options);},onComplete:function(request){this.updateChoices(request.responseText);}});Autocompleter.Local=Class.create();Autocompleter.Local.prototype=Object.extend(new Autocompleter.Base(),{initialize:function(element,update,array,options){this.baseInitialize(element,update,options);this.options.array=array;},getUpdatedChoices:function(){this.updateChoices(this.options.selector(this));},setOptions:function(options){this.options=Object.extend({choices:10,partialSearch:true,partialChars:2,ignoreCase:true,fullSearch:false,selector:function(instance){var ret=[];var partial=[];var entry=instance.getToken();var count=0;for(var i=0;i"+elem.substr(0,entry.length)+""+ +elem.substr(entry.length)+"");break;}else if(entry.length>=instance.options.partialChars&&instance.options.partialSearch&&foundPos!=-1){if(instance.options.fullSearch||/\s/.test(elem.substr(foundPos-1,1))){partial.push("
  • "+elem.substr(0,foundPos)+""+ +elem.substr(foundPos,entry.length)+""+elem.substr(foundPos+entry.length)+"
  • ");break;}} +foundPos=instance.options.ignoreCase?elem.toLowerCase().indexOf(entry.toLowerCase(),foundPos+1):elem.indexOf(entry,foundPos+1);}} +if(partial.length) +ret=ret.concat(partial.slice(0,instance.options.choices-ret.length)) +return"
      "+ret.join('')+"
    ";}},options||{});}});Field.scrollFreeActivate=function(field){setTimeout(function(){Field.activate(field);},1);} +Ajax.InPlaceEditor=Class.create();Ajax.InPlaceEditor.defaultHighlightColor="#FFFF99";Ajax.InPlaceEditor.prototype={initialize:function(element,url,options){this.url=url;this.element=$(element);this.options=Object.extend({paramName:"value",okButton:true,okLink:false,okText:"ok",cancelButton:false,cancelLink:true,cancelText:"cancel",textBeforeControls:'',textBetweenControls:'',textAfterControls:'',savingText:"Saving...",clickToEditText:"Click to edit",okText:"ok",rows:1,onComplete:function(transport,element){new Effect.Highlight(element,{startcolor:this.options.highlightcolor});},onFailure:function(transport){alert("Error communicating with the server: "+transport.responseText.stripTags());},callback:function(form){return Form.serialize(form);},handleLineBreaks:true,loadingText:'Loading...',savingClassName:'inplaceeditor-saving',loadingClassName:'inplaceeditor-loading',formClassName:'inplaceeditor-form',highlightcolor:Ajax.InPlaceEditor.defaultHighlightColor,highlightendcolor:"#FFFFFF",externalControl:null,submitOnBlur:false,ajaxOptions:{},evalScripts:false},options||{});if(!this.options.formId&&this.element.id){this.options.formId=this.element.id+"-inplaceeditor";if($(this.options.formId)){this.options.formId=null;}} +if(this.options.externalControl){this.options.externalControl=$(this.options.externalControl);} +this.originalBackground=Element.getStyle(this.element,'background-color');if(!this.originalBackground){this.originalBackground="transparent";} +this.element.title=this.options.clickToEditText;this.onclickListener=this.enterEditMode.bindAsEventListener(this);this.mouseoverListener=this.enterHover.bindAsEventListener(this);this.mouseoutListener=this.leaveHover.bindAsEventListener(this);Event.observe(this.element,'click',this.onclickListener);Event.observe(this.element,'mouseover',this.mouseoverListener);Event.observe(this.element,'mouseout',this.mouseoutListener);if(this.options.externalControl){Event.observe(this.options.externalControl,'click',this.onclickListener);Event.observe(this.options.externalControl,'mouseover',this.mouseoverListener);Event.observe(this.options.externalControl,'mouseout',this.mouseoutListener);}},enterEditMode:function(evt){if(this.saving)return;if(this.editing)return;this.editing=true;this.onEnterEditMode();if(this.options.externalControl){Element.hide(this.options.externalControl);} +Element.hide(this.element);this.createForm();this.element.parentNode.insertBefore(this.form,this.element);if(!this.options.loadTextURL)Field.scrollFreeActivate(this.editField);if(evt){Event.stop(evt);} +return false;},createForm:function(){this.form=document.createElement("form");this.form.id=this.options.formId;Element.addClassName(this.form,this.options.formClassName) +this.form.onsubmit=this.onSubmit.bind(this);this.createEditField();if(this.options.textarea){var br=document.createElement("br");this.form.appendChild(br);} +if(this.options.textBeforeControls) +this.form.appendChild(document.createTextNode(this.options.textBeforeControls));if(this.options.okButton){var okButton=document.createElement("input");okButton.type="submit";okButton.value=this.options.okText;okButton.className='editor_ok_button';this.form.appendChild(okButton);} +if(this.options.okLink){var okLink=document.createElement("a");okLink.href="#";okLink.appendChild(document.createTextNode(this.options.okText));okLink.onclick=this.onSubmit.bind(this);okLink.className='editor_ok_link';this.form.appendChild(okLink);} +if(this.options.textBetweenControls&&(this.options.okLink||this.options.okButton)&&(this.options.cancelLink||this.options.cancelButton)) +this.form.appendChild(document.createTextNode(this.options.textBetweenControls));if(this.options.cancelButton){var cancelButton=document.createElement("input");cancelButton.type="submit";cancelButton.value=this.options.cancelText;cancelButton.onclick=this.onclickCancel.bind(this);cancelButton.className='editor_cancel_button';this.form.appendChild(cancelButton);} +if(this.options.cancelLink){var cancelLink=document.createElement("a");cancelLink.href="#";cancelLink.appendChild(document.createTextNode(this.options.cancelText));cancelLink.onclick=this.onclickCancel.bind(this);cancelLink.className='editor_cancel editor_cancel_link';this.form.appendChild(cancelLink);} +if(this.options.textAfterControls) +this.form.appendChild(document.createTextNode(this.options.textAfterControls));},hasHTMLLineBreaks:function(string){if(!this.options.handleLineBreaks)return false;return string.match(/
    /i);},convertHTMLLineBreaks:function(string){return string.replace(/
    /gi,"\n").replace(//gi,"\n").replace(/<\/p>/gi,"\n").replace(/

    /gi,"");},createEditField:function(){var text;if(this.options.loadTextURL){text=this.options.loadingText;}else{text=this.getText();} +var obj=this;if(this.options.rows==1&&!this.hasHTMLLineBreaks(text)){this.options.textarea=false;var textField=document.createElement("input");textField.obj=this;textField.type="text";textField.name=this.options.paramName;textField.value=text;textField.style.backgroundColor=this.options.highlightcolor;textField.className='editor_field';var size=this.options.size||this.options.cols||0;if(size!=0)textField.size=size;if(this.options.submitOnBlur) +textField.onblur=this.onSubmit.bind(this);this.editField=textField;}else{this.options.textarea=true;var textArea=document.createElement("textarea");textArea.obj=this;textArea.name=this.options.paramName;textArea.value=this.convertHTMLLineBreaks(text);textArea.rows=this.options.rows;textArea.cols=this.options.cols||40;textArea.className='editor_field';if(this.options.submitOnBlur) +textArea.onblur=this.onSubmit.bind(this);this.editField=textArea;} +if(this.options.loadTextURL){this.loadExternalText();} +this.form.appendChild(this.editField);},getText:function(){return this.element.innerHTML;},loadExternalText:function(){Element.addClassName(this.form,this.options.loadingClassName);this.editField.disabled=true;new Ajax.Request(this.options.loadTextURL,Object.extend({asynchronous:true,onComplete:this.onLoadedExternalText.bind(this)},this.options.ajaxOptions));},onLoadedExternalText:function(transport){Element.removeClassName(this.form,this.options.loadingClassName);this.editField.disabled=false;this.editField.value=transport.responseText.stripTags();Field.scrollFreeActivate(this.editField);},onclickCancel:function(){this.onComplete();this.leaveEditMode();return false;},onFailure:function(transport){this.options.onFailure(transport);if(this.oldInnerHTML){this.element.innerHTML=this.oldInnerHTML;this.oldInnerHTML=null;} +return false;},onSubmit:function(){var form=this.form;var value=this.editField.value;this.onLoading();if(this.options.evalScripts){new Ajax.Request(this.url,Object.extend({parameters:this.options.callback(form,value),onComplete:this.onComplete.bind(this),onFailure:this.onFailure.bind(this),asynchronous:true,evalScripts:true},this.options.ajaxOptions));}else{new Ajax.Updater({success:this.element,failure:null},this.url,Object.extend({parameters:this.options.callback(form,value),onComplete:this.onComplete.bind(this),onFailure:this.onFailure.bind(this)},this.options.ajaxOptions));} +if(arguments.length>1){Event.stop(arguments[0]);} +return false;},onLoading:function(){this.saving=true;this.removeForm();this.leaveHover();this.showSaving();},showSaving:function(){this.oldInnerHTML=this.element.innerHTML;this.element.innerHTML=this.options.savingText;Element.addClassName(this.element,this.options.savingClassName);this.element.style.backgroundColor=this.originalBackground;Element.show(this.element);},removeForm:function(){if(this.form){if(this.form.parentNode)Element.remove(this.form);this.form=null;}},enterHover:function(){if(this.saving)return;this.element.style.backgroundColor=this.options.highlightcolor;if(this.effect){this.effect.cancel();} +Element.addClassName(this.element,this.options.hoverClassName)},leaveHover:function(){if(this.options.backgroundColor){this.element.style.backgroundColor=this.oldBackground;} +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((typeof this.options.value=='undefined')&&((e instanceof Array)?this.element.innerHTML==e[1]:e==optionTag.value))optionTag.selected=true;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));}};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=' '){if(c=='\\'||c=='"'){s+='\\';} +s+=c;}else{switch(c){case'\b':s+='\\b';break;case'\f':s+='\\f';break;case'\n':s+='\\n';break;case'\r':s+='\\r';break;case'\t':s+='\\t';break;default:c=c.charCodeAt();s+='\\u00'+Math.floor(c/16).toString(16)+ +(c%16).toString(16);}}} +return s+'"';case'boolean':return String(arg);default:return'null';}},parse:function(text){var at=0;var ch=' ';function error(m){throw{name:'JSONError',message:m,at:at-1,text:text};} +function next(){ch=text.charAt(at);at+=1;return ch;} +function white(){while(ch){if(ch<=' '){next();}else if(ch=='/'){switch(next()){case'/':while(next()&&ch!='\n'&&ch!='\r'){} +break;case'*':next();for(;;){if(ch){if(ch=='*'){if(next()=='/'){next();break;}}else{next();}}else{error("Unterminated comment");}} +break;default:error("Syntax error");}}else{break;}}} +function string(){var i,s='',t,u;if(ch=='"'){outer:while(next()){if(ch=='"'){next();return s;}else if(ch=='\\'){switch(next()){case'b':s+='\b';break;case'f':s+='\f';break;case'n':s+='\n';break;case'r':s+='\r';break;case't':s+='\t';break;case'u':u=0;for(i=0;i<4;i+=1){t=parseInt(next(),16);if(!isFinite(t)){break outer;} +u=u*16+t;} +s+=String.fromCharCode(u);break;default:s+=ch;}}else{s+=ch;}}} +error("Bad string");} +function array(){var a=[];if(ch=='['){next();white();if(ch==']'){next();return a;} +while(ch){a.push(value());white();if(ch==']'){next();return a;}else if(ch!=','){break;} +next();white();}} +error("Bad array");} +function object(){var k,o={};if(ch=='{'){next();white();if(ch=='}'){next();return o;} +while(ch){k=string();white();if(ch!=':'){break;} +next();o[k]=value();white();if(ch=='}'){next();return o;}else if(ch!=','){break;} +next();white();}} +error("Bad object");} +function number(){var n='',v;if(ch=='-'){n='-';next();} +while(ch>='0'&&ch<='9'){n+=ch;next();} +if(ch=='.'){n+='.';while(next()&&ch>='0'&&ch<='9'){n+=ch;}} +if(ch=='e'||ch=='E'){n+='e';next();if(ch=='-'||ch=='+'){n+=ch;next();} +while(ch>='0'&&ch<='9'){n+=ch;next();}} +v=+n;if(!isFinite(v)){}else{return v;}} +function word(){switch(ch){case't':if(next()=='r'&&next()=='u'&&next()=='e'){next();return true;} +break;case'f':if(next()=='a'&&next()=='l'&&next()=='s'&&next()=='e'){next();return false;} +break;case'n':if(next()=='u'&&next()=='l'&&next()=='l'){next();return null;} +break;} +error("Syntax error");} +function value(){white();switch(ch){case'{':return object();case'[':return array();case'"':return string();case'-':return number();default:return ch>='0'&&ch<='9'?number():word();}} +return value();}};Prado.AjaxRequest=Class.create();Prado.AjaxRequest.prototype=Ajax.Request.prototype;Object.extend(Prado.AjaxRequest.prototype,{respondToReadyState:function(readyState) +{var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.getBodyDataPart(Prado.CallbackRequest.DATA_HEADER);if(event=='Complete') +{var redirectUrl=this.getBodyContentPart(Prado.CallbackRequest.REDIRECT_HEADER);if(redirectUrl) +document.location.href=redirectUrl;if((this.getHeader('Content-type')||'').match(/^text\/javascript/i)) +{try +{json=eval('('+transport.responseText+')');}catch(e) +{if(typeof(json)=="string") +json=Prado.CallbackRequest.decode(result);}} +try +{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.success()?'Success':'Failure')]||Prototype.emptyFunction)(this,json);}catch(e){this.dispatchException(e);}} +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) +{return this.getJsonData(this.getHeader(name));},getBodyContentPart:function(name) +{if(typeof(this.transport.responseText)=="string") +return Prado.Element.extractContent(this.transport.responseText,name);},getJsonData:function(json) +{try +{return eval('('+json+')');} +catch(e) +{if(typeof(json)=="string") +return Prado.CallbackRequest.decode(json);}},getBodyDataPart:function(name) +{return this.getJsonData(this.getBodyContentPart(name));}});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',REDIRECT_HEADER:'X-PRADO-REDIRECT',requestQueue:[],requests:{},getRequestById:function(id) +{var requests=Prado.CallbackRequest.requests;if(typeof(requests[id])!="undefined") +return requests[id];},dispatch:function(id) +{var requests=Prado.CallbackRequest.requests;if(typeof(requests[id])!="undefined") +requests[id].dispatch();},addPostLoaders:function(ids) +{var self=Prado.CallbackRequest;self.PostDataLoaders=self.PostDataLoaders.concat(ids);var list=[];self.PostDataLoaders.each(function(id) +{if(list.indexOf(id)<0) +list.push(id);});self.PostDataLoaders=list;},dispatchActions:function(transport,actions) +{var self=Prado.CallbackRequest;if(actions&&actions.length>0) +actions.each(self.__run.bind(self,transport));},__run:function(transport,command) +{var self=Prado.CallbackRequest;self.transport=transport;for(var method in command) +{try +{method.toFunction().apply(self,command[method]);} +catch(e) +{if(typeof(Logger)!="undefined") +self.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";if(transport.responseText.trim().length>0) +{var f=RegExp('()([\\s\\S\\w\\W]*)()',"m");msg+=transport.responseText.replace(f,'')+"\n";} +if(typeof(data)!="undefined"&&data!=null) +msg+="Data : \n"+inspect(data)+"\n";data=request.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER);if(data&&data.length>0) +{msg+="Actions : \n";data.each(function(action) +{msg+=inspect(action)+"\n";});} +Logger.info(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[i]["function"]+"()"+"\n";} +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;},dispatchNormalRequest:function(callback) +{new Prado.AjaxRequest(callback.url,callback.options);return true;},tryNextRequest:function() +{var self=Prado.CallbackRequest;if(typeof(self.currentRequest)=='undefined'||self.currentRequest==null) +{if(self.requestQueue.length>0) +return self.dispatchQueue();}},updatePageState:function(request,transport) +{var self=Prado.CallbackRequest;var pagestate=$(self.FIELD_CALLBACK_PAGESTATE);var enabled=request.options.EnablePageStateUpdate&&request.options.HasPriority;var aborted=self.currentRequest==null;if(enabled&&!aborted&&pagestate) +{var data=request.getBodyContentPart(self.PAGESTATE_HEADER);if(typeof(data)=="string"&&data.length>0) +pagestate.value=data;else +{if(typeof(Logger)!="undefined") +Logger.warn("Missing page state:"+data);self.endCurrentRequest();return false;}} +self.endCurrentRequest();return true;},enqueue:function(callback) +{var self=Prado.CallbackRequest;self.requestQueue.push(callback);self.tryNextRequest();},dispatchQueue:function() +{var self=Prado.CallbackRequest;var callback=self.requestQueue.shift();self.currentRequest=callback;callback.options.postBody=callback._getPostData(),callback.request=new Prado.AjaxRequest(callback.url,callback.options);callback.timeout=setTimeout(function() +{self.abortRequest(callback.id);},callback.options.RequestTimeOut);},endCurrentRequest:function() +{var self=Prado.CallbackRequest;clearTimeout(self.currentRequest.timeout);self.currentRequest=null;},abortRequest:function(id) +{var self=Prado.CallbackRequest;if(typeof(self.currentRequest)!='undefined'&&self.currentRequest!=null&&self.currentRequest.id==id) +{var request=self.currentRequest.request;if(request.transport.readyState<4) +request.transport.abort();self.endCurrentRequest();} +self.tryNextRequest();}}) +Ajax.Responders.register({onComplete:function(request) +{if(request.options.HasPriority) +Prado.CallbackRequest.tryNextRequest();}});Event.OnLoad(function() +{if(typeof Logger!="undefined") +Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={initialize:function(id,options) +{this.url=this.getCallbackUrl();this.request=null;this.Enabled=true;this.id=id;if(typeof(id)=="string") +Prado.CallbackRequest.requests[id]=this;this.options=Object.extend({RequestTimeOut:30000,EnablePageStateUpdate:true,HasPriority:true,CausesValidation:true,ValidationGroup:null,PostInputs:true},options||{});},getCallbackUrl:function() +{return $('PRADO_PAGESTATE').form.action;},setCallbackParameter:function(value) +{this.options['params']=value;},getCallbackParameter: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() +{if(typeof tinyMCE!="undefined") +tinyMCE.triggerSave();Object.extend(this.options,{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.onPreDispatch) +this.options.onPreDispatch(this,null);if(!this.Enabled) +return;if(this.options.HasPriority) +{return Prado.CallbackRequest.enqueue(this);} +else +return Prado.CallbackRequest.dispatchNormalRequest(this);},abort:function() +{return Prado.CallbackRequest.abortRequest(this.id);},_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"&&value!=null) +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;} +Prado.WebUI.CallbackControl=Class.extend(Prado.WebUI.PostBackControl,{onPostBack:function(event,options) +{var 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);var request=new Prado.CallbackRequest(options.EventTarget,options);request.dispatch();Event.stop(event);}});Prado.WebUI.TActiveCheckBox=Class.extend(Prado.WebUI.CallbackControl,{onPostBack:function(event,options) +{var request=new Prado.CallbackRequest(options.EventTarget,options);if(request.dispatch()==false) +Event.stop(event);}});Prado.WebUI.TActiveRadioButton=Class.extend(Prado.WebUI.TActiveCheckBox);Prado.WebUI.TActiveCheckBoxList=Base.extend({constructor:function(options) +{for(var i=0;i0) +this.updateChoices(result);}});Prado.WebUI.TTimeTriggeredCallback=Base.extend({constructor:function(options) +{this.options=Object.extend({Interval:1},options||{});Prado.WebUI.TTimeTriggeredCallback.register(this);},startTimer:function() +{setTimeout(this.onTimerEvent.bind(this),100);if(typeof(this.timer)=='undefined'||this.timer==null) +this.timer=setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000);},stopTimer:function() +{if(typeof(this.timer)!='undefined') +{clearInterval(this.timer);this.timer=null;}},onTimerEvent:function() +{var request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.dispatch();}},{timers:{},register:function(timer) +{Prado.WebUI.TTimeTriggeredCallback.timers[timer.options.ID]=timer;},start:function(id) +{Prado.WebUI.TTimeTriggeredCallback.timers[id].startTimer();},stop:function(id) +{Prado.WebUI.TTimeTriggeredCallback.timers[id].stopTimer();}});Prado.WebUI.ActiveListControl=Base.extend({constructor:function(options) +{this.element=$(options.ID);if(this.element) +{this.options=options;Event.observe(this.element,"change",this.doCallback.bind(this));}},doCallback:function(event) +{var 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;var element=$(options['ControlID']);if(element) +Event.observe(element,this.getEventName(element),this.doCallback.bind(this));},getEventName:function(element) +{var 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) +{var request=new Prado.CallbackRequest(this.options.EventTarget,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';var 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() +{var element=$(this.options.ControlID);if(element) +{var 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) +{var request=new Prado.CallbackRequest(this.options.EventTarget,this.options);var param={'OldValue':oldValue,'NewValue':newValue};request.setCallbackParameter(param);request.dispatch();}},{timers:{},register:function(timer) +{Prado.WebUI.TValueTriggeredCallback.timers[timer.options.ID]=timer;},stop:function(id) +{Prado.WebUI.TValueTriggeredCallback.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);Prado.WebUI.TInPlaceTextBox.register(this);this.createEditorInput();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||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;},exitEditMode:function(evt) +{this.isEditing=false;this.isSaving=false;this.editField.disabled=false;this.element.innerHTML=this.editField.value;this.showLabel();},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.setCallbackParameter(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.setCallbackParameter(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);if(typeof(this.options.onSuccess)=="function") +this.options.onSuccess(sender,parameter);},onloadExternalTextFailure:function(request,parameter) +{this.isSaving=false;this.isEditing=false;this.showLabel();if(typeof(this.options.onFailure)=="function") +this.options.onFailure(sender,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;if(typeof(this.options.onSuccess)=="function") +this.options.onSuccess(sender,parameter);},onTextChangedFailure:function(sender,parameter) +{this.editField.disabled=false;this.isSaving=false;this.isEditing=false;if(typeof(this.options.onFailure)=="function") +this.options.onFailure(sender,parameter);}},{textboxes:{},register:function(obj) +{Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID]=obj;},setDisplayTextBox:function(id,value) +{var textbox=Prado.WebUI.TInPlaceTextBox.textboxes[id];if(textbox) +{if(value) +textbox.enterEditMode(null);else +{textbox.exitEditMode(null);}}}}); \ No newline at end of file diff --git a/framework/Web/Javascripts/js/compressed/clientscripts.php b/framework/Web/Javascripts/js/compressed/clientscripts.php index a0321bc2..3bc76734 100644 --- a/framework/Web/Javascripts/js/compressed/clientscripts.php +++ b/framework/Web/Javascripts/js/compressed/clientscripts.php @@ -12,7 +12,7 @@ $debugMode=(isset($_GET['mode']) && $_GET['mode']==='debug'); $expiresOffset = $debugMode ? -10000 : 3600 * 24 * 10; //no cache //allowed libraries -$library = array('prado', 'effects', 'validator', 'logger', 'datepicker', 'colorpicker'); +$library = array('prado', 'effects', 'validator', 'logger', 'datepicker', 'colorpicker', 'ajax'); $param = isset($_GET['js']) ? $_GET['js'] : ''; diff --git a/framework/Web/Javascripts/js/compressed/effects.js b/framework/Web/Javascripts/js/compressed/effects.js index 50b64f7a..da6eb8b5 100644 --- a/framework/Web/Javascripts/js/compressed/effects.js +++ b/framework/Web/Javascripts/js/compressed/effects.js @@ -3,28 +3,33 @@ String.prototype.parseColor=function(){var color='#';if(this.slice(0,4)=='rgb(') return(color.length==7?color:(arguments[0]||this));} Element.collectTextNodes=function(element){return $A($(element).childNodes).collect(function(node){return(node.nodeType==3?node.nodeValue:(node.hasChildNodes()?Element.collectTextNodes(node):''));}).flatten().join('');} Element.collectTextNodesIgnoreClass=function(element,className){return $A($(element).childNodes).collect(function(node){return(node.nodeType==3?node.nodeValue:((node.hasChildNodes()&&!Element.hasClassName(node,className))?Element.collectTextNodesIgnoreClass(node,className):''));}).flatten().join('');} -Element.setContentZoom=function(element,percent){element=$(element);element.setStyle({fontSize:(percent/100)+'em'});if(navigator.appVersion.indexOf('AppleWebKit')>0)window.scrollBy(0,0);return element;} -Element.getOpacity=function(element){return $(element).getStyle('opacity');} -Element.setOpacity=function(element,value){return $(element).setStyle({opacity:value});} +Element.setContentZoom=function(element,percent){element=$(element);element.setStyle({fontSize:(percent/100)+'em'});if(Prototype.Browser.WebKit)window.scrollBy(0,0);return element;} Element.getInlineOpacity=function(element){return $(element).style.opacity||'';} Element.forceRerendering=function(element){try{element=$(element);var n=document.createTextNode(' ');element.appendChild(n);element.removeChild(n);}catch(e){}};Array.prototype.call=function(){var args=arguments;this.each(function(f){f.apply(this,args)});} var Effect={_elementDoesNotExistError:{name:'ElementDoesNotExistError',message:'The specified DOM element does not exist, but is required for this effect to operate'},tagifyText:function(element){if(typeof Builder=='undefined') -throw("Effect.tagifyText requires including script.aculo.us' builder.js library");var tagifyStyle='position:relative';if(/MSIE/.test(navigator.userAgent)&&!window.opera)tagifyStyle+=';zoom:1';element=$(element);$A(element.childNodes).each(function(child){if(child.nodeType==3){child.nodeValue.toArray().each(function(character){element.insertBefore(Builder.node('span',{style:tagifyStyle},character==' '?String.fromCharCode(160):character),child);});Element.remove(child);}});},multiple:function(element,effect){var elements;if(((typeof element=='object')||(typeof element=='function'))&&(element.length)) +throw("Effect.tagifyText requires including script.aculo.us' builder.js library");var tagifyStyle='position:relative';if(Prototype.Browser.IE)tagifyStyle+=';zoom:1';element=$(element);$A(element.childNodes).each(function(child){if(child.nodeType==3){child.nodeValue.toArray().each(function(character){element.insertBefore(Builder.node('span',{style:tagifyStyle},character==' '?String.fromCharCode(160):character),child);});Element.remove(child);}});},multiple:function(element,effect){var elements;if(((typeof element=='object')||(typeof element=='function'))&&(element.length)) elements=element;else -elements=$(element).childNodes;var options=Object.extend({speed:0.1,delay:0.0},arguments[2]||{});var masterDelay=options.delay;$A(elements).each(function(element,index){new effect(element,Object.extend(options,{delay:index*options.speed+masterDelay}));});},PAIRS:{'slide':['SlideDown','SlideUp'],'blind':['BlindDown','BlindUp'],'appear':['Appear','Fade']},toggle:function(element,effect){element=$(element);effect=(effect||'appear').toLowerCase();var options=Object.extend({queue:{position:'end',scope:(element.id||'global'),limit:1}},arguments[2]||{});Effect[element.visible()?Effect.PAIRS[effect][1]:Effect.PAIRS[effect][0]](element,options);}};var Effect2=Effect;Effect.Transitions={linear:Prototype.K,sinoidal:function(pos){return(-Math.cos(pos*Math.PI)/2)+0.5;},reverse:function(pos){return 1-pos;},flicker:function(pos){return((-Math.cos(pos*Math.PI)/4)+0.75)+Math.random()/4;},wobble:function(pos){return(-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;},pulse:function(pos,pulses){pulses=pulses||5;return(Math.round((pos%(1/pulses))*pulses)==0?((pos*pulses*2)-Math.floor(pos*pulses*2)):1-((pos*pulses*2)-Math.floor(pos*pulses*2)));},none:function(pos){return 0;},full:function(pos){return 1;}};Effect.ScopedQueue=Class.create();Object.extend(Object.extend(Effect.ScopedQueue.prototype,Enumerable),{initialize:function(){this.effects=[];this.interval=null;},_each:function(iterator){this.effects._each(iterator);},add:function(effect){var timestamp=new Date().getTime();var position=(typeof effect.options.queue=='string')?effect.options.queue:effect.options.queue.position;switch(position){case'front':this.effects.findAll(function(e){return e.state=='idle'}).each(function(e){e.startOn+=effect.finishOn;e.finishOn+=effect.finishOn;});break;case'with-last':timestamp=this.effects.pluck('startOn').max()||timestamp;break;case'end':timestamp=this.effects.pluck('finishOn').max()||timestamp;break;} +elements=$(element).childNodes;var options=Object.extend({speed:0.1,delay:0.0},arguments[2]||{});var masterDelay=options.delay;$A(elements).each(function(element,index){new effect(element,Object.extend(options,{delay:index*options.speed+masterDelay}));});},PAIRS:{'slide':['SlideDown','SlideUp'],'blind':['BlindDown','BlindUp'],'appear':['Appear','Fade']},toggle:function(element,effect){element=$(element);effect=(effect||'appear').toLowerCase();var options=Object.extend({queue:{position:'end',scope:(element.id||'global'),limit:1}},arguments[2]||{});Effect[element.visible()?Effect.PAIRS[effect][1]:Effect.PAIRS[effect][0]](element,options);}};var Effect2=Effect;Effect.Transitions={linear:Prototype.K,sinoidal:function(pos){return(-Math.cos(pos*Math.PI)/2)+0.5;},reverse:function(pos){return 1-pos;},flicker:function(pos){var pos=((-Math.cos(pos*Math.PI)/4)+0.75)+Math.random()/4;return(pos>1?1:pos);},wobble:function(pos){return(-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;},pulse:function(pos,pulses){pulses=pulses||5;return(Math.round((pos%(1/pulses))*pulses)==0?((pos*pulses*2)-Math.floor(pos*pulses*2)):1-((pos*pulses*2)-Math.floor(pos*pulses*2)));},none:function(pos){return 0;},full:function(pos){return 1;}};Effect.ScopedQueue=Class.create();Object.extend(Object.extend(Effect.ScopedQueue.prototype,Enumerable),{initialize:function(){this.effects=[];this.interval=null;},_each:function(iterator){this.effects._each(iterator);},add:function(effect){var timestamp=new Date().getTime();var position=(typeof effect.options.queue=='string')?effect.options.queue:effect.options.queue.position;switch(position){case'front':this.effects.findAll(function(e){return e.state=='idle'}).each(function(e){e.startOn+=effect.finishOn;e.finishOn+=effect.finishOn;});break;case'with-last':timestamp=this.effects.pluck('startOn').max()||timestamp;break;case'end':timestamp=this.effects.pluck('finishOn').max()||timestamp;break;} effect.startOn+=timestamp;effect.finishOn+=timestamp;if(!effect.options.queue.limit||(this.effects.length=this.startOn){if(timePos>=this.finishOn){this.render(1.0);this.cancel();this.event('beforeFinish');if(this.finish)this.finish();this.event('afterFinish');return;} -var pos=(timePos-this.startOn)/(this.finishOn-this.startOn);var frame=Math.round(pos*this.options.fps*this.options.duration);if(frame>this.currentFrame){this.render(pos);this.currentFrame=frame;}}},render:function(pos){if(this.state=='idle'){this.state='running';this.event('beforeSetup');if(this.setup)this.setup();this.event('afterSetup');} -if(this.state=='running'){if(this.options.transition)pos=this.options.transition(pos);pos*=(this.options.to-this.options.from);pos+=this.options.from;this.position=pos;this.event('beforeUpdate');if(this.update)this.update(pos);this.event('afterUpdate');}},cancel:function(){if(!this.options.sync) +var pos=(timePos-this.startOn)/this.totalTime,frame=Math.round(pos*this.totalFrames);if(frame>this.currentFrame){this.render(pos);this.currentFrame=frame;}}},cancel:function(){if(!this.options.sync) Effect.Queues.get(typeof this.options.queue=='string'?'global':this.options.queue.scope).remove(this);this.state='finished';},event:function(eventName){if(this.options[eventName+'Internal'])this.options[eventName+'Internal'](this);if(this.options[eventName])this.options[eventName](this);},inspect:function(){var data=$H();for(property in this) if(typeof this[property]!='function')data[property]=this[property];return'#';}} -Effect.Parallel=Class.create();Object.extend(Object.extend(Effect.Parallel.prototype,Effect.Base.prototype),{initialize:function(effects){this.effects=effects||[];this.start(arguments[1]);},update:function(position){this.effects.invoke('render',position);},finish:function(position){this.effects.each(function(effect){effect.render(1.0);effect.cancel();effect.event('beforeFinish');if(effect.finish)effect.finish(position);effect.event('afterFinish');});}});Effect.Event=Class.create();Object.extend(Object.extend(Effect.Event.prototype,Effect.Base.prototype),{initialize:function(){var options=Object.extend({duration:0},arguments[0]||{});this.start(options);},update:Prototype.emptyFunction});Effect.Opacity=Class.create();Object.extend(Object.extend(Effect.Opacity.prototype,Effect.Base.prototype),{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);if(/MSIE/.test(navigator.userAgent)&&!window.opera&&(!this.element.currentStyle.hasLayout)) +Effect.Parallel=Class.create();Object.extend(Object.extend(Effect.Parallel.prototype,Effect.Base.prototype),{initialize:function(effects){this.effects=effects||[];this.start(arguments[1]);},update:function(position){this.effects.invoke('render',position);},finish:function(position){this.effects.each(function(effect){effect.render(1.0);effect.cancel();effect.event('beforeFinish');if(effect.finish)effect.finish(position);effect.event('afterFinish');});}});Effect.Event=Class.create();Object.extend(Object.extend(Effect.Event.prototype,Effect.Base.prototype),{initialize:function(){var options=Object.extend({duration:0},arguments[0]||{});this.start(options);},update:Prototype.emptyFunction});Effect.Opacity=Class.create();Object.extend(Object.extend(Effect.Opacity.prototype,Effect.Base.prototype),{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)) this.element.setStyle({zoom:1});var options=Object.extend({from:this.element.getOpacity()||0.0,to:1.0},arguments[1]||{});this.start(options);},update:function(position){this.element.setOpacity(position);}});Effect.Move=Class.create();Object.extend(Object.extend(Effect.Move.prototype,Effect.Base.prototype),{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({x:0,y:0,mode:'relative'},arguments[1]||{});this.start(options);},setup:function(){this.element.makePositioned();this.originalLeft=parseFloat(this.element.getStyle('left')||'0');this.originalTop=parseFloat(this.element.getStyle('top')||'0');if(this.options.mode=='absolute'){this.options.x=this.options.x-this.originalLeft;this.options.y=this.options.y-this.originalTop;}},update:function(position){this.element.setStyle({left:Math.round(this.options.x*position+this.originalLeft)+'px',top:Math.round(this.options.y*position+this.originalTop)+'px'});}});Effect.MoveBy=function(element,toTop,toLeft){return new Effect.Move(element,Object.extend({x:toLeft,y:toTop},arguments[3]||{}));};Effect.Scale=Class.create();Object.extend(Object.extend(Effect.Scale.prototype,Effect.Base.prototype),{initialize:function(element,percent){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:'box',scaleFrom:100.0,scaleTo:percent},arguments[2]||{});this.start(options);},setup:function(){this.restoreAfterFinish=this.options.restoreAfterFinish||false;this.elementPositioning=this.element.getStyle('position');this.originalStyle={};['top','left','width','height','fontSize'].each(function(k){this.originalStyle[k]=this.element.style[k];}.bind(this));this.originalTop=this.element.offsetTop;this.originalLeft=this.element.offsetLeft;var fontSize=this.element.getStyle('font-size')||'100%';['em','px','%','pt'].each(function(fontSizeType){if(fontSize.indexOf(fontSizeType)>0){this.fontSize=parseFloat(fontSize);this.fontSizeType=fontSizeType;}}.bind(this));this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;this.dims=null;if(this.options.scaleMode=='box') this.dims=[this.element.offsetHeight,this.element.offsetWidth];if(/^content/.test(this.options.scaleMode)) this.dims=[this.element.scrollHeight,this.element.scrollWidth];if(!this.dims) @@ -52,10 +57,16 @@ Effect.Shrink=function(element){element=$(element);var options=Object.extend({di return new Effect.Parallel([new Effect.Opacity(element,{sync:true,to:0.0,from:1.0,transition:options.opacityTransition}),new Effect.Scale(element,window.opera?1:0,{sync:true,transition:options.scaleTransition,restoreAfterFinish:true}),new Effect.Move(element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition})],Object.extend({beforeStartInternal:function(effect){effect.effects[0].element.makePositioned().makeClipping();},afterFinishInternal:function(effect){effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle);}},options));} Effect.Pulsate=function(element){element=$(element);var options=arguments[1]||{};var oldOpacity=element.getInlineOpacity();var transition=options.transition||Effect.Transitions.sinoidal;var reverser=function(pos){return transition(1-Effect.Transitions.pulse(pos,options.pulses))};reverser.bind(transition);return new Effect.Opacity(element,Object.extend(Object.extend({duration:2.0,from:0,afterFinishInternal:function(effect){effect.element.setStyle({opacity:oldOpacity});}},options),{transition:reverser}));} Effect.Fold=function(element){element=$(element);var oldStyle={top:element.style.top,left:element.style.left,width:element.style.width,height:element.style.height};element.makeClipping();return new Effect.Scale(element,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(effect){new Effect.Scale(element,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(effect){effect.element.hide().undoClipping().setStyle(oldStyle);}});}},arguments[1]||{}));};Effect.Morph=Class.create();Object.extend(Object.extend(Effect.Morph.prototype,Effect.Base.prototype),{initialize:function(element){this.element=$(element);if(!this.element)throw(Effect._elementDoesNotExistError);var options=Object.extend({style:{}},arguments[1]||{});if(typeof options.style=='string'){if(options.style.indexOf(':')==-1){var cssText='',selector='.'+options.style;$A(document.styleSheets).reverse().each(function(styleSheet){if(styleSheet.cssRules)cssRules=styleSheet.cssRules;else if(styleSheet.rules)cssRules=styleSheet.rules;$A(cssRules).reverse().each(function(rule){if(selector==rule.selectorText){cssText=rule.style.cssText;throw $break;}});if(cssText)throw $break;});this.style=cssText.parseStyle();options.afterFinishInternal=function(effect){effect.element.addClassName(effect.options.style);effect.transforms.each(function(transform){if(transform.style!='opacity') -effect.element.style[transform.style.camelize()]='';});}}else this.style=options.style.parseStyle();}else this.style=$H(options.style) +effect.element.style[transform.style]='';});}}else this.style=options.style.parseStyle();}else this.style=$H(options.style) this.start(options);},setup:function(){function parseColor(color){if(!color||['rgba(0, 0, 0, 0)','transparent'].include(color))color='#ffffff';color=color.parseColor();return $R(0,2).map(function(i){return parseInt(color.slice(i*2+1,i*2+3),16)});} -this.transforms=this.style.map(function(pair){var property=pair[0].underscore().dasherize(),value=pair[1],unit=null;if(value.parseColor('#zzzzzz')!='#zzzzzz'){value=value.parseColor();unit='color';}else if(property=='opacity'){value=parseFloat(value);if(/MSIE/.test(navigator.userAgent)&&!window.opera&&(!this.element.currentStyle.hasLayout)) -this.element.setStyle({zoom:1});}else if(Element.CSS_LENGTH.test(value)) -var components=value.match(/^([\+\-]?[0-9\.]+)(.*)$/),value=parseFloat(components[1]),unit=(components.length==3)?components[2]:null;var originalValue=this.element.getStyle(property);return $H({style:property,originalValue:unit=='color'?parseColor(originalValue):parseFloat(originalValue||0),targetValue:unit=='color'?parseColor(value):value,unit:unit});}.bind(this)).reject(function(transform){return((transform.originalValue==transform.targetValue)||(transform.unit!='color'&&(isNaN(transform.originalValue)||isNaN(transform.targetValue))))});},update:function(position){var style=$H(),value=null;this.transforms.each(function(transform){value=transform.unit=='color'?$R(0,2).inject('#',function(m,v,i){return m+(Math.round(transform.originalValue[i]+ -(transform.targetValue[i]-transform.originalValue[i])*position)).toColorPart()}):transform.originalValue+Math.round(((transform.targetValue-transform.originalValue)*position)*1000)/1000+transform.unit;style[transform.style]=value;});this.element.setStyle(style);}});Effect.Transform=Class.create();Object.extend(Effect.Transform.prototype,{initialize:function(tracks){this.tracks=[];this.options=arguments[1]||{};this.addTracks(tracks);},addTracks:function(tracks){tracks.each(function(track){var data=$H(track).values().first();this.tracks.push($H({ids:$H(track).keys().first(),effect:Effect.Morph,options:{style:data}}));}.bind(this));return this;},play:function(){return new Effect.Parallel(this.tracks.map(function(track){var elements=[$(track.ids)||$$(track.ids)].flatten();return elements.map(function(e){return new track.effect(e,Object.extend({sync:true},track.options))});}).flatten(),this.options);}});Element.CSS_PROPERTIES=$w('backgroundColor backgroundPosition borderBottomColor borderBottomStyle '+'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth '+'borderRightColor borderRightStyle borderRightWidth borderSpacing '+'borderTopColor borderTopStyle borderTopWidth bottom clip color '+'fontSize fontWeight height left letterSpacing lineHeight '+'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+'maxWidth minHeight minWidth opacity outlineColor outlineOffset '+'outlineWidth paddingBottom paddingLeft paddingRight paddingTop '+'right textIndent top width wordSpacing zIndex');Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.prototype.parseStyle=function(){var element=Element.extend(document.createElement('div'));element.innerHTML='

    ';var style=element.down().style,styleRules=$H();Element.CSS_PROPERTIES.each(function(property){if(style[property])styleRules[property]=style[property];});if(/MSIE/.test(navigator.userAgent)&&!window.opera&&this.indexOf('opacity')>-1){styleRules.opacity=this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];} -return styleRules;};Element.morph=function(element,style){new Effect.Morph(element,Object.extend({style:style},arguments[2]||{}));return element;};['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom','collectTextNodes','collectTextNodesIgnoreClass','morph'].each(function(f){Element.Methods[f]=Element[f];});Element.Methods.visualEffect=function(element,effect,options){s=effect.gsub(/_/,'-').camelize();effect_class=s.charAt(0).toUpperCase()+s.substring(1);new Effect[effect_class](element,options);return $(element);};Element.addMethods(); \ No newline at end of file +this.transforms=this.style.map(function(pair){var property=pair[0],value=pair[1],unit=null;if(value.parseColor('#zzzzzz')!='#zzzzzz'){value=value.parseColor();unit='color';}else if(property=='opacity'){value=parseFloat(value);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)) +this.element.setStyle({zoom:1});}else if(Element.CSS_LENGTH.test(value)){var components=value.match(/^([\+\-]?[0-9\.]+)(.*)$/);value=parseFloat(components[1]);unit=(components.length==3)?components[2]:null;} +var originalValue=this.element.getStyle(property);return{style:property.camelize(),originalValue:unit=='color'?parseColor(originalValue):parseFloat(originalValue||0),targetValue:unit=='color'?parseColor(value):value,unit:unit};}.bind(this)).reject(function(transform){return((transform.originalValue==transform.targetValue)||(transform.unit!='color'&&(isNaN(transform.originalValue)||isNaN(transform.targetValue))))});},update:function(position){var style={},transform,i=this.transforms.length;while(i--) +style[(transform=this.transforms[i]).style]=transform.unit=='color'?'#'+ +(Math.round(transform.originalValue[0]+ +(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart()+ +(Math.round(transform.originalValue[1]+ +(transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart()+ +(Math.round(transform.originalValue[2]+ +(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart():transform.originalValue+Math.round(((transform.targetValue-transform.originalValue)*position)*1000)/1000+transform.unit;this.element.setStyle(style,true);}});Effect.Transform=Class.create();Object.extend(Effect.Transform.prototype,{initialize:function(tracks){this.tracks=[];this.options=arguments[1]||{};this.addTracks(tracks);},addTracks:function(tracks){tracks.each(function(track){var data=$H(track).values().first();this.tracks.push($H({ids:$H(track).keys().first(),effect:Effect.Morph,options:{style:data}}));}.bind(this));return this;},play:function(){return new Effect.Parallel(this.tracks.map(function(track){var elements=[$(track.ids)||$$(track.ids)].flatten();return elements.map(function(e){return new track.effect(e,Object.extend({sync:true},track.options))});}).flatten(),this.options);}});Element.CSS_PROPERTIES=$w('backgroundColor backgroundPosition borderBottomColor borderBottomStyle '+'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth '+'borderRightColor borderRightStyle borderRightWidth borderSpacing '+'borderTopColor borderTopStyle borderTopWidth bottom clip color '+'fontSize fontWeight height left letterSpacing lineHeight '+'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+'maxWidth minHeight minWidth opacity outlineColor outlineOffset '+'outlineWidth paddingBottom paddingLeft paddingRight paddingTop '+'right textIndent top width wordSpacing zIndex');Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.prototype.parseStyle=function(){var element=document.createElement('div');element.innerHTML='
    ';var style=element.childNodes[0].style,styleRules=$H();Element.CSS_PROPERTIES.each(function(property){if(style[property])styleRules[property]=style[property];});if(Prototype.Browser.IE&&this.indexOf('opacity')>-1){styleRules.opacity=this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];} +return styleRules;};Element.morph=function(element,style){new Effect.Morph(element,Object.extend({style:style},arguments[2]||{}));return element;};['getInlineOpacity','forceRerendering','setContentZoom','collectTextNodes','collectTextNodesIgnoreClass','morph'].each(function(f){Element.Methods[f]=Element[f];});Element.Methods.visualEffect=function(element,effect,options){s=effect.dasherize().camelize();effect_class=s.charAt(0).toUpperCase()+s.substring(1);new Effect[effect_class](element,options);return $(element);};Element.addMethods(); \ 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 4a718d25..74c50356 100644 --- a/framework/Web/Javascripts/js/compressed/prado.js +++ b/framework/Web/Javascripts/js/compressed/prado.js @@ -235,7 +235,7 @@ if(Element.getStyle(element,'position')=='absolute')break;element=element.offset Element.addMethods();var Builder={NODEMAP:{AREA:'map',CAPTION:'table',COL:'table',COLGROUP:'table',LEGEND:'fieldset',OPTGROUP:'select',OPTION:'select',PARAM:'object',TBODY:'table',TD:'table',TFOOT:'table',TH:'table',THEAD:'table',TR:'table'},node:function(elementName){elementName=elementName.toUpperCase();var parentTag=this.NODEMAP[elementName]||'div';var parentElement=document.createElement(parentTag);try{parentElement.innerHTML="<"+elementName+">";}catch(e){} var element=parentElement.firstChild||null;if(element&&(element.tagName.toUpperCase()!=elementName)) element=element.getElementsByTagName(elementName)[0];if(!element)element=document.createElement(elementName);if(!element)return;if(arguments[1]) -if(this._isStringOrNumber(arguments[1])||(arguments[1]instanceof Array)){this._children(element,arguments[1]);}else{var attrs=this._attributes(arguments[1]);if(attrs.length){try{parentElement.innerHTML="<"+elementName+" "+ +if(this._isStringOrNumber(arguments[1])||(arguments[1]instanceof Array)||arguments[1].tagName){this._children(element,arguments[1]);}else{var attrs=this._attributes(arguments[1]);if(attrs.length){try{parentElement.innerHTML="<"+elementName+" "+ attrs+">";}catch(e){} element=parentElement.firstChild||null;if(!element){element=document.createElement(elementName);for(attr in arguments[1]) element[attr=='class'?'className':attr]=arguments[1][attr];} @@ -243,7 +243,8 @@ if(element.tagName.toUpperCase()!=elementName) element=parentElement.getElementsByTagName(elementName)[0];}} if(arguments[2]) this._children(element,arguments[2]);return element;},_text:function(text){return document.createTextNode(text);},ATTR_MAP:{'className':'class','htmlFor':'for'},_attributes:function(attributes){var attrs=[];for(attribute in attributes) -attrs.push((attribute in this.ATTR_MAP?this.ATTR_MAP[attribute]:attribute)+'="'+attributes[attribute].toString().escapeHTML()+'"');return attrs.join(" ");},_children:function(element,children){if(typeof children=='object'){children.flatten().each(function(e){if(typeof e=='object') +attrs.push((attribute in this.ATTR_MAP?this.ATTR_MAP[attribute]:attribute)+'="'+attributes[attribute].toString().escapeHTML()+'"');return attrs.join(" ");},_children:function(element,children){if(children.tagName){element.appendChild(children);return;} +if(typeof children=='object'){children.flatten().each(function(e){if(typeof e=='object') element.appendChild(e) else if(Builder._isStringOrNumber(e)) @@ -277,46 +278,94 @@ 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);if(!el)return;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(!el)return;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)([\\s\\S\\w\\W]*)()',"m");var 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':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(el,value) +{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;iop2);case"GreaterThanEqual":return(op1>=op2);case"LessThan":return(op10) {validate=clientFunction.toFunction();return validate(this,value);} -return true;}});Prado.WebUI.TRangeValidator=Class.extend(Prado.WebUI.TBaseValidator,{evaluateIsValid:function() +return true;}});Prado.WebUI.TActiveCustomValidator=Class.extend(Prado.WebUI.TBaseValidator,{validatingValue:null,evaluateIsValid:function() +{value=this.getValidationValue();if(!this.requestDispatched&&value!=this.validatingValue) +{this.validatingValue=value;request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.setCallbackParameter(value);request.setCausesValidation(false);request.options.onSuccess=this.callbackOnSuccess.bind(this);request.options.onFailure=this.callbackOnFailure.bind(this);request.dispatch();this.requestDispatched=true;return false;} +return this.isValid;},callbackOnSuccess:function(request,data) +{this.isValid=data;this.requestDispatched=false;if(typeof(this.options.onSuccess)=="function") +this.options.onSuccess(request,data);Prado.Validation.validate(this.options.FormID,this.group,null);},callbackOnFailure:function(request,data) +{this.requestDispatched=false;if(typeof(this.options.onFailure)=="function") +this.options.onFailure(request,data);}});Prado.WebUI.TRangeValidator=Class.extend(Prado.WebUI.TBaseValidator,{evaluateIsValid:function() {var value=this.getValidationValue();if(value.length<=0) return true;if(typeof(this.options.DataType)=="undefined") this.options.DataType="String";if(this.options.DataType!="StringLength") diff --git a/framework/Web/Javascripts/js/debug/ajax.js b/framework/Web/Javascripts/js/debug/ajax.js new file mode 100644 index 00000000..60956194 --- /dev/null +++ b/framework/Web/Javascripts/js/debug/ajax.js @@ -0,0 +1,2474 @@ +// script.aculo.us controls.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) +// Contributors: +// Richard Livsey +// Rahul Bhargava +// Rob Wills +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// Autocompleter.Base handles all the autocompletion functionality +// that's independent of the data source for autocompletion. This +// includes drawing the autocompletion menu, observing keyboard +// and mouse events, and similar. +// +// Specific autocompleters need to provide, at the very least, +// a getUpdatedChoices function that will be invoked every time +// the text inside the monitored textbox changes. This method +// should get the text for which to provide autocompletion by +// invoking this.getToken(), NOT by directly accessing +// this.element.value. This is to allow incremental tokenized +// autocompletion. Specific auto-completion logic (AJAX, etc) +// belongs in getUpdatedChoices. +// +// Tokenized incremental autocompletion is enabled automatically +// when an autocompleter is instantiated with the 'tokens' option +// in the options parameter, e.g.: +// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); +// will incrementally autocomplete with a comma as the token. +// Additionally, ',' in the above example can be replaced with +// a token array, e.g. { tokens: [',', '\n'] } which +// enables autocompletion on multiple tokens. This is most +// useful when one of the tokens is \n (a newline), as it +// allows smart autocompletion after linebreaks. + +if(typeof Effect == 'undefined') + throw("controls.js requires including script.aculo.us' effects.js library"); + +var Autocompleter = {} +Autocompleter.Base = function() {}; +Autocompleter.Base.prototype = { + baseInitialize: function(element, update, options) { + this.element = $(element); + this.update = $(update); + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entryCount = 0; + + if(this.setOptions) + this.setOptions(options); + else + this.options = options || {}; + + this.options.paramName = this.options.paramName || this.element.name; + this.options.tokens = this.options.tokens || []; + this.options.frequency = this.options.frequency || 0.4; + this.options.minChars = this.options.minChars || 1; + this.options.onShow = this.options.onShow || + function(element, update){ + if(!update.style.position || update.style.position=='absolute') { + update.style.position = 'absolute'; + Position.clone(element, update, { + setHeight: false, + offsetTop: element.offsetHeight + }); + } + Effect.Appear(update,{duration:0.15}); + }; + this.options.onHide = this.options.onHide || + function(element, update){ new Effect.Fade(update,{duration:0.15}) }; + + if(typeof(this.options.tokens) == 'string') + this.options.tokens = new Array(this.options.tokens); + + this.observer = null; + + this.element.setAttribute('autocomplete','off'); + + Element.hide(this.update); + + Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); + Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); + }, + + show: function() { + if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); + if(!this.iefix && + (Prototype.Browser.IE) && + (Element.getStyle(this.update, 'position')=='absolute')) { + new Insertion.After(this.update, + ''); + this.iefix = $(this.update.id+'_iefix'); + } + if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); + }, + + fixIEOverlapping: function() { + Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); + this.iefix.style.zIndex = 1; + this.update.style.zIndex = 2; + Element.show(this.iefix); + }, + + hide: function() { + this.stopIndicator(); + if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); + if(this.iefix) Element.hide(this.iefix); + }, + + startIndicator: function() { + if(this.options.indicator) Element.show(this.options.indicator); + }, + + stopIndicator: function() { + if(this.options.indicator) Element.hide(this.options.indicator); + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.selectEntry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active = false; + Event.stop(event); + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.markPrevious(); + this.render(); + if(Prototype.Browser.WebKit) Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + if(Prototype.Browser.WebKit) Event.stop(event); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; + + this.changed = true; + this.hasFocus = true; + + if(this.observer) clearTimeout(this.observer); + this.observer = + setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); + }, + + activate: function() { + this.changed = false; + this.hasFocus = true; + this.getUpdatedChoices(); + }, + + onHover: function(event) { + var element = Event.findElement(event, 'LI'); + if(this.index != element.autocompleteIndex) + { + this.index = element.autocompleteIndex; + this.render(); + } + Event.stop(event); + }, + + onClick: function(event) { + var element = Event.findElement(event, 'LI'); + this.index = element.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + + onBlur: function(event) { + // needed to make click events working + setTimeout(this.hide.bind(this), 250); + this.hasFocus = false; + this.active = false; + }, + + render: function() { + if(this.entryCount > 0) { + for (var i = 0; i < this.entryCount; i++) + this.index==i ? + Element.addClassName(this.getEntry(i),"selected") : + Element.removeClassName(this.getEntry(i),"selected"); + + if(this.hasFocus) { + this.show(); + this.active = true; + } + } else { + this.active = false; + this.hide(); + } + }, + + markPrevious: function() { + if(this.index > 0) this.index-- + else this.index = this.entryCount-1; + this.getEntry(this.index).scrollIntoView(true); + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++ + else this.index = 0; + this.getEntry(this.index).scrollIntoView(false); + }, + + getEntry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + + selectEntry: function() { + this.active = false; + this.updateElement(this.getCurrentEntry()); + }, + + updateElement: function(selectedElement) { + if (this.options.updateElement) { + this.options.updateElement(selectedElement); + return; + } + var value = ''; + if (this.options.select) { + var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; + if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); + } else + 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; + } else { + this.element.value = value; + } + this.element.focus(); + + if (this.options.afterUpdateElement) + this.options.afterUpdateElement(this.element, selectedElement); + }, + + updateChoices: function(choices) { + if(!this.changed && this.hasFocus) { + this.update.innerHTML = choices; + Element.cleanWhitespace(this.update); + Element.cleanWhitespace(this.update.down()); + + if(this.update.firstChild && this.update.down().childNodes) { + this.entryCount = + this.update.down().childNodes.length; + for (var i = 0; i < this.entryCount; i++) { + var entry = this.getEntry(i); + entry.autocompleteIndex = i; + this.addObservers(entry); + } + } else { + this.entryCount = 0; + } + + this.stopIndicator(); + this.index = 0; + + if(this.entryCount==1 && this.options.autoSelect) { + this.selectEntry(); + this.hide(); + } else { + this.render(); + } + } + }, + + addObservers: function(element) { + Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); + Event.observe(element, "click", this.onClick.bindAsEventListener(this)); + }, + + onObserverEvent: function() { + this.changed = false; + if(this.getToken().length>=this.options.minChars) { + this.startIndicator(); + this.getUpdatedChoices(); + } else { + this.active = false; + this.hide(); + } + }, + + getToken: function() { + var tokenPos = this.findLastToken(); + if (tokenPos != -1) + var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); + else + var ret = this.element.value; + + return /\n/.test(ret) ? '' : ret; + }, + + findLastToken: function() { + var lastTokenPos = -1; + + for (var i=0; i lastTokenPos) + lastTokenPos = thisTokenPos; + } + return lastTokenPos; + } +} + +Ajax.Autocompleter = Class.create(); +Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { + initialize: function(element, update, url, options) { + this.baseInitialize(element, update, options); + this.options.asynchronous = true; + this.options.onComplete = this.onComplete.bind(this); + this.options.defaultParams = this.options.parameters || null; + this.url = url; + }, + + getUpdatedChoices: function() { + entry = encodeURIComponent(this.options.paramName) + '=' + + encodeURIComponent(this.getToken()); + + this.options.parameters = this.options.callback ? + this.options.callback(this.element, entry) : entry; + + if(this.options.defaultParams) + this.options.parameters += '&' + this.options.defaultParams; + + new Ajax.Request(this.url, this.options); + }, + + onComplete: function(request) { + this.updateChoices(request.responseText); + } + +}); + +// The local array autocompleter. Used when you'd prefer to +// inject an array of autocompletion options into the page, rather +// than sending out Ajax queries, which can be quite slow sometimes. +// +// The constructor takes four parameters. The first two are, as usual, +// the id of the monitored textbox, and id of the autocompletion menu. +// The third is the array you want to autocomplete from, and the fourth +// is the options block. +// +// Extra local autocompletion options: +// - choices - How many autocompletion choices to offer +// +// - partialSearch - If false, the autocompleter will match entered +// text only at the beginning of strings in the +// autocomplete array. Defaults to true, which will +// match text at the beginning of any *word* in the +// strings in the autocomplete array. If you want to +// search anywhere in the string, additionally set +// the option fullSearch to true (default: off). +// +// - fullSsearch - Search anywhere in autocomplete array strings. +// +// - partialChars - How many characters to enter before triggering +// a partial match (unlike minChars, which defines +// how many characters are required to do any match +// at all). Defaults to 2. +// +// - ignoreCase - Whether to ignore case when autocompleting. +// Defaults to true. +// +// It's possible to pass in a custom function as the 'selector' +// option, if you prefer to write your own autocompletion logic. +// In that case, the other options above will not apply unless +// you support them. + +Autocompleter.Local = Class.create(); +Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { + initialize: function(element, update, array, options) { + this.baseInitialize(element, update, options); + this.options.array = array; + }, + + getUpdatedChoices: function() { + this.updateChoices(this.options.selector(this)); + }, + + setOptions: function(options) { + this.options = Object.extend({ + choices: 10, + partialSearch: true, + partialChars: 2, + ignoreCase: true, + fullSearch: false, + selector: function(instance) { + var ret = []; // Beginning matches + var partial = []; // Inside matches + var entry = instance.getToken(); + var count = 0; + + for (var i = 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { + + var elem = instance.options.array[i]; + var foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : + elem.indexOf(entry); + + while (foundPos != -1) { + if (foundPos == 0 && elem.length != entry.length) { + ret.push("
  • " + elem.substr(0, entry.length) + "" + + elem.substr(entry.length) + "
  • "); + break; + } else if (entry.length >= instance.options.partialChars && + instance.options.partialSearch && foundPos != -1) { + if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { + partial.push("
  • " + elem.substr(0, foundPos) + "" + + elem.substr(foundPos, entry.length) + "" + elem.substr( + foundPos + entry.length) + "
  • "); + break; + } + } + + foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : + elem.indexOf(entry, foundPos + 1); + + } + } + if (partial.length) + ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) + return "
      " + ret.join('') + "
    "; + } + }, options || {}); + } +}); + +// AJAX in-place editor +// +// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor + +// Use this if you notice weird scrolling problems on some browsers, +// the DOM might be a bit confused when this gets called so do this +// waits 1 ms (with setTimeout) until it does the activation +Field.scrollFreeActivate = function(field) { + setTimeout(function() { + Field.activate(field); + }, 1); +} + +Ajax.InPlaceEditor = Class.create(); +Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; +Ajax.InPlaceEditor.prototype = { + initialize: function(element, url, options) { + this.url = url; + this.element = $(element); + + this.options = Object.extend({ + paramName: "value", + okButton: true, + okLink: false, + okText: "ok", + cancelButton: false, + cancelLink: true, + cancelText: "cancel", + textBeforeControls: '', + textBetweenControls: '', + textAfterControls: '', + savingText: "Saving...", + clickToEditText: "Click to edit", + okText: "ok", + rows: 1, + onComplete: function(transport, element) { + new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); + }, + onFailure: function(transport) { + alert("Error communicating with the server: " + transport.responseText.stripTags()); + }, + callback: function(form) { + return Form.serialize(form); + }, + handleLineBreaks: true, + loadingText: 'Loading...', + savingClassName: 'inplaceeditor-saving', + loadingClassName: 'inplaceeditor-loading', + formClassName: 'inplaceeditor-form', + highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, + highlightendcolor: "#FFFFFF", + externalControl: null, + submitOnBlur: false, + ajaxOptions: {}, + evalScripts: false + }, options || {}); + + if(!this.options.formId && this.element.id) { + this.options.formId = this.element.id + "-inplaceeditor"; + if ($(this.options.formId)) { + // there's already a form with that name, don't specify an id + this.options.formId = null; + } + } + + if (this.options.externalControl) { + this.options.externalControl = $(this.options.externalControl); + } + + this.originalBackground = Element.getStyle(this.element, 'background-color'); + if (!this.originalBackground) { + this.originalBackground = "transparent"; + } + + this.element.title = this.options.clickToEditText; + + this.onclickListener = this.enterEditMode.bindAsEventListener(this); + this.mouseoverListener = this.enterHover.bindAsEventListener(this); + this.mouseoutListener = this.leaveHover.bindAsEventListener(this); + Event.observe(this.element, 'click', this.onclickListener); + Event.observe(this.element, 'mouseover', this.mouseoverListener); + Event.observe(this.element, 'mouseout', this.mouseoutListener); + if (this.options.externalControl) { + Event.observe(this.options.externalControl, 'click', this.onclickListener); + Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); + Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); + } + }, + enterEditMode: function(evt) { + if (this.saving) return; + if (this.editing) return; + this.editing = true; + this.onEnterEditMode(); + if (this.options.externalControl) { + Element.hide(this.options.externalControl); + } + Element.hide(this.element); + this.createForm(); + this.element.parentNode.insertBefore(this.form, this.element); + if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField); + // stop the event to avoid a page refresh in Safari + if (evt) { + Event.stop(evt); + } + return false; + }, + createForm: function() { + this.form = document.createElement("form"); + this.form.id = this.options.formId; + Element.addClassName(this.form, this.options.formClassName) + this.form.onsubmit = this.onSubmit.bind(this); + + this.createEditField(); + + if (this.options.textarea) { + var br = document.createElement("br"); + this.form.appendChild(br); + } + + if (this.options.textBeforeControls) + this.form.appendChild(document.createTextNode(this.options.textBeforeControls)); + + if (this.options.okButton) { + var okButton = document.createElement("input"); + okButton.type = "submit"; + okButton.value = this.options.okText; + okButton.className = 'editor_ok_button'; + this.form.appendChild(okButton); + } + + if (this.options.okLink) { + var okLink = document.createElement("a"); + okLink.href = "#"; + okLink.appendChild(document.createTextNode(this.options.okText)); + okLink.onclick = this.onSubmit.bind(this); + okLink.className = 'editor_ok_link'; + this.form.appendChild(okLink); + } + + if (this.options.textBetweenControls && + (this.options.okLink || this.options.okButton) && + (this.options.cancelLink || this.options.cancelButton)) + this.form.appendChild(document.createTextNode(this.options.textBetweenControls)); + + if (this.options.cancelButton) { + var cancelButton = document.createElement("input"); + cancelButton.type = "submit"; + cancelButton.value = this.options.cancelText; + cancelButton.onclick = this.onclickCancel.bind(this); + cancelButton.className = 'editor_cancel_button'; + this.form.appendChild(cancelButton); + } + + if (this.options.cancelLink) { + var cancelLink = document.createElement("a"); + cancelLink.href = "#"; + cancelLink.appendChild(document.createTextNode(this.options.cancelText)); + cancelLink.onclick = this.onclickCancel.bind(this); + cancelLink.className = 'editor_cancel editor_cancel_link'; + this.form.appendChild(cancelLink); + } + + if (this.options.textAfterControls) + this.form.appendChild(document.createTextNode(this.options.textAfterControls)); + }, + hasHTMLLineBreaks: function(string) { + if (!this.options.handleLineBreaks) return false; + return string.match(/
    /i); + }, + convertHTMLLineBreaks: function(string) { + return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); + }, + createEditField: function() { + var text; + if(this.options.loadTextURL) { + text = this.options.loadingText; + } else { + text = this.getText(); + } + + var obj = this; + + if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { + this.options.textarea = false; + var textField = document.createElement("input"); + textField.obj = this; + textField.type = "text"; + textField.name = this.options.paramName; + textField.value = text; + textField.style.backgroundColor = this.options.highlightcolor; + textField.className = 'editor_field'; + var size = this.options.size || this.options.cols || 0; + if (size != 0) textField.size = size; + if (this.options.submitOnBlur) + textField.onblur = this.onSubmit.bind(this); + this.editField = textField; + } else { + this.options.textarea = true; + var textArea = document.createElement("textarea"); + textArea.obj = this; + textArea.name = this.options.paramName; + textArea.value = this.convertHTMLLineBreaks(text); + textArea.rows = this.options.rows; + textArea.cols = this.options.cols || 40; + textArea.className = 'editor_field'; + if (this.options.submitOnBlur) + textArea.onblur = this.onSubmit.bind(this); + this.editField = textArea; + } + + if(this.options.loadTextURL) { + this.loadExternalText(); + } + this.form.appendChild(this.editField); + }, + getText: function() { + return this.element.innerHTML; + }, + loadExternalText: function() { + Element.addClassName(this.form, this.options.loadingClassName); + this.editField.disabled = true; + new Ajax.Request( + this.options.loadTextURL, + Object.extend({ + asynchronous: true, + onComplete: this.onLoadedExternalText.bind(this) + }, this.options.ajaxOptions) + ); + }, + onLoadedExternalText: function(transport) { + Element.removeClassName(this.form, this.options.loadingClassName); + this.editField.disabled = false; + this.editField.value = transport.responseText.stripTags(); + Field.scrollFreeActivate(this.editField); + }, + onclickCancel: function() { + this.onComplete(); + this.leaveEditMode(); + return false; + }, + onFailure: function(transport) { + this.options.onFailure(transport); + if (this.oldInnerHTML) { + this.element.innerHTML = this.oldInnerHTML; + this.oldInnerHTML = null; + } + return false; + }, + onSubmit: function() { + // onLoading resets these so we need to save them away for the Ajax call + var form = this.form; + var value = this.editField.value; + + // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... + // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... + // to be displayed indefinitely + this.onLoading(); + + if (this.options.evalScripts) { + new Ajax.Request( + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this), + asynchronous:true, + evalScripts:true + }, this.options.ajaxOptions)); + } else { + new Ajax.Updater( + { success: this.element, + // don't update on failure (this could be an option) + failure: null }, + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this) + }, this.options.ajaxOptions)); + } + // stop the event to avoid a page refresh in Safari + if (arguments.length > 1) { + Event.stop(arguments[0]); + } + return false; + }, + onLoading: function() { + this.saving = true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + showSaving: function() { + this.oldInnerHTML = this.element.innerHTML; + this.element.innerHTML = this.options.savingText; + Element.addClassName(this.element, this.options.savingClassName); + this.element.style.backgroundColor = this.originalBackground; + Element.show(this.element); + }, + removeForm: function() { + if(this.form) { + if (this.form.parentNode) Element.remove(this.form); + this.form = null; + } + }, + enterHover: function() { + if (this.saving) return; + this.element.style.backgroundColor = this.options.highlightcolor; + if (this.effect) { + this.effect.cancel(); + } + Element.addClassName(this.element, this.options.hoverClassName) + }, + leaveHover: function() { + if (this.options.backgroundColor) { + this.element.style.backgroundColor = this.oldBackground; + } + 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((typeof this.options.value == 'undefined') && + ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true; + 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); + } + } +}); + +// Delayed observer, like Form.Element.Observer, +// but waits for delay after last key input +// Ideal for live-search fields + +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)); + } +}; + + +/* +Copyright (c) 2005 JSON.org + +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 Software shall be used for Good, not Evil. + +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. +*/ + +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; + } + } + return '{' + s + '}'; + } + } + return 'null'; + case 'number': + return isFinite(arg) ? String(arg) : 'null'; + case 'string': + l = arg.length; + s = '"'; + for (i = 0; i < l; i += 1) { + c = arg.charAt(i); + if (c >= ' ') { + if (c == '\\' || c == '"') { + s += '\\'; + } + s += c; + } else { + switch (c) { + case '\b': + s += '\\b'; + break; + case '\f': + s += '\\f'; + break; + case '\n': + s += '\\n'; + break; + case '\r': + s += '\\r'; + break; + case '\t': + s += '\\t'; + break; + default: + c = c.charCodeAt(); + s += '\\u00' + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + } + } + } + return s + '"'; + case 'boolean': + return String(arg); + default: + return 'null'; + } + }, + parse: function (text) { + var at = 0; + var ch = ' '; + + function error(m) { + throw { + name: 'JSONError', + message: m, + at: at - 1, + text: text + }; + } + + function next() { + ch = text.charAt(at); + at += 1; + return ch; + } + + function white() { + while (ch) { + if (ch <= ' ') { + next(); + } else if (ch == '/') { + switch (next()) { + case '/': + while (next() && ch != '\n' && ch != '\r') {} + break; + case '*': + next(); + for (;;) { + if (ch) { + if (ch == '*') { + if (next() == '/') { + next(); + break; + } + } else { + next(); + } + } else { + error("Unterminated comment"); + } + } + break; + default: + error("Syntax error"); + } + } else { + break; + } + } + } + + function string() { + var i, s = '', t, u; + + if (ch == '"') { +outer: while (next()) { + if (ch == '"') { + next(); + return s; + } else if (ch == '\\') { + switch (next()) { + case 'b': + s += '\b'; + break; + case 'f': + s += '\f'; + break; + case 'n': + s += '\n'; + break; + case 'r': + s += '\r'; + break; + case 't': + s += '\t'; + break; + case 'u': + u = 0; + for (i = 0; i < 4; i += 1) { + t = parseInt(next(), 16); + if (!isFinite(t)) { + break outer; + } + u = u * 16 + t; + } + s += String.fromCharCode(u); + break; + default: + s += ch; + } + } else { + s += ch; + } + } + } + error("Bad string"); + } + + function array() { + var a = []; + + if (ch == '[') { + next(); + white(); + if (ch == ']') { + next(); + return a; + } + while (ch) { + a.push(value()); + white(); + if (ch == ']') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad array"); + } + + function object() { + var k, o = {}; + + if (ch == '{') { + next(); + white(); + if (ch == '}') { + next(); + return o; + } + while (ch) { + k = string(); + white(); + if (ch != ':') { + break; + } + next(); + o[k] = value(); + white(); + if (ch == '}') { + next(); + return o; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad object"); + } + + function number() { + var n = '', v; + if (ch == '-') { + n = '-'; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + if (ch == '.') { + n += '.'; + while (next() && ch >= '0' && ch <= '9') { + n += ch; + } + } + if (ch == 'e' || ch == 'E') { + n += 'e'; + next(); + if (ch == '-' || ch == '+') { + n += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + } + v = +n; + if (!isFinite(v)) { + ////error("Bad number"); + } else { + return v; + } + } + + function word() { + switch (ch) { + case 't': + if (next() == 'r' && next() == 'u' && next() == 'e') { + next(); + return true; + } + break; + case 'f': + if (next() == 'a' && next() == 'l' && next() == 's' && + next() == 'e') { + next(); + return false; + } + break; + case 'n': + if (next() == 'u' && next() == 'l' && next() == 'l') { + next(); + return null; + } + break; + } + error("Syntax error"); + } + + function value() { + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } + } + + return value(); + } +}; + + +Prado.AjaxRequest = Class.create(); +Prado.AjaxRequest.prototype = Ajax.Request.prototype; + + +/** + * Override Prototype's response implementation. + */ +Object.extend(Prado.AjaxRequest.prototype, +{ + /** + * Customize the response, dispatch onXXX response code events, and + * tries to execute response actions (javascript statements). + */ + respondToReadyState : function(readyState) + { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.getBodyDataPart(Prado.CallbackRequest.DATA_HEADER); + + if (event == 'Complete') + { + var redirectUrl = this.getBodyContentPart(Prado.CallbackRequest.REDIRECT_HEADER); + if(redirectUrl) + document.location.href = redirectUrl; + + if ((this.getHeader('Content-type') || '').match(/^text\/javascript/i)) + { + try + { + json = eval('(' + transport.responseText + ')'); + }catch (e) + { + if(typeof(json) == "string") + json = Prado.CallbackRequest.decode(result); + } + } + + try + { + Prado.CallbackRequest.updatePageState(this,transport); + Ajax.Responders.dispatch('on' + transport.status, this, transport, json); + Prado.CallbackRequest.dispatchActions(transport,this.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER)); + + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(this, json); + } catch (e) { + this.dispatchException(e); + } + } + + 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; + }, + + /** + * Gets header data assuming JSON encoding. + * @param string header name + * @return object header data as javascript structures. + */ + getHeaderData : function(name) + { + return this.getJsonData(this.getHeader(name)); + }, + + getBodyContentPart : function(name) + { + if(typeof(this.transport.responseText)=="string") + return Prado.Element.extractContent(this.transport.responseText, name); + }, + + getJsonData : function(json) + { + try + { + return eval('(' + json + ')'); + } + catch (e) + { + if(typeof(json) == "string") + return Prado.CallbackRequest.decode(json); + } + }, + + getBodyDataPart : function(name) + { + return this.getJsonData(this.getBodyContentPart(name)); + } +}); + +/** + * Prado Callback client-side request handler. + */ +Prado.CallbackRequest = Class.create(); + +/** + * Static definitions. + */ +Object.extend(Prado.CallbackRequest, +{ + /** + * 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', + + REDIRECT_HEADER : 'X-PRADO-REDIRECT', + + requestQueue : [], + + //all request objects + requests : {}, + + getRequestById : function(id) + { + var requests = Prado.CallbackRequest.requests; + if(typeof(requests[id]) != "undefined") + return requests[id]; + }, + + dispatch : function(id) + { + var requests = Prado.CallbackRequest.requests; + if(typeof(requests[id]) != "undefined") + requests[id].dispatch(); + }, + + /** + * Add ids of inputs element to post in the request. + */ + addPostLoaders : function(ids) + { + var self = Prado.CallbackRequest; + self.PostDataLoaders = self.PostDataLoaders.concat(ids); + var list = []; + self.PostDataLoaders.each(function(id) + { + if(list.indexOf(id) < 0) + list.push(id); + }); + self.PostDataLoaders = list; + }, + + /** + * Dispatch callback response actions. + */ + dispatchActions : function(transport,actions) + { + var self = Prado.CallbackRequest; + if(actions && actions.length > 0) + actions.each(self.__run.bind(self,transport)); + }, + + /** + * Prase and evaluate a Callback clien-side action + */ + __run : function(transport, command) + { + var self = Prado.CallbackRequest; + self.transport = transport; + for(var method in command) + { + try + { + method.toFunction().apply(self,command[method]); + } + catch(e) + { + if(typeof(Logger) != "undefined") + self.Exception.onException(null,e); + } + } + }, + + /** + * Respond to Prado Callback request exceptions. + */ + Exception : + { + /** + * 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"; + if(transport.responseText.trim().length >0) + { + var f = RegExp('()([\\s\\S\\w\\W]*)()',"m"); + msg += transport.responseText.replace(f,'') + "\n"; + } + if(typeof(data)!="undefined" && data != null) + msg += "Data : \n"+inspect(data)+"\n"; + data = request.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER); + if(data && data.length > 0) + { + msg += "Actions : \n"; + data.each(function(action) + { + msg += inspect(action)+"\n"; + }); + } + Logger.info(msg); + } + }, + + /** + * 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[i]["function"]+"()"+"\n"; + } + msg += e.version+" "+e.time+"\n"; + return msg; + } + }, + + /** + * @return string JSON encoded data. + */ + encode : function(data) + { + return Prado.JSON.stringify(data); + }, + + /** + * @return mixed javascript data decoded from string using JSON decoding. + */ + decode : function(data) + { + if(typeof(data) == "string" && data.trim().length > 0) + return Prado.JSON.parse(data); + else + return null; + }, + + /** + * Dispatch a normal request, no timeouts or aborting of requests. + */ + dispatchNormalRequest : function(callback) + { + //Logger.info("dispatching normal request"); + new Prado.AjaxRequest(callback.url, callback.options); + return true; + }, + + /** + * Abort the current priority request in progress. + */ + tryNextRequest : function() + { + var self = Prado.CallbackRequest; + //Logger.debug('trying next request'); + if(typeof(self.currentRequest) == 'undefined' || self.currentRequest==null) + { + if(self.requestQueue.length > 0) + return self.dispatchQueue(); + //else + //Logger.warn('empty queque'); + } +// else + // Logger.warn('current request ' + self.currentRequest.id); + }, + + /** + * Updates the page state. It will update only if EnablePageStateUpdate and + * HasPriority options are both true. + */ + updatePageState : function(request, transport) + { + var self = Prado.CallbackRequest; + var pagestate = $(self.FIELD_CALLBACK_PAGESTATE); + var enabled = request.options.EnablePageStateUpdate && request.options.HasPriority; + var aborted = self.currentRequest == null; + if(enabled && !aborted && pagestate) + { + var data = request.getBodyContentPart(self.PAGESTATE_HEADER); + if(typeof(data) == "string" && data.length > 0) + pagestate.value = data; + else + { + if(typeof(Logger) != "undefined") + Logger.warn("Missing page state:"+data); +// Logger.warn('## bad state: setting current request to null'); + self.endCurrentRequest(); + //self.tryNextRequest(); + return false; + } + } + self.endCurrentRequest(); + // Logger.warn('## state updated: setting current request to null'); + // self.tryNextRequest(); + return true; + }, + + enqueue : function(callback) + { + var self = Prado.CallbackRequest; + self.requestQueue.push(callback); + //Logger.warn("equeued "+callback.id+", current queque length="+self.requestQueue.length); + self.tryNextRequest(); + }, + + dispatchQueue : function() + { + var self = Prado.CallbackRequest; + //Logger.warn("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); + var callback = self.requestQueue.shift(); + self.currentRequest = callback; + + //get data + callback.options.postBody = callback._getPostData(), + + callback.request = new Prado.AjaxRequest(callback.url, callback.options); + callback.timeout = setTimeout(function() + { + //Logger.warn("priority timeout"); + self.abortRequest(callback.id); + },callback.options.RequestTimeOut); + //Logger.debug("dispatched "+self.currentRequest.id + " ...") + }, + + endCurrentRequest : function() + { + var self = Prado.CallbackRequest; + clearTimeout(self.currentRequest.timeout); + self.currentRequest=null; + }, + + abortRequest : function(id) + { + //Logger.warn("abort id="+id); + var self = Prado.CallbackRequest; + if(typeof(self.currentRequest) != 'undefined' + && self.currentRequest != null && self.currentRequest.id == id) + { + var request = self.currentRequest.request; + if(request.transport.readyState < 4) + request.transport.abort(); + //Logger.warn('## aborted: setting current request to null'); + self.endCurrentRequest(); + } + self.tryNextRequest(); + } +}) + +/** + * Automatically aborts the current request when a priority request has returned. + */ +Ajax.Responders.register({onComplete : function(request) +{ + if(request.options.HasPriority) + Prado.CallbackRequest.tryNextRequest(); +}}); + +//Add HTTP exception respones when logger is enabled. +Event.OnLoad(function() +{ + if(typeof Logger != "undefined") + Ajax.Responders.register(Prado.CallbackRequest.Exception); +}); + +/** + * Create and prepare a new callback request. + * Call the dispatch() method to start the callback request. + * + * request = new Prado.CallbackRequest(UniqueID, callback); + * request.dispatch(); + * + */ +Prado.CallbackRequest.prototype = +{ + + /** + * Prepare and inititate a callback request. + */ + initialize : function(id, options) + { + /** + * Callback URL, same url as the current page. + */ + this.url = this.getCallbackUrl(); + + /** + * Current callback request. + */ + this.request = null; + + this.Enabled = true; + + this.id = id; + if(typeof(id)=="string") + Prado.CallbackRequest.requests[id] = this; + + this.options = Object.extend( + { + RequestTimeOut : 30000, // 30 second timeout. + EnablePageStateUpdate : true, + HasPriority : true, + CausesValidation : true, + ValidationGroup : null, + PostInputs : true + }, options || {}); + }, + + /** + * Gets the url from the forms that contains the PRADO_PAGESTATE + * @return {String} callback url. + */ + getCallbackUrl : function() + { + return $('PRADO_PAGESTATE').form.action; + }, + + /** + * Sets the request parameter + * @param {Object} parameter value + */ + setCallbackParameter : function(value) + { + this.options['params'] = value; + }, + + /** + * @return {Object} request paramater value. + */ + getCallbackParameter : function() + { + return this.options['params']; + }, + + /** + * Sets the callback request timeout. + * @param {integer} timeout in milliseconds + */ + setRequestTimeOut : function(timeout) + { + this.options['RequestTimeOut'] = timeout; + }, + + /** + * @return {integer} request timeout in milliseconds + */ + getRequestTimeOut : function() + { + return this.options['RequestTimeOut']; + }, + + /** + * Set true to enable validation on callback dispatch. + * @param {boolean} true to validate + */ + setCausesValidation : function(validate) + { + 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; + }, + + /** + * @return {string} validation group name. + */ + getValidationGroup : function() + { + return this.options['ValidationGroup']; + }, + + /** + * Dispatch the callback request. + */ + dispatch : function() + { + //Logger.info("dispatching request"); + //trigger tinyMCE to save data. + if(typeof tinyMCE != "undefined") + tinyMCE.triggerSave(); + + //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; + } + + if(this.options.onPreDispatch) + this.options.onPreDispatch(this,null); + + if(!this.Enabled) + return; + + if(this.options.HasPriority) + { + return Prado.CallbackRequest.enqueue(this); + //return Prado.CallbackRequest.dispatchPriorityRequest(this); + } + else + return Prado.CallbackRequest.dispatchNormalRequest(this); + }, + + abort : function() + { + return Prado.CallbackRequest.abortRequest(this.id); + }, + + /** + * 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" && value != null) + 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(); + } +} + +/** + * 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(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; +} + + +/** + * Generic postback control. + */ +Prado.WebUI.CallbackControl = Class.extend(Prado.WebUI.PostBackControl, +{ + onPostBack : function(event, options) + { + var 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); + var request = new Prado.CallbackRequest(options.EventTarget, options); + request.dispatch(); + Event.stop(event); + } +}); +/** + * Active check box. + */ +Prado.WebUI.TActiveCheckBox = Class.extend(Prado.WebUI.CallbackControl, +{ + onPostBack : function(event, options) + { + var request = new Prado.CallbackRequest(options.EventTarget, options); + if(request.dispatch()==false) + Event.stop(event); + } +}); + +/** + * TActiveRadioButton control. + */ +Prado.WebUI.TActiveRadioButton = Class.extend(Prado.WebUI.TActiveCheckBox); + + +Prado.WebUI.TActiveCheckBoxList = Base.extend( +{ + constructor : function(options) + { + for(var i = 0; i 0) + this.updateChoices(result); + } +}); + +/** + * Time Triggered Callback class. + */ +Prado.WebUI.TTimeTriggeredCallback = Base.extend( +{ + constructor : function(options) + { + this.options = Object.extend({ Interval : 1 }, options || {}); + Prado.WebUI.TTimeTriggeredCallback.register(this); + }, + + startTimer : function() + { + setTimeout(this.onTimerEvent.bind(this), 100); + if(typeof(this.timer) == 'undefined' || this.timer == null) + this.timer = setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000); + }, + + stopTimer : function() + { + if(typeof(this.timer) != 'undefined') + { + clearInterval(this.timer); + this.timer = null; + } + }, + + onTimerEvent : function() + { + var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.dispatch(); + } +}, +//class methods +{ + timers : {}, + + register : function(timer) + { + Prado.WebUI.TTimeTriggeredCallback.timers[timer.options.ID] = timer; + }, + + start : function(id) + { + Prado.WebUI.TTimeTriggeredCallback.timers[id].startTimer(); + }, + + stop : function(id) + { + Prado.WebUI.TTimeTriggeredCallback.timers[id].stopTimer(); + } +}); + +Prado.WebUI.ActiveListControl = Base.extend( +{ + constructor : function(options) + { + this.element = $(options.ID); + if(this.element) + { + this.options = options; + Event.observe(this.element, "change", this.doCallback.bind(this)); + } + }, + + doCallback : function(event) + { + var 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; + +/** + * Observe event of a particular control to trigger a callback request. + */ +Prado.WebUI.TEventTriggeredCallback = Base.extend( +{ + constructor : function(options) + { + this.options = options; + var element = $(options['ControlID']); + if(element) + Event.observe(element, this.getEventName(element), this.doCallback.bind(this)); + }, + + getEventName : function(element) + { + var 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) + { + var request = new Prado.CallbackRequest(this.options.EventTarget, 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'; + var 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() + { + var element = $(this.options.ControlID); + if(element) + { + var 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) + { + var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + var param = {'OldValue' : oldValue, 'NewValue' : newValue}; + request.setCallbackParameter(param); + request.dispatch(); + } +}, +//class methods +{ + timers : {}, + + register : function(timer) + { + Prado.WebUI.TValueTriggeredCallback.timers[timer.options.ID] = timer; + }, + + stop : function(id) + { + Prado.WebUI.TValueTriggeredCallback.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); + Prado.WebUI.TInPlaceTextBox.register(this); + this.createEditorInput(); + 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 || 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; + }, + + exitEditMode : function(evt) + { + this.isEditing = false; + this.isSaving = false; + this.editField.disabled = false; + this.element.innerHTML = this.editField.value; + this.showLabel(); + }, + + showTextBox : function() + { + Element.hide(this.element); + Element.show(this.editField); + }, + + showLabel : function() + { + Element.show(this.element); + Element.hide(this.editField); + }, + + /** + * Create the edit input field. + */ + 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.setCallbackParameter(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') + { + 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)); + }, + + /** + * @return {String} panel inner html text. + */ + getText: function() + { + return this.element.innerHTML; + }, + + /** + * Edit mode entered, calls optional event handlers. + */ + 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(); + } + }, + + /** + * When the text input value has changed. + * @param {String} original text + */ + onTextChanged : function(text) + { + request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.setCallbackParameter(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; + } + }, + + /** + * When loading external text. + */ + onLoadingText : function() + { + //Logger.info("on loading text"); + }, + + onloadExternalTextSuccess : function(request, parameter) + { + this.isEditing = true; + this.editField.disabled = false; + this.editField.value = this.getText(); + Prado.Element.focus(this.editField); + if(typeof(this.options.onSuccess)=="function") + this.options.onSuccess(sender,parameter); + }, + + onloadExternalTextFailure : function(request, parameter) + { + this.isSaving = false; + this.isEditing = false; + this.showLabel(); + if(typeof(this.options.onFailure)=="function") + this.options.onFailure(sender,parameter); + }, + + /** + * 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; + if(typeof(this.options.onSuccess)=="function") + this.options.onSuccess(sender,parameter); + }, + + onTextChangedFailure : function(sender, parameter) + { + this.editField.disabled = false; + this.isSaving = false; + this.isEditing = false; + if(typeof(this.options.onFailure)=="function") + this.options.onFailure(sender,parameter); + } +}, +{ + textboxes : {}, + + register : function(obj) + { + Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID] = obj; + }, + + setDisplayTextBox : function(id,value) + { + var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id]; + if(textbox) + { + if(value) + textbox.enterEditMode(null); + else + { + textbox.exitEditMode(null); + } + } + } +}); + diff --git a/framework/Web/Javascripts/js/debug/clientscripts.php b/framework/Web/Javascripts/js/debug/clientscripts.php index a0321bc2..3bc76734 100644 --- a/framework/Web/Javascripts/js/debug/clientscripts.php +++ b/framework/Web/Javascripts/js/debug/clientscripts.php @@ -12,7 +12,7 @@ $debugMode=(isset($_GET['mode']) && $_GET['mode']==='debug'); $expiresOffset = $debugMode ? -10000 : 3600 * 24 * 10; //no cache //allowed libraries -$library = array('prado', 'effects', 'validator', 'logger', 'datepicker', 'colorpicker'); +$library = array('prado', 'effects', 'validator', 'logger', 'datepicker', 'colorpicker', 'ajax'); $param = isset($_GET['js']) ? $_GET['js'] : ''; diff --git a/framework/Web/Javascripts/js/debug/effects.js b/framework/Web/Javascripts/js/debug/effects.js index 685e57ae..d306ae44 100644 --- a/framework/Web/Javascripts/js/debug/effects.js +++ b/framework/Web/Javascripts/js/debug/effects.js @@ -1,6 +1,6 @@ -// script.aculo.us effects.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 +// script.aculo.us effects.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007 -// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Contributors: // Justin Palmer (http://encytemedia.com/) // Mark Pilgrim (http://diveintomark.org/) @@ -45,18 +45,10 @@ Element.collectTextNodesIgnoreClass = function(element, className) { Element.setContentZoom = function(element, percent) { element = $(element); element.setStyle({fontSize: (percent/100) + 'em'}); - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + if(Prototype.Browser.WebKit) window.scrollBy(0,0); return element; } -Element.getOpacity = function(element){ - return $(element).getStyle('opacity'); -} - -Element.setOpacity = function(element, value){ - return $(element).setStyle({opacity:value}); -} - Element.getInlineOpacity = function(element){ return $(element).style.opacity || ''; } @@ -89,7 +81,7 @@ var Effect = { throw("Effect.tagifyText requires including script.aculo.us' builder.js library"); var tagifyStyle = 'position:relative'; - if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1'; + if(Prototype.Browser.IE) tagifyStyle += ';zoom:1'; element = $(element); $A(element.childNodes).each( function(child) { @@ -152,7 +144,8 @@ Effect.Transitions = { return 1-pos; }, flicker: function(pos) { - return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; + var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; + return (pos > 1 ? 1 : pos); }, wobble: function(pos) { return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; @@ -179,7 +172,7 @@ Effect.ScopedQueue = Class.create(); Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { initialize: function() { this.effects = []; - this.interval = null; + this.interval = null; }, _each: function(iterator) { this.effects._each(iterator); @@ -213,7 +206,7 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) this.effects.push(effect); - if(!this.interval) + if(!this.interval) this.interval = setInterval(this.loop.bind(this), 15); }, remove: function(effect) { @@ -226,7 +219,7 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { loop: function() { var timePos = new Date().getTime(); for(var i=0, len=this.effects.length;i this.currentFrame) { this.render(pos); this.currentFrame = frame; } } }, - render: function(pos) { - if(this.state == 'idle') { - this.state = 'running'; - this.event('beforeSetup'); - if(this.setup) this.setup(); - this.event('afterSetup'); - } - if(this.state == 'running') { - if(this.options.transition) pos = this.options.transition(pos); - pos *= (this.options.to-this.options.from); - pos += this.options.from; - this.position = pos; - this.event('beforeUpdate'); - if(this.update) this.update(pos); - this.event('afterUpdate'); - } - }, cancel: function() { if(!this.options.sync) Effect.Queues.get(typeof this.options.queue == 'string' ? @@ -358,7 +358,7 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); // make this work on IE on elements without 'layout' - if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout)) + if(Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) this.element.setStyle({zoom: 1}); var options = Object.extend({ from: this.element.getOpacity() || 0.0, @@ -953,7 +953,7 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { effect.element.addClassName(effect.options.style); effect.transforms.each(function(transform) { if(transform.style != 'opacity') - effect.element.style[transform.style.camelize()] = ''; + effect.element.style[transform.style] = ''; }); } } else this.style = options.style.parseStyle(); @@ -969,26 +969,28 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { }); } this.transforms = this.style.map(function(pair){ - var property = pair[0].underscore().dasherize(), value = pair[1], unit = null; + var property = pair[0], value = pair[1], unit = null; if(value.parseColor('#zzzzzz') != '#zzzzzz') { value = value.parseColor(); unit = 'color'; } else if(property == 'opacity') { value = parseFloat(value); - if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout)) + if(Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) this.element.setStyle({zoom: 1}); - } else if(Element.CSS_LENGTH.test(value)) - var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/), - value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null; + } else if(Element.CSS_LENGTH.test(value)) { + var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); + value = parseFloat(components[1]); + unit = (components.length == 3) ? components[2] : null; + } var originalValue = this.element.getStyle(property); - return $H({ - style: property, + return { + style: property.camelize(), originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), targetValue: unit=='color' ? parseColor(value) : value, unit: unit - }); + }; }.bind(this)).reject(function(transform){ return ( (transform.originalValue == transform.targetValue) || @@ -1000,17 +1002,19 @@ Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { }); }, update: function(position) { - var style = $H(), value = null; - this.transforms.each(function(transform){ - value = transform.unit=='color' ? - $R(0,2).inject('#',function(m,v,i){ - return m+(Math.round(transform.originalValue[i]+ - (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) : + var style = {}, transform, i = this.transforms.length; + while(i--) + style[(transform = this.transforms[i]).style] = + transform.unit=='color' ? '#'+ + (Math.round(transform.originalValue[0]+ + (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + + (Math.round(transform.originalValue[1]+ + (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + + (Math.round(transform.originalValue[2]+ + (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : transform.originalValue + Math.round( ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit; - style[transform.style] = value; - }); - this.element.setStyle(style); + this.element.setStyle(style, true); } }); @@ -1057,14 +1061,14 @@ Element.CSS_PROPERTIES = $w( Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; String.prototype.parseStyle = function(){ - var element = Element.extend(document.createElement('div')); + var element = document.createElement('div'); element.innerHTML = '

    '; - var style = element.down().style, styleRules = $H(); + var style = element.childNodes[0].style, styleRules = $H(); Element.CSS_PROPERTIES.each(function(property){ if(style[property]) styleRules[property] = style[property]; }); - if(/MSIE/.test(navigator.userAgent) && !window.opera && this.indexOf('opacity') > -1) { + if(Prototype.Browser.IE && this.indexOf('opacity') > -1) { styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]; } return styleRules; @@ -1075,13 +1079,13 @@ Element.morph = function(element, style) { return element; }; -['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', +['getInlineOpacity','forceRerendering','setContentZoom', 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( function(f) { Element.Methods[f] = Element[f]; } ); Element.Methods.visualEffect = function(element, effect, options) { - s = effect.gsub(/_/, '-').camelize(); + s = effect.dasherize().camelize(); effect_class = s.charAt(0).toUpperCase() + s.substring(1); new Effect[effect_class](element, options); return $(element); diff --git a/framework/Web/Javascripts/js/debug/prado.js b/framework/Web/Javascripts/js/debug/prado.js index 87622c93..1388135d 100644 --- a/framework/Web/Javascripts/js/debug/prado.js +++ b/framework/Web/Javascripts/js/debug/prado.js @@ -3215,9 +3215,9 @@ if (Prototype.Browser.WebKit) { Element.addMethods(); -// script.aculo.us builder.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 +// script.aculo.us builder.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007 -// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ @@ -3265,7 +3265,8 @@ var Builder = { // attributes (or text) if(arguments[1]) if(this._isStringOrNumber(arguments[1]) || - (arguments[1] instanceof Array)) { + (arguments[1] instanceof Array) || + arguments[1].tagName) { this._children(element, arguments[1]); } else { var attrs = this._attributes(arguments[1]); @@ -3283,7 +3284,7 @@ var Builder = { } if(element.tagName.toUpperCase() != elementName) element = parentElement.getElementsByTagName(elementName)[0]; - } + } } // text, or array of children @@ -3309,6 +3310,10 @@ var Builder = { return attrs.join(" "); }, _children: function(element, children) { + if(children.tagName) { + element.appendChild(children); + return; + } if(typeof children=='object') { // array can hold nodes and text children.flatten().each( function(e) { if(typeof e=='object') @@ -3318,8 +3323,8 @@ var Builder = { element.appendChild(Builder._text(e)); }); } else - if(Builder._isStringOrNumber(children)) - element.appendChild(Builder._text(children)); + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); }, _isStringOrNumber: function(param) { return(typeof param=='string' || typeof param=='number'); @@ -3584,9 +3589,6 @@ Prado.PostBack = function(event,options) Event.fireEvent(form,"submit"); } -/** - * Additional element utilities. - */ Prado.Element = { /** @@ -3601,15 +3603,16 @@ 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; + if(!el) return; 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) @@ -3622,8 +3625,21 @@ Prado.Element = setAttribute : function(element, attribute, value) { var el = $(element); - if(attribute == "disabled" && value==false) + if(!el) return; + 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); }, @@ -3631,12 +3647,12 @@ Prado.Element = setOptions : function(element, options) { var el = $(element); + if(!el) return; if(el && el.tagName.toLowerCase() == "select") { - while(el.length > 0) - el.remove(0); + el.options.length = options.length; for(var i = 0; i)([\\s\\S\\w\\W]*)()',"m"); + var result = text.match(f); + if(result && result.length >= 2) + return result[2]; + else + return null; + }, + + evaluateScript : function(content) + { + content.evalScripts(); } } -/** - * Selectable element utilities - */ 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()) @@ -3668,61 +3732,125 @@ Prado.Element.Selection = } }, - 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 * options['FormID']* The ID of HTML form to manage. @@ -156,6 +174,11 @@ Prado.ValidationManager.prototype = */ initialize : function(options) { + this.validators = []; // list of validators + this.summaries = []; // validation summaries + this.groups = []; // validation groups + this.options = {}; + this.options = options; Prado.Validation.managers[options.FormID] = this; }, @@ -333,11 +356,6 @@ Prado.ValidationManager.prototype = Prado.WebUI.TValidationSummary = Class.create(); Prado.WebUI.TValidationSummary.prototype = { - group : null, - options : {}, - visible : false, - messages : null, - /** * * options['ID']* Validation summary ID, i.e., an HTML element ID @@ -357,9 +375,12 @@ Prado.WebUI.TValidationSummary.prototype = this.options = options; this.group = options.ValidationGroup; this.messages = $(options.ID); - this.visible = this.messages.style.visibility != "hidden" - this.visible = this.visible && this.messages.style.display != "none"; - Prado.Validation.addSummary(options.FormID, this); + if(this.messages) + { + this.visible = this.messages.style.visibility != "hidden" + this.visible = this.visible && this.messages.style.display != "none"; + Prado.Validation.addSummary(options.FormID, this); + } }, /** @@ -540,15 +561,6 @@ Prado.WebUI.TValidationSummary.prototype = Prado.WebUI.TBaseValidator = Class.create(); Prado.WebUI.TBaseValidator.prototype = { - enabled : true, - visible : false, - isValid : true, - options : {}, - _isObserving : {}, - group : null, - manager : null, - message : null, - /** * * options['ID']* Validator ID, e.g. span with message @@ -561,8 +573,8 @@ Prado.WebUI.TBaseValidator.prototype = * options['ValidationGroup'] Validation group * options['ControlCssClass'] Css class to use on the input upon error * options['OnValidate'] Function to call immediately after validation - * options['OnSuccess'] Function to call upon after successful validation - * options['OnError'] Function to call upon after error in validation. + * options['OnValidationSuccess'] Function to call upon after successful validation + * options['OnValidationError'] Function to call upon after error in validation. * options['ObserveChanges'] True to observe changes in input * */ @@ -572,12 +584,23 @@ Prado.WebUI.TBaseValidator.prototype = options.OnSuccess = options.OnSuccess || Prototype.emptyFunction; options.OnError = options.OnError || Prototype.emptyFunction; */ + + this.enabled = true; + this.visible = false; + this.isValid = true; + this._isObserving = {}; + this.group = null; + this.requestDispatched = false; + this.options = options; this.control = $(options.ControlToValidate); this.message = $(options.ID); - this.group = options.ValidationGroup; + if(this.control && this.message) + { + this.group = options.ValidationGroup; - this.manager = Prado.Validation.addValidator(options.FormID, this); + this.manager = Prado.Validation.addValidator(options.FormID, this); + } }, /** @@ -599,6 +622,8 @@ Prado.WebUI.TBaseValidator.prototype = if(this.options.FocusOnError && !this.isValid ) Prado.Element.focus(this.options.FocusElementID); + + this.visible = true; }, refreshControlAndMessage : function() @@ -650,8 +675,21 @@ 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); + { + if(this.requestDispatched == false) + this.options.OnValidate(this, invoker); + } if(this.enabled) this.isValid = this.evaluateIsValid(); @@ -660,20 +698,26 @@ Prado.WebUI.TBaseValidator.prototype = if(this.isValid) { - if(typeof(this.options.OnSuccess) == "function") + if(typeof(this.options.OnValidationSuccess) == "function") { - this.refreshControlAndMessage(); - this.options.OnSuccess(this, invoker); + if(this.requestDispatched == false) + { + this.refreshControlAndMessage(); + this.options.OnValidationSuccess(this, invoker); + } } else this.updateControl(); } else { - if(typeof(this.options.OnError) == "function") + if(typeof(this.options.OnValidationError) == "function") { - this.refreshControlAndMessage(); - this.options.OnError(this, invoker); + if(this.requestDispatched == false) + { + this.refreshControlAndMessage(); + this.options.OnValidationError(this, invoker) + } } else this.updateControl(); @@ -1080,6 +1124,51 @@ Prado.WebUI.TCustomValidator = Class.extend(Prado.WebUI.TBaseValidator, } }); +/** + * Uses callback request to perform validation. + */ +Prado.WebUI.TActiveCustomValidator = Class.extend(Prado.WebUI.TBaseValidator, +{ + validatingValue : null, + + /** + * Calls custom validation function. + */ + evaluateIsValid : function() + { + value = this.getValidationValue(); + if(!this.requestDispatched && value != this.validatingValue) + { + this.validatingValue = value; + request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.setCallbackParameter(value); + request.setCausesValidation(false); + request.options.onSuccess = this.callbackOnSuccess.bind(this); + request.options.onFailure = this.callbackOnFailure.bind(this); + request.dispatch(); + this.requestDispatched = true; + return false; + } + return this.isValid; + }, + + callbackOnSuccess : function(request, data) + { + this.isValid = data; + this.requestDispatched = false; + if(typeof(this.options.onSuccess) == "function") + this.options.onSuccess(request,data); + Prado.Validation.validate(this.options.FormID, this.group,null); + }, + + callbackOnFailure : function(request, data) + { + this.requestDispatched = false; + if(typeof(this.options.onFailure) == "function") + this.options.onFailure(request,data); + } +}); + /** * TRangeValidator tests whether an input value is within a specified range. * @@ -1273,6 +1362,5 @@ Prado.WebUI.TDataTypeValidator = Class.extend(Prado.WebUI.TBaseValidator, return this.convert(this.options.DataType, value) != null; } }); - diff --git a/framework/Web/Javascripts/prado/activecontrols/activecontrols3.js b/framework/Web/Javascripts/prado/activecontrols/activecontrols3.js new file mode 100644 index 00000000..bb61d8ea --- /dev/null +++ b/framework/Web/Javascripts/prado/activecontrols/activecontrols3.js @@ -0,0 +1,332 @@ +/** + * Generic postback control. + */ +Prado.WebUI.CallbackControl = Class.extend(Prado.WebUI.PostBackControl, +{ + onPostBack : function(event, options) + { + var 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); + var request = new Prado.CallbackRequest(options.EventTarget, options); + request.dispatch(); + Event.stop(event); + } +}); +/** + * Active check box. + */ +Prado.WebUI.TActiveCheckBox = Class.extend(Prado.WebUI.CallbackControl, +{ + onPostBack : function(event, options) + { + var request = new Prado.CallbackRequest(options.EventTarget, options); + if(request.dispatch()==false) + Event.stop(event); + } +}); + +/** + * TActiveRadioButton control. + */ +Prado.WebUI.TActiveRadioButton = Class.extend(Prado.WebUI.TActiveCheckBox); + + +Prado.WebUI.TActiveCheckBoxList = Base.extend( +{ + constructor : function(options) + { + for(var i = 0; i 0) + this.updateChoices(result); + } +}); + +/** + * Time Triggered Callback class. + */ +Prado.WebUI.TTimeTriggeredCallback = Base.extend( +{ + constructor : function(options) + { + this.options = Object.extend({ Interval : 1 }, options || {}); + Prado.WebUI.TTimeTriggeredCallback.register(this); + }, + + startTimer : function() + { + setTimeout(this.onTimerEvent.bind(this), 100); + if(typeof(this.timer) == 'undefined' || this.timer == null) + this.timer = setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000); + }, + + stopTimer : function() + { + if(typeof(this.timer) != 'undefined') + { + clearInterval(this.timer); + this.timer = null; + } + }, + + onTimerEvent : function() + { + var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.dispatch(); + } +}, +//class methods +{ + timers : {}, + + register : function(timer) + { + Prado.WebUI.TTimeTriggeredCallback.timers[timer.options.ID] = timer; + }, + + start : function(id) + { + Prado.WebUI.TTimeTriggeredCallback.timers[id].startTimer(); + }, + + stop : function(id) + { + Prado.WebUI.TTimeTriggeredCallback.timers[id].stopTimer(); + } +}); + +Prado.WebUI.ActiveListControl = Base.extend( +{ + constructor : function(options) + { + this.element = $(options.ID); + if(this.element) + { + this.options = options; + Event.observe(this.element, "change", this.doCallback.bind(this)); + } + }, + + doCallback : function(event) + { + var 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; + +/** + * Observe event of a particular control to trigger a callback request. + */ +Prado.WebUI.TEventTriggeredCallback = Base.extend( +{ + constructor : function(options) + { + this.options = options; + var element = $(options['ControlID']); + if(element) + Event.observe(element, this.getEventName(element), this.doCallback.bind(this)); + }, + + getEventName : function(element) + { + var 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) + { + var request = new Prado.CallbackRequest(this.options.EventTarget, 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'; + var 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() + { + var element = $(this.options.ControlID); + if(element) + { + var 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) + { + var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + var param = {'OldValue' : oldValue, 'NewValue' : newValue}; + request.setCallbackParameter(param); + request.dispatch(); + } +}, +//class methods +{ + timers : {}, + + register : function(timer) + { + Prado.WebUI.TValueTriggeredCallback.timers[timer.options.ID] = timer; + }, + + stop : function(id) + { + Prado.WebUI.TValueTriggeredCallback.timers[id].stopObserving(); + } +}); diff --git a/framework/Web/Javascripts/prado/activecontrols/ajax3.js b/framework/Web/Javascripts/prado/activecontrols/ajax3.js new file mode 100644 index 00000000..a8906a78 --- /dev/null +++ b/framework/Web/Javascripts/prado/activecontrols/ajax3.js @@ -0,0 +1,659 @@ + +Prado.AjaxRequest = Class.create(); +Prado.AjaxRequest.prototype = Ajax.Request.prototype; + + +/** + * Override Prototype's response implementation. + */ +Object.extend(Prado.AjaxRequest.prototype, +{ + /** + * Customize the response, dispatch onXXX response code events, and + * tries to execute response actions (javascript statements). + */ + respondToReadyState : function(readyState) + { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.getBodyDataPart(Prado.CallbackRequest.DATA_HEADER); + + if (event == 'Complete') + { + var redirectUrl = this.getBodyContentPart(Prado.CallbackRequest.REDIRECT_HEADER); + if(redirectUrl) + document.location.href = redirectUrl; + + if ((this.getHeader('Content-type') || '').match(/^text\/javascript/i)) + { + try + { + json = eval('(' + transport.responseText + ')'); + }catch (e) + { + if(typeof(json) == "string") + json = Prado.CallbackRequest.decode(result); + } + } + + try + { + Prado.CallbackRequest.updatePageState(this,transport); + Ajax.Responders.dispatch('on' + transport.status, this, transport, json); + Prado.CallbackRequest.dispatchActions(transport,this.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER)); + + (this.options['on' + this.transport.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(this, json); + } catch (e) { + this.dispatchException(e); + } + } + + 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; + }, + + /** + * Gets header data assuming JSON encoding. + * @param string header name + * @return object header data as javascript structures. + */ + getHeaderData : function(name) + { + return this.getJsonData(this.getHeader(name)); + }, + + getBodyContentPart : function(name) + { + if(typeof(this.transport.responseText)=="string") + return Prado.Element.extractContent(this.transport.responseText, name); + }, + + getJsonData : function(json) + { + try + { + return eval('(' + json + ')'); + } + catch (e) + { + if(typeof(json) == "string") + return Prado.CallbackRequest.decode(json); + } + }, + + getBodyDataPart : function(name) + { + return this.getJsonData(this.getBodyContentPart(name)); + } +}); + +/** + * Prado Callback client-side request handler. + */ +Prado.CallbackRequest = Class.create(); + +/** + * Static definitions. + */ +Object.extend(Prado.CallbackRequest, +{ + /** + * 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', + + REDIRECT_HEADER : 'X-PRADO-REDIRECT', + + requestQueue : [], + + //all request objects + requests : {}, + + getRequestById : function(id) + { + var requests = Prado.CallbackRequest.requests; + if(typeof(requests[id]) != "undefined") + return requests[id]; + }, + + dispatch : function(id) + { + var requests = Prado.CallbackRequest.requests; + if(typeof(requests[id]) != "undefined") + requests[id].dispatch(); + }, + + /** + * Add ids of inputs element to post in the request. + */ + addPostLoaders : function(ids) + { + var self = Prado.CallbackRequest; + self.PostDataLoaders = self.PostDataLoaders.concat(ids); + var list = []; + self.PostDataLoaders.each(function(id) + { + if(list.indexOf(id) < 0) + list.push(id); + }); + self.PostDataLoaders = list; + }, + + /** + * Dispatch callback response actions. + */ + dispatchActions : function(transport,actions) + { + var self = Prado.CallbackRequest; + if(actions && actions.length > 0) + actions.each(self.__run.bind(self,transport)); + }, + + /** + * Prase and evaluate a Callback clien-side action + */ + __run : function(transport, command) + { + var self = Prado.CallbackRequest; + self.transport = transport; + for(var method in command) + { + try + { + method.toFunction().apply(self,command[method]); + } + catch(e) + { + if(typeof(Logger) != "undefined") + self.Exception.onException(null,e); + } + } + }, + + /** + * Respond to Prado Callback request exceptions. + */ + Exception : + { + /** + * 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"; + if(transport.responseText.trim().length >0) + { + var f = RegExp('()([\\s\\S\\w\\W]*)()',"m"); + msg += transport.responseText.replace(f,'') + "\n"; + } + if(typeof(data)!="undefined" && data != null) + msg += "Data : \n"+inspect(data)+"\n"; + data = request.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER); + if(data && data.length > 0) + { + msg += "Actions : \n"; + data.each(function(action) + { + msg += inspect(action)+"\n"; + }); + } + Logger.info(msg); + } + }, + + /** + * 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[i]["function"]+"()"+"\n"; + } + msg += e.version+" "+e.time+"\n"; + return msg; + } + }, + + /** + * @return string JSON encoded data. + */ + encode : function(data) + { + return Prado.JSON.stringify(data); + }, + + /** + * @return mixed javascript data decoded from string using JSON decoding. + */ + decode : function(data) + { + if(typeof(data) == "string" && data.trim().length > 0) + return Prado.JSON.parse(data); + else + return null; + }, + + /** + * Dispatch a normal request, no timeouts or aborting of requests. + */ + dispatchNormalRequest : function(callback) + { + //Logger.info("dispatching normal request"); + new Prado.AjaxRequest(callback.url, callback.options); + return true; + }, + + /** + * Abort the current priority request in progress. + */ + tryNextRequest : function() + { + var self = Prado.CallbackRequest; + //Logger.debug('trying next request'); + if(typeof(self.currentRequest) == 'undefined' || self.currentRequest==null) + { + if(self.requestQueue.length > 0) + return self.dispatchQueue(); + //else + //Logger.warn('empty queque'); + } +// else + // Logger.warn('current request ' + self.currentRequest.id); + }, + + /** + * Updates the page state. It will update only if EnablePageStateUpdate and + * HasPriority options are both true. + */ + updatePageState : function(request, transport) + { + var self = Prado.CallbackRequest; + var pagestate = $(self.FIELD_CALLBACK_PAGESTATE); + var enabled = request.options.EnablePageStateUpdate && request.options.HasPriority; + var aborted = self.currentRequest == null; + if(enabled && !aborted && pagestate) + { + var data = request.getBodyContentPart(self.PAGESTATE_HEADER); + if(typeof(data) == "string" && data.length > 0) + pagestate.value = data; + else + { + if(typeof(Logger) != "undefined") + Logger.warn("Missing page state:"+data); +// Logger.warn('## bad state: setting current request to null'); + self.endCurrentRequest(); + //self.tryNextRequest(); + return false; + } + } + self.endCurrentRequest(); + // Logger.warn('## state updated: setting current request to null'); + // self.tryNextRequest(); + return true; + }, + + enqueue : function(callback) + { + var self = Prado.CallbackRequest; + self.requestQueue.push(callback); + //Logger.warn("equeued "+callback.id+", current queque length="+self.requestQueue.length); + self.tryNextRequest(); + }, + + dispatchQueue : function() + { + var self = Prado.CallbackRequest; + //Logger.warn("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); + var callback = self.requestQueue.shift(); + self.currentRequest = callback; + + //get data + callback.options.postBody = callback._getPostData(), + + callback.request = new Prado.AjaxRequest(callback.url, callback.options); + callback.timeout = setTimeout(function() + { + //Logger.warn("priority timeout"); + self.abortRequest(callback.id); + },callback.options.RequestTimeOut); + //Logger.debug("dispatched "+self.currentRequest.id + " ...") + }, + + endCurrentRequest : function() + { + var self = Prado.CallbackRequest; + clearTimeout(self.currentRequest.timeout); + self.currentRequest=null; + }, + + abortRequest : function(id) + { + //Logger.warn("abort id="+id); + var self = Prado.CallbackRequest; + if(typeof(self.currentRequest) != 'undefined' + && self.currentRequest != null && self.currentRequest.id == id) + { + var request = self.currentRequest.request; + if(request.transport.readyState < 4) + request.transport.abort(); + //Logger.warn('## aborted: setting current request to null'); + self.endCurrentRequest(); + } + self.tryNextRequest(); + } +}) + +/** + * Automatically aborts the current request when a priority request has returned. + */ +Ajax.Responders.register({onComplete : function(request) +{ + if(request.options.HasPriority) + Prado.CallbackRequest.tryNextRequest(); +}}); + +//Add HTTP exception respones when logger is enabled. +Event.OnLoad(function() +{ + if(typeof Logger != "undefined") + Ajax.Responders.register(Prado.CallbackRequest.Exception); +}); + +/** + * Create and prepare a new callback request. + * Call the dispatch() method to start the callback request. + * + * request = new Prado.CallbackRequest(UniqueID, callback); + * request.dispatch(); + * + */ +Prado.CallbackRequest.prototype = +{ + + /** + * Prepare and inititate a callback request. + */ + initialize : function(id, options) + { + /** + * Callback URL, same url as the current page. + */ + this.url = this.getCallbackUrl(); + + /** + * Current callback request. + */ + this.request = null; + + this.Enabled = true; + + this.id = id; + if(typeof(id)=="string") + Prado.CallbackRequest.requests[id] = this; + + this.options = Object.extend( + { + RequestTimeOut : 30000, // 30 second timeout. + EnablePageStateUpdate : true, + HasPriority : true, + CausesValidation : true, + ValidationGroup : null, + PostInputs : true + }, options || {}); + }, + + /** + * Gets the url from the forms that contains the PRADO_PAGESTATE + * @return {String} callback url. + */ + getCallbackUrl : function() + { + return $('PRADO_PAGESTATE').form.action; + }, + + /** + * Sets the request parameter + * @param {Object} parameter value + */ + setCallbackParameter : function(value) + { + this.options['params'] = value; + }, + + /** + * @return {Object} request paramater value. + */ + getCallbackParameter : function() + { + return this.options['params']; + }, + + /** + * Sets the callback request timeout. + * @param {integer} timeout in milliseconds + */ + setRequestTimeOut : function(timeout) + { + this.options['RequestTimeOut'] = timeout; + }, + + /** + * @return {integer} request timeout in milliseconds + */ + getRequestTimeOut : function() + { + return this.options['RequestTimeOut']; + }, + + /** + * Set true to enable validation on callback dispatch. + * @param {boolean} true to validate + */ + setCausesValidation : function(validate) + { + 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; + }, + + /** + * @return {string} validation group name. + */ + getValidationGroup : function() + { + return this.options['ValidationGroup']; + }, + + /** + * Dispatch the callback request. + */ + dispatch : function() + { + //Logger.info("dispatching request"); + //trigger tinyMCE to save data. + if(typeof tinyMCE != "undefined") + tinyMCE.triggerSave(); + + //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; + } + + if(this.options.onPreDispatch) + this.options.onPreDispatch(this,null); + + if(!this.Enabled) + return; + + if(this.options.HasPriority) + { + return Prado.CallbackRequest.enqueue(this); + //return Prado.CallbackRequest.dispatchPriorityRequest(this); + } + else + return Prado.CallbackRequest.dispatchNormalRequest(this); + }, + + abort : function() + { + return Prado.CallbackRequest.abortRequest(this.id); + }, + + /** + * 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" && value != null) + 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(); + } +} + +/** + * 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(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; +} diff --git a/framework/Web/Javascripts/prado/activecontrols/inlineeditor.js b/framework/Web/Javascripts/prado/activecontrols/inlineeditor.js new file mode 100644 index 00000000..c73985f7 --- /dev/null +++ b/framework/Web/Javascripts/prado/activecontrols/inlineeditor.js @@ -0,0 +1,267 @@ +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); + Prado.WebUI.TInPlaceTextBox.register(this); + this.createEditorInput(); + 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 || 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; + }, + + exitEditMode : function(evt) + { + this.isEditing = false; + this.isSaving = false; + this.editField.disabled = false; + this.element.innerHTML = this.editField.value; + this.showLabel(); + }, + + showTextBox : function() + { + Element.hide(this.element); + Element.show(this.editField); + }, + + showLabel : function() + { + Element.show(this.element); + Element.hide(this.editField); + }, + + /** + * Create the edit input field. + */ + 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.setCallbackParameter(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') + { + 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)); + }, + + /** + * @return {String} panel inner html text. + */ + getText: function() + { + return this.element.innerHTML; + }, + + /** + * Edit mode entered, calls optional event handlers. + */ + 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(); + } + }, + + /** + * When the text input value has changed. + * @param {String} original text + */ + onTextChanged : function(text) + { + request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.setCallbackParameter(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; + } + }, + + /** + * When loading external text. + */ + onLoadingText : function() + { + //Logger.info("on loading text"); + }, + + onloadExternalTextSuccess : function(request, parameter) + { + this.isEditing = true; + this.editField.disabled = false; + this.editField.value = this.getText(); + Prado.Element.focus(this.editField); + if(typeof(this.options.onSuccess)=="function") + this.options.onSuccess(sender,parameter); + }, + + onloadExternalTextFailure : function(request, parameter) + { + this.isSaving = false; + this.isEditing = false; + this.showLabel(); + if(typeof(this.options.onFailure)=="function") + this.options.onFailure(sender,parameter); + }, + + /** + * 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; + if(typeof(this.options.onSuccess)=="function") + this.options.onSuccess(sender,parameter); + }, + + onTextChangedFailure : function(sender, parameter) + { + this.editField.disabled = false; + this.isSaving = false; + this.isEditing = false; + if(typeof(this.options.onFailure)=="function") + this.options.onFailure(sender,parameter); + } +}, +{ + textboxes : {}, + + register : function(obj) + { + Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID] = obj; + }, + + setDisplayTextBox : function(id,value) + { + var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id]; + if(textbox) + { + if(value) + textbox.enterEditMode(null); + else + { + textbox.exitEditMode(null); + } + } + } +}); \ No newline at end of file diff --git a/framework/Web/Javascripts/prado/activecontrols/json.js b/framework/Web/Javascripts/prado/activecontrols/json.js new file mode 100644 index 00000000..25b17b5f --- /dev/null +++ b/framework/Web/Javascripts/prado/activecontrols/json.js @@ -0,0 +1,340 @@ +/* +Copyright (c) 2005 JSON.org + +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 Software shall be used for Good, not Evil. + +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. +*/ + +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; + } + } + return '{' + s + '}'; + } + } + return 'null'; + case 'number': + return isFinite(arg) ? String(arg) : 'null'; + case 'string': + l = arg.length; + s = '"'; + for (i = 0; i < l; i += 1) { + c = arg.charAt(i); + if (c >= ' ') { + if (c == '\\' || c == '"') { + s += '\\'; + } + s += c; + } else { + switch (c) { + case '\b': + s += '\\b'; + break; + case '\f': + s += '\\f'; + break; + case '\n': + s += '\\n'; + break; + case '\r': + s += '\\r'; + break; + case '\t': + s += '\\t'; + break; + default: + c = c.charCodeAt(); + s += '\\u00' + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + } + } + } + return s + '"'; + case 'boolean': + return String(arg); + default: + return 'null'; + } + }, + parse: function (text) { + var at = 0; + var ch = ' '; + + function error(m) { + throw { + name: 'JSONError', + message: m, + at: at - 1, + text: text + }; + } + + function next() { + ch = text.charAt(at); + at += 1; + return ch; + } + + function white() { + while (ch) { + if (ch <= ' ') { + next(); + } else if (ch == '/') { + switch (next()) { + case '/': + while (next() && ch != '\n' && ch != '\r') {} + break; + case '*': + next(); + for (;;) { + if (ch) { + if (ch == '*') { + if (next() == '/') { + next(); + break; + } + } else { + next(); + } + } else { + error("Unterminated comment"); + } + } + break; + default: + error("Syntax error"); + } + } else { + break; + } + } + } + + function string() { + var i, s = '', t, u; + + if (ch == '"') { +outer: while (next()) { + if (ch == '"') { + next(); + return s; + } else if (ch == '\\') { + switch (next()) { + case 'b': + s += '\b'; + break; + case 'f': + s += '\f'; + break; + case 'n': + s += '\n'; + break; + case 'r': + s += '\r'; + break; + case 't': + s += '\t'; + break; + case 'u': + u = 0; + for (i = 0; i < 4; i += 1) { + t = parseInt(next(), 16); + if (!isFinite(t)) { + break outer; + } + u = u * 16 + t; + } + s += String.fromCharCode(u); + break; + default: + s += ch; + } + } else { + s += ch; + } + } + } + error("Bad string"); + } + + function array() { + var a = []; + + if (ch == '[') { + next(); + white(); + if (ch == ']') { + next(); + return a; + } + while (ch) { + a.push(value()); + white(); + if (ch == ']') { + next(); + return a; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad array"); + } + + function object() { + var k, o = {}; + + if (ch == '{') { + next(); + white(); + if (ch == '}') { + next(); + return o; + } + while (ch) { + k = string(); + white(); + if (ch != ':') { + break; + } + next(); + o[k] = value(); + white(); + if (ch == '}') { + next(); + return o; + } else if (ch != ',') { + break; + } + next(); + white(); + } + } + error("Bad object"); + } + + function number() { + var n = '', v; + if (ch == '-') { + n = '-'; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + if (ch == '.') { + n += '.'; + while (next() && ch >= '0' && ch <= '9') { + n += ch; + } + } + if (ch == 'e' || ch == 'E') { + n += 'e'; + next(); + if (ch == '-' || ch == '+') { + n += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + n += ch; + next(); + } + } + v = +n; + if (!isFinite(v)) { + ////error("Bad number"); + } else { + return v; + } + } + + function word() { + switch (ch) { + case 't': + if (next() == 'r' && next() == 'u' && next() == 'e') { + next(); + return true; + } + break; + case 'f': + if (next() == 'a' && next() == 'l' && next() == 's' && + next() == 'e') { + next(); + return false; + } + break; + case 'n': + if (next() == 'u' && next() == 'l' && next() == 'l') { + next(); + return null; + } + break; + } + error("Syntax error"); + } + + function value() { + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } + } + + return value(); + } +}; \ No newline at end of file diff --git a/framework/Web/Javascripts/prado/activecontrols3.js b/framework/Web/Javascripts/prado/activecontrols3.js deleted file mode 100644 index bb61d8ea..00000000 --- a/framework/Web/Javascripts/prado/activecontrols3.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Generic postback control. - */ -Prado.WebUI.CallbackControl = Class.extend(Prado.WebUI.PostBackControl, -{ - onPostBack : function(event, options) - { - var 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); - var request = new Prado.CallbackRequest(options.EventTarget, options); - request.dispatch(); - Event.stop(event); - } -}); -/** - * Active check box. - */ -Prado.WebUI.TActiveCheckBox = Class.extend(Prado.WebUI.CallbackControl, -{ - onPostBack : function(event, options) - { - var request = new Prado.CallbackRequest(options.EventTarget, options); - if(request.dispatch()==false) - Event.stop(event); - } -}); - -/** - * TActiveRadioButton control. - */ -Prado.WebUI.TActiveRadioButton = Class.extend(Prado.WebUI.TActiveCheckBox); - - -Prado.WebUI.TActiveCheckBoxList = Base.extend( -{ - constructor : function(options) - { - for(var i = 0; i 0) - this.updateChoices(result); - } -}); - -/** - * Time Triggered Callback class. - */ -Prado.WebUI.TTimeTriggeredCallback = Base.extend( -{ - constructor : function(options) - { - this.options = Object.extend({ Interval : 1 }, options || {}); - Prado.WebUI.TTimeTriggeredCallback.register(this); - }, - - startTimer : function() - { - setTimeout(this.onTimerEvent.bind(this), 100); - if(typeof(this.timer) == 'undefined' || this.timer == null) - this.timer = setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000); - }, - - stopTimer : function() - { - if(typeof(this.timer) != 'undefined') - { - clearInterval(this.timer); - this.timer = null; - } - }, - - onTimerEvent : function() - { - var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); - request.dispatch(); - } -}, -//class methods -{ - timers : {}, - - register : function(timer) - { - Prado.WebUI.TTimeTriggeredCallback.timers[timer.options.ID] = timer; - }, - - start : function(id) - { - Prado.WebUI.TTimeTriggeredCallback.timers[id].startTimer(); - }, - - stop : function(id) - { - Prado.WebUI.TTimeTriggeredCallback.timers[id].stopTimer(); - } -}); - -Prado.WebUI.ActiveListControl = Base.extend( -{ - constructor : function(options) - { - this.element = $(options.ID); - if(this.element) - { - this.options = options; - Event.observe(this.element, "change", this.doCallback.bind(this)); - } - }, - - doCallback : function(event) - { - var 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; - -/** - * Observe event of a particular control to trigger a callback request. - */ -Prado.WebUI.TEventTriggeredCallback = Base.extend( -{ - constructor : function(options) - { - this.options = options; - var element = $(options['ControlID']); - if(element) - Event.observe(element, this.getEventName(element), this.doCallback.bind(this)); - }, - - getEventName : function(element) - { - var 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) - { - var request = new Prado.CallbackRequest(this.options.EventTarget, 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'; - var 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() - { - var element = $(this.options.ControlID); - if(element) - { - var 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) - { - var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); - var param = {'OldValue' : oldValue, 'NewValue' : newValue}; - request.setCallbackParameter(param); - request.dispatch(); - } -}, -//class methods -{ - timers : {}, - - register : function(timer) - { - Prado.WebUI.TValueTriggeredCallback.timers[timer.options.ID] = timer; - }, - - stop : function(id) - { - Prado.WebUI.TValueTriggeredCallback.timers[id].stopObserving(); - } -}); diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js deleted file mode 100644 index 51d0186b..00000000 --- a/framework/Web/Javascripts/prado/ajax3.js +++ /dev/null @@ -1,654 +0,0 @@ -/** - * Override Prototype's response implementation. - */ -Object.extend(Ajax.Request.prototype, -{ - /** - * Customize the response, dispatch onXXX response code events, and - * tries to execute response actions (javascript statements). - */ - respondToReadyState : function(readyState) - { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.getBodyDataPart(Prado.CallbackRequest.DATA_HEADER); - - if (event == 'Complete') - { - var redirectUrl = this.getBodyContentPart(Prado.CallbackRequest.REDIRECT_HEADER); - if(redirectUrl) - document.location.href = redirectUrl; - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - { - try - { - json = eval('(' + transport.responseText + ')'); - }catch (e) - { - if(typeof(json) == "string") - json = Prado.CallbackRequest.decode(result); - } - } - - try - { - Prado.CallbackRequest.updatePageState(this,transport); - Ajax.Responders.dispatch('on' + transport.status, this, transport, json); - Prado.CallbackRequest.dispatchActions(transport,this.getBodyDataPart(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); - } - } - - 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; - }, - - /** - * Gets header data assuming JSON encoding. - * @param string header name - * @return object header data as javascript structures. - */ - getHeaderData : function(name) - { - return this.getJsonData(this.header(name)); - }, - - getBodyContentPart : function(name) - { - if(typeof(this.transport.responseText)=="string") - return Prado.Element.extractContent(this.transport.responseText, name); - }, - - getJsonData : function(json) - { - try - { - return eval('(' + json + ')'); - } - catch (e) - { - if(typeof(json) == "string") - return Prado.CallbackRequest.decode(json); - } - }, - - getBodyDataPart : function(name) - { - return this.getJsonData(this.getBodyContentPart(name)); - } -}); - -/** - * Prado Callback client-side request handler. - */ -Prado.CallbackRequest = Class.create(); - -/** - * Static definitions. - */ -Object.extend(Prado.CallbackRequest, -{ - /** - * 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', - - REDIRECT_HEADER : 'X-PRADO-REDIRECT', - - requestQueue : [], - - //all request objects - requests : {}, - - getRequestById : function(id) - { - var requests = Prado.CallbackRequest.requests; - if(typeof(requests[id]) != "undefined") - return requests[id]; - }, - - dispatch : function(id) - { - var requests = Prado.CallbackRequest.requests; - if(typeof(requests[id]) != "undefined") - requests[id].dispatch(); - }, - - /** - * Add ids of inputs element to post in the request. - */ - addPostLoaders : function(ids) - { - var self = Prado.CallbackRequest; - self.PostDataLoaders = self.PostDataLoaders.concat(ids); - var list = []; - self.PostDataLoaders.each(function(id) - { - if(list.indexOf(id) < 0) - list.push(id); - }); - self.PostDataLoaders = list; - }, - - /** - * Dispatch callback response actions. - */ - dispatchActions : function(transport,actions) - { - var self = Prado.CallbackRequest; - if(actions && actions.length > 0) - actions.each(self.__run.bind(self,transport)); - }, - - /** - * Prase and evaluate a Callback clien-side action - */ - __run : function(transport, command) - { - var self = Prado.CallbackRequest; - self.transport = transport; - for(var method in command) - { - try - { - method.toFunction().apply(self,command[method]); - } - catch(e) - { - if(typeof(Logger) != "undefined") - self.Exception.onException(null,e); - } - } - }, - - /** - * Respond to Prado Callback request exceptions. - */ - Exception : - { - /** - * 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"; - if(transport.responseText.trim().length >0) - { - var f = RegExp('()([\\s\\S\\w\\W]*)()',"m"); - msg += transport.responseText.replace(f,'') + "\n"; - } - if(typeof(data)!="undefined" && data != null) - msg += "Data : \n"+inspect(data)+"\n"; - data = request.getBodyDataPart(Prado.CallbackRequest.ACTION_HEADER); - if(data && data.length > 0) - { - msg += "Actions : \n"; - data.each(function(action) - { - msg += inspect(action)+"\n"; - }); - } - Logger.info(msg); - } - }, - - /** - * 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[i]["function"]+"()"+"\n"; - } - msg += e.version+" "+e.time+"\n"; - return msg; - } - }, - - /** - * @return string JSON encoded data. - */ - encode : function(data) - { - return Prado.JSON.stringify(data); - }, - - /** - * @return mixed javascript data decoded from string using JSON decoding. - */ - decode : function(data) - { - if(typeof(data) == "string" && data.trim().length > 0) - return Prado.JSON.parse(data); - else - return null; - }, - - /** - * Dispatch a normal request, no timeouts or aborting of requests. - */ - dispatchNormalRequest : function(callback) - { - //Logger.info("dispatching normal request"); - new Ajax.Request(callback.url, callback.options); - return true; - }, - - /** - * Abort the current priority request in progress. - */ - tryNextRequest : function() - { - var self = Prado.CallbackRequest; - //Logger.debug('trying next request'); - if(typeof(self.currentRequest) == 'undefined' || self.currentRequest==null) - { - if(self.requestQueue.length > 0) - return self.dispatchQueue(); - //else - //Logger.warn('empty queque'); - } -// else - // Logger.warn('current request ' + self.currentRequest.id); - }, - - /** - * Updates the page state. It will update only if EnablePageStateUpdate and - * HasPriority options are both true. - */ - updatePageState : function(request, transport) - { - var self = Prado.CallbackRequest; - var pagestate = $(self.FIELD_CALLBACK_PAGESTATE); - var enabled = request.options.EnablePageStateUpdate && request.options.HasPriority; - var aborted = self.currentRequest == null; - if(enabled && !aborted && pagestate) - { - var data = request.getBodyContentPart(self.PAGESTATE_HEADER); - if(typeof(data) == "string" && data.length > 0) - pagestate.value = data; - else - { - if(typeof(Logger) != "undefined") - Logger.warn("Missing page state:"+data); -// Logger.warn('## bad state: setting current request to null'); - self.endCurrentRequest(); - //self.tryNextRequest(); - return false; - } - } - self.endCurrentRequest(); - // Logger.warn('## state updated: setting current request to null'); - // self.tryNextRequest(); - return true; - }, - - enqueue : function(callback) - { - var self = Prado.CallbackRequest; - self.requestQueue.push(callback); - //Logger.warn("equeued "+callback.id+", current queque length="+self.requestQueue.length); - self.tryNextRequest(); - }, - - dispatchQueue : function() - { - var self = Prado.CallbackRequest; - //Logger.warn("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); - var callback = self.requestQueue.shift(); - self.currentRequest = callback; - - //get data - callback.options.postBody = callback._getPostData(), - - callback.request = new Ajax.Request(callback.url, callback.options); - callback.timeout = setTimeout(function() - { - //Logger.warn("priority timeout"); - self.abortRequest(callback.id); - },callback.options.RequestTimeOut); - //Logger.debug("dispatched "+self.currentRequest.id + " ...") - }, - - endCurrentRequest : function() - { - var self = Prado.CallbackRequest; - clearTimeout(self.currentRequest.timeout); - self.currentRequest=null; - }, - - abortRequest : function(id) - { - //Logger.warn("abort id="+id); - var self = Prado.CallbackRequest; - if(typeof(self.currentRequest) != 'undefined' - && self.currentRequest != null && self.currentRequest.id == id) - { - var request = self.currentRequest.request; - if(request.transport.readyState < 4) - request.transport.abort(); - //Logger.warn('## aborted: setting current request to null'); - self.endCurrentRequest(); - } - self.tryNextRequest(); - } -}) - -/** - * Automatically aborts the current request when a priority request has returned. - */ -Ajax.Responders.register({onComplete : function(request) -{ - if(request.options.HasPriority) - Prado.CallbackRequest.tryNextRequest(); -}}); - -//Add HTTP exception respones when logger is enabled. -Event.OnLoad(function() -{ - if(typeof Logger != "undefined") - Ajax.Responders.register(Prado.CallbackRequest.Exception); -}); - -/** - * Create and prepare a new callback request. - * Call the dispatch() method to start the callback request. - * - * request = new Prado.CallbackRequest(UniqueID, callback); - * request.dispatch(); - * - */ -Prado.CallbackRequest.prototype = -{ - - /** - * Prepare and inititate a callback request. - */ - initialize : function(id, options) - { - /** - * Callback URL, same url as the current page. - */ - this.url = this.getCallbackUrl(); - - /** - * Current callback request. - */ - this.request = null; - - this.Enabled = true; - - this.id = id; - if(typeof(id)=="string") - Prado.CallbackRequest.requests[id] = this; - - this.options = Object.extend( - { - RequestTimeOut : 30000, // 30 second timeout. - EnablePageStateUpdate : true, - HasPriority : true, - CausesValidation : true, - ValidationGroup : null, - PostInputs : true - }, options || {}); - }, - - /** - * Gets the url from the forms that contains the PRADO_PAGESTATE - * @return {String} callback url. - */ - getCallbackUrl : function() - { - return $('PRADO_PAGESTATE').form.action; - }, - - /** - * Sets the request parameter - * @param {Object} parameter value - */ - setCallbackParameter : function(value) - { - this.options['params'] = value; - }, - - /** - * @return {Object} request paramater value. - */ - getCallbackParameter : function() - { - return this.options['params']; - }, - - /** - * Sets the callback request timeout. - * @param {integer} timeout in milliseconds - */ - setRequestTimeOut : function(timeout) - { - this.options['RequestTimeOut'] = timeout; - }, - - /** - * @return {integer} request timeout in milliseconds - */ - getRequestTimeOut : function() - { - return this.options['RequestTimeOut']; - }, - - /** - * Set true to enable validation on callback dispatch. - * @param {boolean} true to validate - */ - setCausesValidation : function(validate) - { - 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; - }, - - /** - * @return {string} validation group name. - */ - getValidationGroup : function() - { - return this.options['ValidationGroup']; - }, - - /** - * Dispatch the callback request. - */ - dispatch : function() - { - //Logger.info("dispatching request"); - //trigger tinyMCE to save data. - if(typeof tinyMCE != "undefined") - tinyMCE.triggerSave(); - - //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; - } - - if(this.options.onPreDispatch) - this.options.onPreDispatch(this,null); - - if(!this.Enabled) - return; - - if(this.options.HasPriority) - { - return Prado.CallbackRequest.enqueue(this); - //return Prado.CallbackRequest.dispatchPriorityRequest(this); - } - else - return Prado.CallbackRequest.dispatchNormalRequest(this); - }, - - abort : function() - { - return Prado.CallbackRequest.abortRequest(this.id); - }, - - /** - * 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" && value != null) - 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(); - } -} - -/** - * 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(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; -} diff --git a/framework/Web/Javascripts/prado/inlineeditor.js b/framework/Web/Javascripts/prado/inlineeditor.js deleted file mode 100644 index c73985f7..00000000 --- a/framework/Web/Javascripts/prado/inlineeditor.js +++ /dev/null @@ -1,267 +0,0 @@ -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); - Prado.WebUI.TInPlaceTextBox.register(this); - this.createEditorInput(); - 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 || 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; - }, - - exitEditMode : function(evt) - { - this.isEditing = false; - this.isSaving = false; - this.editField.disabled = false; - this.element.innerHTML = this.editField.value; - this.showLabel(); - }, - - showTextBox : function() - { - Element.hide(this.element); - Element.show(this.editField); - }, - - showLabel : function() - { - Element.show(this.element); - Element.hide(this.editField); - }, - - /** - * Create the edit input field. - */ - 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.setCallbackParameter(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') - { - 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)); - }, - - /** - * @return {String} panel inner html text. - */ - getText: function() - { - return this.element.innerHTML; - }, - - /** - * Edit mode entered, calls optional event handlers. - */ - 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(); - } - }, - - /** - * When the text input value has changed. - * @param {String} original text - */ - onTextChanged : function(text) - { - request = new Prado.CallbackRequest(this.options.EventTarget, this.options); - request.setCallbackParameter(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; - } - }, - - /** - * When loading external text. - */ - onLoadingText : function() - { - //Logger.info("on loading text"); - }, - - onloadExternalTextSuccess : function(request, parameter) - { - this.isEditing = true; - this.editField.disabled = false; - this.editField.value = this.getText(); - Prado.Element.focus(this.editField); - if(typeof(this.options.onSuccess)=="function") - this.options.onSuccess(sender,parameter); - }, - - onloadExternalTextFailure : function(request, parameter) - { - this.isSaving = false; - this.isEditing = false; - this.showLabel(); - if(typeof(this.options.onFailure)=="function") - this.options.onFailure(sender,parameter); - }, - - /** - * 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; - if(typeof(this.options.onSuccess)=="function") - this.options.onSuccess(sender,parameter); - }, - - onTextChangedFailure : function(sender, parameter) - { - this.editField.disabled = false; - this.isSaving = false; - this.isEditing = false; - if(typeof(this.options.onFailure)=="function") - this.options.onFailure(sender,parameter); - } -}, -{ - textboxes : {}, - - register : function(obj) - { - Prado.WebUI.TInPlaceTextBox.textboxes[obj.options.TextBoxID] = obj; - }, - - setDisplayTextBox : function(id,value) - { - var textbox = Prado.WebUI.TInPlaceTextBox.textboxes[id]; - if(textbox) - { - if(value) - textbox.enterEditMode(null); - else - { - textbox.exitEditMode(null); - } - } - } -}); \ No newline at end of file diff --git a/framework/Web/Javascripts/prado/scriptaculous-adapter.js b/framework/Web/Javascripts/prado/scriptaculous-adapter.js index 89e6710b..f7971884 100644 --- a/framework/Web/Javascripts/prado/scriptaculous-adapter.js +++ b/framework/Web/Javascripts/prado/scriptaculous-adapter.js @@ -177,9 +177,6 @@ Prado.PostBack = function(event,options) Event.fireEvent(form,"submit"); } -/** - * Additional element utilities. - */ Prado.Element = { /** @@ -194,15 +191,16 @@ 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; + if(!el) return; 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) @@ -215,8 +213,21 @@ Prado.Element = setAttribute : function(element, attribute, value) { var el = $(element); - if(attribute == "disabled" && value==false) + if(!el) return; + 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); }, @@ -224,12 +235,12 @@ Prado.Element = setOptions : function(element, options) { var el = $(element); + if(!el) return; if(el && el.tagName.toLowerCase() == "select") { - while(el.length > 0) - el.remove(0); + el.options.length = options.length; for(var i = 0; i)([\\s\\S\\w\\W]*)()',"m"); + var result = text.match(f); + if(result && result.length >= 2) + return result[2]; + else + return null; + }, + + evaluateScript : function(content) + { + content.evalScripts(); } } -/** - * Selectable element utilities - */ 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()) @@ -261,61 +320,125 @@ Prado.Element.Selection = } }, - 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) { - for(var i = 0; i * options['FormID']* The ID of HTML form to manage. @@ -156,6 +174,11 @@ Prado.ValidationManager.prototype = */ initialize : function(options) { + this.validators = []; // list of validators + this.summaries = []; // validation summaries + this.groups = []; // validation groups + this.options = {}; + this.options = options; Prado.Validation.managers[options.FormID] = this; }, @@ -333,11 +356,6 @@ Prado.ValidationManager.prototype = Prado.WebUI.TValidationSummary = Class.create(); Prado.WebUI.TValidationSummary.prototype = { - group : null, - options : {}, - visible : false, - messages : null, - /** * * options['ID']* Validation summary ID, i.e., an HTML element ID @@ -357,9 +375,12 @@ Prado.WebUI.TValidationSummary.prototype = this.options = options; this.group = options.ValidationGroup; this.messages = $(options.ID); - this.visible = this.messages.style.visibility != "hidden" - this.visible = this.visible && this.messages.style.display != "none"; - Prado.Validation.addSummary(options.FormID, this); + if(this.messages) + { + this.visible = this.messages.style.visibility != "hidden" + this.visible = this.visible && this.messages.style.display != "none"; + Prado.Validation.addSummary(options.FormID, this); + } }, /** @@ -540,15 +561,6 @@ Prado.WebUI.TValidationSummary.prototype = Prado.WebUI.TBaseValidator = Class.create(); Prado.WebUI.TBaseValidator.prototype = { - enabled : true, - visible : false, - isValid : true, - options : {}, - _isObserving : {}, - group : null, - manager : null, - message : null, - /** * * options['ID']* Validator ID, e.g. span with message @@ -561,8 +573,8 @@ Prado.WebUI.TBaseValidator.prototype = * options['ValidationGroup'] Validation group * options['ControlCssClass'] Css class to use on the input upon error * options['OnValidate'] Function to call immediately after validation - * options['OnSuccess'] Function to call upon after successful validation - * options['OnError'] Function to call upon after error in validation. + * options['OnValidationSuccess'] Function to call upon after successful validation + * options['OnValidationError'] Function to call upon after error in validation. * options['ObserveChanges'] True to observe changes in input * */ @@ -572,12 +584,23 @@ Prado.WebUI.TBaseValidator.prototype = options.OnSuccess = options.OnSuccess || Prototype.emptyFunction; options.OnError = options.OnError || Prototype.emptyFunction; */ + + this.enabled = true; + this.visible = false; + this.isValid = true; + this._isObserving = {}; + this.group = null; + this.requestDispatched = false; + this.options = options; this.control = $(options.ControlToValidate); this.message = $(options.ID); - this.group = options.ValidationGroup; + if(this.control && this.message) + { + this.group = options.ValidationGroup; - this.manager = Prado.Validation.addValidator(options.FormID, this); + this.manager = Prado.Validation.addValidator(options.FormID, this); + } }, /** @@ -599,6 +622,8 @@ Prado.WebUI.TBaseValidator.prototype = if(this.options.FocusOnError && !this.isValid ) Prado.Element.focus(this.options.FocusElementID); + + this.visible = true; }, refreshControlAndMessage : function() @@ -650,8 +675,21 @@ 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); + { + if(this.requestDispatched == false) + this.options.OnValidate(this, invoker); + } if(this.enabled) this.isValid = this.evaluateIsValid(); @@ -660,20 +698,26 @@ Prado.WebUI.TBaseValidator.prototype = if(this.isValid) { - if(typeof(this.options.OnSuccess) == "function") + if(typeof(this.options.OnValidationSuccess) == "function") { - this.refreshControlAndMessage(); - this.options.OnSuccess(this, invoker); + if(this.requestDispatched == false) + { + this.refreshControlAndMessage(); + this.options.OnValidationSuccess(this, invoker); + } } else this.updateControl(); } else { - if(typeof(this.options.OnError) == "function") + if(typeof(this.options.OnValidationError) == "function") { - this.refreshControlAndMessage(); - this.options.OnError(this, invoker); + if(this.requestDispatched == false) + { + this.refreshControlAndMessage(); + this.options.OnValidationError(this, invoker) + } } else this.updateControl(); @@ -1080,6 +1124,51 @@ Prado.WebUI.TCustomValidator = Class.extend(Prado.WebUI.TBaseValidator, } }); +/** + * Uses callback request to perform validation. + */ +Prado.WebUI.TActiveCustomValidator = Class.extend(Prado.WebUI.TBaseValidator, +{ + validatingValue : null, + + /** + * Calls custom validation function. + */ + evaluateIsValid : function() + { + value = this.getValidationValue(); + if(!this.requestDispatched && value != this.validatingValue) + { + this.validatingValue = value; + request = new Prado.CallbackRequest(this.options.EventTarget, this.options); + request.setCallbackParameter(value); + request.setCausesValidation(false); + request.options.onSuccess = this.callbackOnSuccess.bind(this); + request.options.onFailure = this.callbackOnFailure.bind(this); + request.dispatch(); + this.requestDispatched = true; + return false; + } + return this.isValid; + }, + + callbackOnSuccess : function(request, data) + { + this.isValid = data; + this.requestDispatched = false; + if(typeof(this.options.onSuccess) == "function") + this.options.onSuccess(request,data); + Prado.Validation.validate(this.options.FormID, this.group,null); + }, + + callbackOnFailure : function(request, data) + { + this.requestDispatched = false; + if(typeof(this.options.onFailure) == "function") + this.options.onFailure(request,data); + } +}); + /** * TRangeValidator tests whether an input value is within a specified range. * @@ -1273,4 +1362,3 @@ Prado.WebUI.TDataTypeValidator = Class.extend(Prado.WebUI.TBaseValidator, return this.convert(this.options.DataType, value) != null; } }); - diff --git a/framework/Web/Javascripts/scriptaculous/builder.js b/framework/Web/Javascripts/scriptaculous/builder.js index 199afc12..c110e0c7 100644 --- a/framework/Web/Javascripts/scriptaculous/builder.js +++ b/framework/Web/Javascripts/scriptaculous/builder.js @@ -1,6 +1,6 @@ -// script.aculo.us builder.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 +// script.aculo.us builder.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007 -// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ @@ -48,7 +48,8 @@ var Builder = { // attributes (or text) if(arguments[1]) if(this._isStringOrNumber(arguments[1]) || - (arguments[1] instanceof Array)) { + (arguments[1] instanceof Array) || + arguments[1].tagName) { this._children(element, arguments[1]); } else { var attrs = this._attributes(arguments[1]); @@ -66,7 +67,7 @@ var Builder = { } if(element.tagName.toUpperCase() != elementName) element = parentElement.getElementsByTagName(elementName)[0]; - } + } } // text, or array of children @@ -92,6 +93,10 @@ var Builder = { return attrs.join(" "); }, _children: function(element, children) { + if(children.tagName) { + element.appendChild(children); + return; + } if(typeof children=='object') { // array can hold nodes and text children.flatten().each( function(e) { if(typeof e=='object') @@ -101,8 +106,8 @@ var Builder = { element.appendChild(Builder._text(e)); }); } else - if(Builder._isStringOrNumber(children)) - element.appendChild(Builder._text(children)); + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); }, _isStringOrNumber: function(param) { return(typeof param=='string' || typeof param=='number'); diff --git a/framework/Web/Javascripts/scriptaculous/controls.js b/framework/Web/Javascripts/scriptaculous/controls.js index 46f2cc18..bbd00d69 100644 --- a/framework/Web/Javascripts/scriptaculous/controls.js +++ b/framework/Web/Javascripts/scriptaculous/controls.js @@ -1,8 +1,8 @@ -// script.aculo.us controls.js v1.7.0, Fri Jan 19 19:16:36 CET 2007 +// script.aculo.us controls.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007 -// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com) +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) // Contributors: // Richard Livsey // Rahul Bhargava @@ -90,8 +90,7 @@ Autocompleter.Base.prototype = { show: function() { if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); if(!this.iefix && - (navigator.appVersion.indexOf('MSIE')>0) && - (navigator.userAgent.indexOf('Opera')<0) && + (Prototype.Browser.IE) && (Element.getStyle(this.update, 'position')=='absolute')) { new Insertion.After(this.update, '