From 295150b5e9c55794f9b2964ce0fe8f62ca4bd52c Mon Sep 17 00:00:00 2001 From: Musachy Barroso Date: Sun, 22 Jun 2008 15:28:01 +0000 Subject: [PATCH] WW-2601 Tabindex not working on autocompleter also fixed tabindex for datepicker git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@670371 13f79535-47bb-0310-9956-ffa450edef68 --- .../static/dojo/struts/widget/ComboBox.js | 7 + .../dojo/struts/widget/StrutsDatePicker.js | 22 +- .../dojo/struts/widget/StrutsTimePicker.js | 25 +- .../apache/struts2/static/dojo/struts_dojo.js | 5165 ++++++++- .../dojo/struts_dojo.js.uncompressed.js | 9286 ++++++++++++++++- plugins/dojo/src/profile/struts.profile.js | 2 +- 6 files changed, 14477 insertions(+), 30 deletions(-) diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js index 4217efc1a..77521c348 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js @@ -279,6 +279,8 @@ dojo.widget.defineWidget( //load options when page loads preload : true, + tabIndex: "", + //from Dojo's ComboBox showResultList: function() { // Our dear friend IE doesnt take max-height so we need to calculate that on our own every time @@ -418,6 +420,11 @@ dojo.widget.defineWidget( this.comboBoxSelectionValue.value = this.initialKey; this.textInputNode.value = this.initialValue; + //tabindex + if(!dojo.string.isBlank(this.tabIndex)) { + this.textInputNode.tabIndex = this.tabIndex; + } + //hide arrow? if(!this.visibleDownArrow) { dojo.html.hide(this.downArrowNode); diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsDatePicker.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsDatePicker.js index f6e86c8b2..78d3d87e9 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsDatePicker.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsDatePicker.js @@ -29,26 +29,32 @@ dojo.widget.defineWidget( valueNotifyTopics : "", valueNotifyTopicsArray : null, - + tabIndex : "", + postCreate: function() { struts.widget.StrutsDatePicker.superclass.postCreate.apply(this, arguments); - + //set cssClass if(this.extraArgs["class"]) { dojo.html.setClass(this.inputNode, this.extraArgs["class"]); - } - + } + //set cssStyle if(this.extraArgs.style) { dojo.html.setStyleText(this.inputNode, this.extraArgs.style); - } - + } + //value topics if(!dojo.string.isBlank(this.valueNotifyTopics)) { this.valueNotifyTopicsArray = this.valueNotifyTopics.split(","); } + + //tabindex + if(!dojo.string.isBlank(this.tabIndex)) { + this.inputNode.tabIndex = this.tabIndex; + } }, - + _syncValueNode:function () { var date = this.datePicker.value; var value = ""; @@ -69,7 +75,7 @@ dojo.widget.defineWidget( } this.valueNode.value = value; }, - + _updateText : function() { struts.widget.StrutsDatePicker.superclass._updateText.apply(this, arguments); if(this.valueNotifyTopicsArray != null) { diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsTimePicker.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsTimePicker.js index d01fcd942..3892a1f95 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsTimePicker.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/widget/StrutsTimePicker.js @@ -33,29 +33,36 @@ dojo.widget.defineWidget( inputName: "", name: "", - + valueNotifyTopics : "", valueNotifyTopicsArray : null, - + + tabIndex : "", + postCreate: function() { struts.widget.StrutsTimePicker.superclass.postCreate.apply(this, arguments); - + //set cssClass if(this.extraArgs["class"]) { dojo.html.setClass(this.inputNode, this.extraArgs["class"]); - } - + } + //set cssStyle if(this.extraArgs.style) { dojo.html.setStyleText(this.inputNode, this.extraArgs.style); - } - + } + //value topics if(!dojo.string.isBlank(this.valueNotifyTopics)) { this.valueNotifyTopicsArray = this.valueNotifyTopics.split(","); } + + //tabindex + if(!dojo.string.isBlank(this.tabIndex)) { + this.inputNode.tabIndex = this.tabIndex; + } }, - + _syncValueNode:function () { var time = this.timePicker.time; var value; @@ -75,7 +82,7 @@ dojo.widget.defineWidget( } this.valueNode.value = value; }, - + _updateText : function() { struts.widget.StrutsTimePicker.superclass._updateText.apply(this, arguments); if(this.valueNotifyTopicsArray != null) { diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js index 20766a736..cd33f3659 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js @@ -482,7 +482,7 @@ break; } } }; -dojo.hostenv.localesGenerated; +dojo.hostenv.localesGenerated=["ROOT","es-es","es","it-it","pt-br","de","fr-fr","zh-cn","pt","en-us","zh","fr","zh-tw","it","en-gb","xx","de-de","ko-kr","ja-jp","ko","en","ja"]; dojo.hostenv.registerNlsPrefix=function(){ dojo.registerModulePath("nls","nls"); }; @@ -13628,4 +13628,5167 @@ self.addKeyHandler(item[1]?item[1]:item[0].charAt(0),item[2]==undefined?self.KEY } }); }}); +dojo.provide("struts.widget.Bind"); +dojo.widget.defineWidget("struts.widget.Bind",dojo.widget.HtmlWidget,{widgetType:"Bind",executeScripts:false,scriptSeparation:false,targets:"",targetsArray:null,href:"",handler:"",loadingText:"Loading...",errorText:"",showError:true,showLoading:false,listenTopics:"",notifyTopics:"",notifyTopicsArray:null,beforeNotifyTopics:"",beforeNotifyTopicsArray:null,afterNotifyTopics:"",afterNotifyTopicsArray:null,errorNotifyTopics:"",errorNotifyTopicsArray:null,formId:"",formFilter:"",formNode:null,events:"",indicator:"",parseContent:true,highlightColor:"",highlightDuration:2000,validate:false,ajaxAfterValidation:false,cacheContent:true,scriptSeparation:true,scriptScope:null,transport:"",postCreate:function(){ +var self=this; +if(!dojo.string.isBlank(this.listenTopics)){ +this.log("Listening to "+this.listenTopics+" to refresh"); +var _b7b=this.listenTopics.split(","); +if(_b7b){ +dojo.lang.forEach(_b7b,function(_b7c){ +dojo.event.topic.subscribe(_b7c,self,"reloadContents"); +}); +} +} +if(!dojo.string.isBlank(this.notifyTopics)){ +this.notifyTopicsArray=this.notifyTopics.split(","); +} +if(!dojo.string.isBlank(this.beforeNotifyTopics)){ +this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.afterNotifyTopics)){ +this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.errorNotifyTopics)){ +this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.targets)){ +this.targetsArray=this.targets.split(","); +} +if(!dojo.string.isBlank(this.events)){ +var _b7d=this.events.split(","); +if(_b7d&&this.domNode){ +dojo.lang.forEach(_b7d,function(_b7e){ +dojo.event.connect(self.domNode,_b7e,function(evt){ +evt.preventDefault(); +evt.stopPropagation(); +self.reloadContents(); +}); +}); +} +} +if(dojo.string.isBlank(this.formId)){ +this.formNode=dojo.dom.getFirstAncestorByTag(this.domNode,"form"); +}else{ +this.formNode=dojo.byId(this.formId); +} +if(this.formNode&&dojo.string.isBlank(this.href)){ +this.href=this.formNode.action; +} +},highlight:function(){ +if(!dojo.string.isBlank(this.highlightColor)){ +var _b80=[]; +dojo.lang.forEach(this.targetsArray,function(_b81){ +var node=dojo.byId(_b81); +if(node){ +_b80.push(node); +} +}); +var _b83=dojo.lfx.html.highlight(_b80,this.highlightColor,this.highlightDuration); +_b83.play(); +} +},log:function(text){ +dojo.debug("["+(this.widgetId?this.widgetId:"unknown")+"] "+text); +},setContent:function(text){ +if(this.targetsArray){ +var self=this; +var _b87=new dojo.xml.Parse(); +dojo.lang.forEach(this.targetsArray,function(_b88){ +var node=dojo.byId(_b88); +if(node){ +node.innerHTML=text; +if(self.parseContent&&text!=self.loadingText){ +var frag=_b87.parseElement(node,null,true); +dojo.widget.getParser().createSubComponents(frag,dojo.widget.byId(_b88)); +} +}else{ +self.log("Unable to find target: "+node); +} +}); +} +},bindHandler:function(type,data,e){ +dojo.html.hide(this.indicator); +this.notify(data,type,e); +if(type=="load"){ +if(this.validate){ +StrutsUtils.clearValidationErrors(this.formNode); +var _b8e=StrutsUtils.getValidationErrors(data); +if(_b8e&&_b8e.fieldErrors){ +StrutsUtils.showValidationErrors(this.formNode,_b8e); +return; +}else{ +if(!this.ajaxAfterValidation&&this.formNode){ +this.formNode.submit(); +return; +} +} +} +if(this.executeScripts){ +var _b8f=this.parse(data); +this.setContent(_b8f.text); +this._executeScripts(_b8f.scripts); +}else{ +this.setContent(data); +} +this.highlight(); +}else{ +if(this.showError){ +var _b90=dojo.string.isBlank(this.errorText)?e.message:this.errorText; +this.setContent(_b90); +} +} +},notify:function(data,type,e){ +var self=this; +if(this.notifyTopicsArray){ +dojo.lang.forEach(this.notifyTopicsArray,function(_b95){ +try{ +dojo.event.topic.publish(_b95,data,type,e,self); +} +catch(ex){ +self.log(ex); +} +}); +} +var _b96=null; +switch(type){ +case "before": +this.notifyTo(this.beforeNotifyTopicsArray,null,e); +break; +case "load": +this.notifyTo(this.afterNotifyTopicsArray,data,e); +break; +case "error": +this.notifyTo(this.errorNotifyTopicsArray,data,e); +break; +} +},notifyTo:function(_b97,data,e){ +var self=this; +if(_b97){ +dojo.lang.forEach(_b97,function(_b9b){ +try{ +if(data!=null){ +dojo.event.topic.publish(_b9b,data,e,self); +}else{ +dojo.event.topic.publish(_b9b,e,self); +} +} +catch(ex){ +self.log(ex); +} +}); +} +},onDownloadStart:function(_b9c){ +if(this.showLoading&&!dojo.string.isBlank(this.loadingText)){ +_b9c.text=this.loadingText; +} +},reloadContents:function(evt){ +if(!dojo.string.isBlank(this.handler)){ +this.log("Invoking handler: "+this.handler); +window[this.handler](this,this.domNode); +}else{ +try{ +var self=this; +var _b9f={cancel:false}; +this.notify(this.widgetId,"before",_b9f); +if(_b9f.cancel){ +this.log("Request canceled"); +return; +} +if(dojo.string.isBlank(this.href)){ +return; +} +if(!this.validate&&this.formNode&&this.formNode.onsubmit!=null){ +var _ba0=this.formNode.onsubmit.call(evt); +if(_ba0!=null&&!_ba0){ +this.log("Request canceled by 'onsubmit' of the form"); +return; +} +} +dojo.html.show(this.indicator); +if(this.showLoading){ +this.setContent(this.loadingText); +} +var _ba1=this.href; +_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+"struts.enableJSONValidation=true"; +if(!this.ajaxAfterValidation&&this.validate){ +_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+"struts.validateOnly=true"; +} +if(dojo.dom.isTag(this.domNode,"INPUT","input")&&this.events=="onclick"&&this.domNode.type=="submit"&&!dojo.string.isBlank(this.domNode.name)&&!dojo.string.isBlank(this.domNode.value)){ +var enc=/utf/i.test("")?encodeURIComponent:dojo.string.encodeAscii; +_ba1=_ba1+(_ba1.indexOf("?")>-1?"&":"?")+enc(this.domNode.name)+"="+enc(this.domNode.value); +} +dojo.io.bind({url:_ba1,useCache:false,preventCache:true,formNode:self.formNode,formFilter:window[self.formFilter],transport:self.transport,handler:function(type,data,e){ +dojo.lang.hitch(self,"bindHandler")(type,data,e); +},mimetype:"text/html"}); +} +catch(ex){ +if(this.showError){ +var _ba6=dojo.string.isBlank(this.errorText)?ex:this.errorText; +this.setContent(_ba6); +} +} +} +},parse:function(s){ +this.log("Parsing: "+s); +var _ba8=[]; +var tmp=[]; +var _baa=[]; +while(_ba8){ +_ba8=s.match(/]*)>([\s\S]*?)<\/script>/i); +if(!_ba8){ +break; +} +if(_ba8[1]){ +attr=_ba8[1].match(/src=(['"]?)([^"']*)\1/i); +if(attr){ +var tmp2=attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/); +if(tmp2>-1){ +this.log("Security note! inhibit:"+attr[2]+" from beeing loaded again."); +} +} +} +if(_ba8[2]){ +var sc=_ba8[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g,""); +if(!sc){ +continue; +} +tmp=[]; +while(tmp){ +tmp=sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/); +if(!tmp){ +break; +} +sc=sc.replace(tmp[0],""); +} +_baa.push(sc); +} +s=s.replace(/]*>[\s\S]*?<\/script>/i,""); +} +return {text:s,scripts:_baa}; +},_executeScripts:function(_bad){ +var self=this; +var tmp="",code=""; +for(var i=0;i<_bad.length;i++){ +if(_bad[i].path){ +dojo.io.bind(this._cacheSetting({"url":_bad[i].path,"load":function(type,_bb3){ +dojo.lang.hitch(self,tmp=";"+_bb3); +},"error":function(type,_bb5){ +_bb5.text=type+" downloading remote script"; +self._handleDefaults.call(self,_bb5,"onExecError","debug"); +},"mimetype":"text/plain","sync":true},this.cacheContent)); +code+=tmp; +}else{ +code+=_bad[i]; +} +} +try{ +if(this.scriptSeparation){ +delete this.scriptScope; +this.scriptScope=new (new Function("_container_",code+"; return this;"))(self); +}else{ +var djg=dojo.global(); +if(djg.execScript){ +djg.execScript(code); +}else{ +var djd=dojo.doc(); +var sc=djd.createElement("script"); +sc.appendChild(djd.createTextNode(code)); +(this.containerNode||this.domNode).appendChild(sc); +} +} +} +catch(e){ +e.text="Error running scripts from content:\n"+e.description; +this.log(e); +} +},_cacheSetting:function(_bb9,_bba){ +for(var x in this.bindArgs){ +if(dojo.lang.isUndefined(_bb9[x])){ +_bb9[x]=this.bindArgs[x]; +} +} +if(dojo.lang.isUndefined(_bb9.useCache)){ +_bb9.useCache=_bba; +} +if(dojo.lang.isUndefined(_bb9.preventCache)){ +_bb9.preventCache=!_bba; +} +if(dojo.lang.isUndefined(_bb9.mimetype)){ +_bb9.mimetype="text/html"; +} +return _bb9; +}}); +dojo.provide("dojo.lang.timing.Timer"); +dojo.lang.timing.Timer=function(_bbc){ +this.timer=null; +this.isRunning=false; +this.interval=_bbc; +this.onStart=null; +this.onStop=null; +}; +dojo.extend(dojo.lang.timing.Timer,{onTick:function(){ +},setInterval:function(_bbd){ +if(this.isRunning){ +dj_global.clearInterval(this.timer); +} +this.interval=_bbd; +if(this.isRunning){ +this.timer=dj_global.setInterval(dojo.lang.hitch(this,"onTick"),this.interval); +} +},start:function(){ +if(typeof this.onStart=="function"){ +this.onStart(); +} +this.isRunning=true; +this.timer=dj_global.setInterval(dojo.lang.hitch(this,"onTick"),this.interval); +},stop:function(){ +if(typeof this.onStop=="function"){ +this.onStop(); +} +this.isRunning=false; +dj_global.clearInterval(this.timer); +}}); +dojo.provide("struts.widget.BindDiv"); +dojo.widget.defineWidget("struts.widget.BindDiv",dojo.widget.ContentPane,{widgetType:"BindDiv",href:"",extractContent:false,parseContent:false,cacheContent:false,refreshOnShow:false,executeScripts:false,preload:true,updateFreq:0,delay:0,autoStart:true,timer:null,loadingText:"Loading...",showLoading:false,errorText:"",showError:true,listenTopics:"",notifyTopics:"",notifyTopicsArray:null,stopTimerListenTopics:"",startTimerListenTopics:"",beforeNotifyTopics:"",beforeNotifyTopicsArray:null,afterNotifyTopics:"",afterNotifyTopicsArray:null,errorNotifyTopics:"",errorNotifyTopicsArray:null,beforeLoading:"",afterLoading:"",formId:"",formFilter:"",indicator:"",parseContent:true,highlightColor:"",highlightDuration:2000,disabled:false,transport:"",onDownloadStart:function(_bbe){ +if(!this.showLoading){ +_bbe.returnValue=false; +return; +} +if(this.showLoading&&!dojo.string.isBlank(this.loadingText)){ +_bbe.text=this.loadingText; +} +},highlight:function(){ +if(!dojo.string.isBlank(this.highlightColor)){ +var _bbf=dojo.lfx.html.highlight([this.domNode],this.highlightColor,this.highlightDuration); +_bbf.play(); +} +},onDownloadError:function(_bc0){ +this.onError(_bc0); +},onContentError:function(_bc1){ +this.onError(_bc1); +},onExecError:function(_bc2){ +this.onError(_bc2); +},onError:function(_bc3){ +if(this.showError){ +if(!dojo.string.isBlank(this.errorText)){ +_bc3.text=this.errorText; +} +}else{ +_bc3.text=""; +} +},notify:function(data,type,e){ +if(this.notifyTopicsArray){ +var self=this; +dojo.lang.forEach(this.notifyTopicsArray,function(_bc8){ +try{ +dojo.event.topic.publish(_bc8,data,type,e,self); +} +catch(ex){ +self.log(ex); +} +}); +} +var _bc9=null; +switch(type){ +case "before": +this.notifyTo(this.beforeNotifyTopicsArray,null,e); +break; +case "load": +this.notifyTo(this.afterNotifyTopicsArray,data,e); +break; +case "error": +this.notifyTo(this.errorNotifyTopicsArray,data,e); +break; +} +},notifyTo:function(_bca,data,e){ +var self=this; +if(_bca){ +dojo.lang.forEach(_bca,function(_bce){ +try{ +if(data!=null){ +dojo.event.topic.publish(_bce,data,e,self); +}else{ +dojo.event.topic.publish(_bce,e,self); +} +} +catch(ex){ +self.log(ex); +} +}); +} +},postCreate:function(args,frag){ +if(this.handler!==""){ +this.setHandler(this.handler); +} +var self=this; +var _bd2=function(){ +dojo.lang.hitch(self,"refresh")(); +}; +var _bd3=function(){ +dojo.lang.hitch(self,"startTimer")(); +}; +if(this.updateFreq>0){ +this.timer=new dojo.lang.timing.Timer(this.updateFreq); +this.timer.onTick=_bd2; +if(this.autoStart){ +if(this.delay>0){ +dojo.lang.setTimeout(_bd3,this.delay); +}else{ +this.startTimer(); +} +} +}else{ +if(this.delay>0){ +dojo.lang.setTimeout(_bd2,this.delay); +} +} +if(!dojo.string.isBlank(this.listenTopics)){ +this.log("Listening to "+this.listenTopics+" to refresh"); +var _bd4=this.listenTopics.split(","); +if(_bd4){ +dojo.lang.forEach(_bd4,function(_bd5){ +dojo.event.topic.subscribe(_bd5,self,"refresh"); +}); +} +} +if(!dojo.string.isBlank(this.stopTimerListenTopics)){ +this.log("Listening to "+this.stopTimerListenTopics+" to stop timer"); +var _bd6=this.stopTimerListenTopics.split(","); +if(_bd6){ +dojo.lang.forEach(_bd6,function(_bd7){ +dojo.event.topic.subscribe(_bd7,self,"stopTimer"); +}); +} +} +if(!dojo.string.isBlank(this.startTimerListenTopics)){ +this.log("Listening to "+this.stopTimerListenTopics+" to start timer"); +var _bd8=this.startTimerListenTopics.split(","); +if(_bd8){ +dojo.lang.forEach(_bd8,function(_bd9){ +dojo.event.topic.subscribe(_bd9,self,"startTimer"); +}); +} +} +if(!dojo.string.isBlank(this.notifyTopics)){ +this.notifyTopicsArray=this.notifyTopics.split(","); +} +if(!dojo.string.isBlank(this.beforeNotifyTopics)){ +this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.afterNotifyTopics)){ +this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.errorNotifyTopics)){ +this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); +} +if(this.isShowing()&&this.preload&&this.updateFreq<=0&&this.delay<=0){ +this.refresh(); +} +},_downloadExternalContent:function(url,_bdb){ +var _bdc={cancel:false}; +this.notify(this.widgetId,"before",_bdc); +if(_bdc.cancel){ +return; +} +dojo.html.show(this.indicator); +this._handleDefaults("Loading...","onDownloadStart"); +var self=this; +dojo.io.bind({url:url,useCache:_bdb,preventCache:!_bdb,mimetype:"text/html",formNode:dojo.byId(self.formId),formFilter:window[self.formFilter],transport:self.transport,handler:function(type,data,e){ +dojo.html.hide(self.indicator); +self.notify(data,type,e); +if(type=="load"){ +self.onDownloadEnd.call(self,url,data); +self.highlight(); +}else{ +self._handleDefaults.call(self,"Error loading '"+url+"' ("+e.status+" "+e.statusText+")","onDownloadError"); +self.onLoad(); +} +}}); +},log:function(text){ +dojo.debug("["+this.widgetId+"] "+text); +},stopTimer:function(){ +if(this.timer&&this.timer.isRunning){ +this.log("stopping timer"); +this.timer.stop(); +} +},startTimer:function(){ +if(this.timer&&!this.timer.isRunning){ +this.log("starting timer with update interval "+this.updateFreq); +this.timer.start(); +} +},splitAndFixPaths:function(s,url){ +var _be4=[],_be5=[],tmp=[]; +var _be7=[],_be8=[],attr=[],_bea=[]; +var str="",path="",fix="",_bee="",tag="",_bf0=""; +if(!url){ +url="./"; +} +if(s){ +var _bf1=/]*>([\s\S]*?)<\/title>/i; +while(_be7=_bf1.exec(s)){ +_be4.push(_be7[1]); +s=s.substring(0,_be7.index)+s.substr(_be7.index+_be7[0].length); +} +if(this.adjustPaths){ +var _bf2=/<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i; +var _bf3=/\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@!]+?)\2/i; +var _bf4=/^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/; +while(tag=_bf2.exec(s)){ +str+=s.substring(0,tag.index); +s=s.substring((tag.index+tag[0].length),s.length); +tag=tag[0]; +_bee=""; +while(attr=_bf3.exec(tag)){ +path=""; +_bf0=attr[3]; +switch(attr[1].toLowerCase()){ +case "src": +case "href": +if(_bf4.exec(_bf0)){ +path=_bf0; +}else{ +path=(new dojo.uri.Uri(url,_bf0).toString()); +} +break; +case "style": +path=dojo.html.fixPathsInCssText(_bf0,url); +break; +default: +path=_bf0; +} +fix=" "+attr[1]+"="+attr[2]+path+attr[2]; +_bee+=tag.substring(0,attr.index)+fix; +tag=tag.substring((attr.index+attr[0].length),tag.length); +} +str+=_bee+tag; +} +s=str+s; +} +_bf1=/(?:<(style)[^>]*>([\s\S]*?)<\/style>|]*rel=['"]?stylesheet['"]?[^>]*)>)/i; +while(_be7=_bf1.exec(s)){ +if(_be7[1]&&_be7[1].toLowerCase()=="style"){ +_bea.push(dojo.html.fixPathsInCssText(_be7[2],url)); +}else{ +if(attr=_be7[3].match(/href=(['"]?)([^'">]*)\1/i)){ +_bea.push({path:attr[2]}); +} +} +s=s.substring(0,_be7.index)+s.substr(_be7.index+_be7[0].length); +} +var _bf1=/]*)>([\s\S]*?)<\/script>/i; +var _bf5=/src=(['"]?)([^"']*)\1/i; +var _bf6=/.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/; +var _bf7=/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g; +var _bf8=/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix|registerModulePath)|defineNamespace)\((['"]).*?\1\)\s*;?/; +while(_be7=_bf1.exec(s)){ +if(this.executeScripts&&_be7[1]){ +if(attr=_bf5.exec(_be7[1])){ +if(_bf6.exec(attr[2])){ +dojo.debug("Security note! inhibit:"+attr[2]+" from being loaded again."); +}else{ +_be5.push({path:attr[2]}); +} +} +} +if(_be7[2]){ +var sc=_be7[2].replace(_bf7,""); +if(!sc){ +continue; +} +while(tmp=_bf8.exec(sc)){ +_be8.push(tmp[0]); +sc=sc.substring(0,tmp.index)+sc.substr(tmp.index+tmp[0].length); +} +if(this.executeScripts){ +_be5.push(sc); +} +} +s=s.substr(0,_be7.index)+s.substr(_be7.index+_be7[0].length); +} +if(this.extractContent){ +_be7=s.match(/]*>\s*([\s\S]+)\s*<\/body>/im); +if(_be7){ +s=_be7[1]; +} +} +if(this.executeScripts&&this.scriptSeparation){ +var _bf1=/(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*?\S=)((['"])[^>]*scriptScope[^>]*>)/; +var _bfa=/([\s'";:\(])scriptScope(.*)/; +str=""; +while(tag=_bf1.exec(s)){ +tmp=((tag[3]=="'")?"\"":"'"); +fix=""; +str+=s.substring(0,tag.index)+tag[1]; +while(attr=_bfa.exec(tag[2])){ +tag[2]=tag[2].substring(0,attr.index)+attr[1]+"dojo.widget.byId("+tmp+this.widgetId+tmp+").scriptScope"+attr[2]; +} +str+=tag[2]; +s=s.substr(tag.index+tag[0].length); +} +s=str+s; +} +} +return {"xml":s,"styles":_bea,"titles":_be4,"requires":_be8,"scripts":_be5,"url":url}; +}}); +dojo.provide("struts.widget.BindAnchor"); +dojo.widget.defineWidget("struts.widget.BindAnchor",struts.widget.Bind,{widgetType:"BindAnchor",events:"onclick",postCreate:function(){ +struts.widget.BindAnchor.superclass.postCreate.apply(this); +this.domNode.href="#"; +}}); +dojo.provide("dojo.widget.html.stabile"); +dojo.widget.html.stabile={_sqQuotables:new RegExp("([\\\\'])","g"),_depth:0,_recur:false,depthLimit:2}; +dojo.widget.html.stabile.getState=function(id){ +dojo.widget.html.stabile.setup(); +return dojo.widget.html.stabile.widgetState[id]; +}; +dojo.widget.html.stabile.setState=function(id,_bfd,_bfe){ +dojo.widget.html.stabile.setup(); +dojo.widget.html.stabile.widgetState[id]=_bfd; +if(_bfe){ +dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState); +} +}; +dojo.widget.html.stabile.setup=function(){ +if(!dojo.widget.html.stabile.widgetState){ +var text=dojo.widget.html.stabile._getStorage().value; +dojo.widget.html.stabile.widgetState=text?dj_eval("("+text+")"):{}; +} +}; +dojo.widget.html.stabile.commit=function(_c00){ +dojo.widget.html.stabile._getStorage().value=dojo.widget.html.stabile.description(_c00); +}; +dojo.widget.html.stabile.description=function(v,_c02){ +var _c03=dojo.widget.html.stabile._depth; +var _c04=function(){ +return this.description(this,true); +}; +try{ +if(v===void (0)){ +return "undefined"; +} +if(v===null){ +return "null"; +} +if(typeof (v)=="boolean"||typeof (v)=="number"||v instanceof Boolean||v instanceof Number){ +return v.toString(); +} +if(typeof (v)=="string"||v instanceof String){ +var v1=v.replace(dojo.widget.html.stabile._sqQuotables,"\\$1"); +v1=v1.replace(/\n/g,"\\n"); +v1=v1.replace(/\r/g,"\\r"); +return "'"+v1+"'"; +} +if(v instanceof Date){ +return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")"; +} +var d; +if(v instanceof Array||v.push){ +if(_c03>=dojo.widget.html.stabile.depthLimit){ +return "[ ... ]"; +} +d="["; +var _c07=true; +dojo.widget.html.stabile._depth++; +for(var i=0;i=dojo.widget.html.stabile.depthLimit){ +return "{ ... }"; +} +if(typeof (v.hasOwnProperty)!="function"&&v.prototype){ +throw new Error("description: "+v+" not supported by script engine"); +} +var _c07=true; +d="{"; +dojo.widget.html.stabile._depth++; +for(var key in v){ +if(v[key]==void (0)||typeof (v[key])=="function"){ +continue; +} +if(_c07){ +_c07=false; +}else{ +d+=", "; +} +var kd=key; +if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){ +kd=arguments.callee(key,_c02); +} +d+=kd+": "+arguments.callee(v[key],_c02); +} +return d+"}"; +} +if(_c02){ +if(dojo.widget.html.stabile._recur){ +var _c0b=Object.prototype.toString; +return _c0b.apply(v,[]); +}else{ +dojo.widget.html.stabile._recur=true; +return v.toString(); +} +}else{ +throw new Error("Unknown type: "+v); +return "'unknown'"; +} +} +finally{ +dojo.widget.html.stabile._depth=_c03; +} +}; +dojo.widget.html.stabile._getStorage=function(){ +if(dojo.widget.html.stabile.dataField){ +return dojo.widget.html.stabile.dataField; +} +var form=document.forms._dojo_form; +return dojo.widget.html.stabile.dataField=form?form.stabile:{value:""}; +}; +dojo.provide("dojo.widget.ComboBox"); +dojo.declare("dojo.widget.incrementalComboBoxDataProvider",null,function(_c0d){ +this.searchUrl=_c0d.dataUrl; +this._cache={}; +this._inFlight=false; +this._lastRequest=null; +this.allowCache=false; +},{_addToCache:function(_c0e,data){ +if(this.allowCache){ +this._cache[_c0e]=data; +} +},startSearch:function(_c10,_c11){ +if(this._inFlight){ +} +var tss=encodeURIComponent(_c10); +var _c13=dojo.string.substituteParams(this.searchUrl,{"searchString":tss}); +var _c14=this; +var _c15=this._lastRequest=dojo.io.bind({url:_c13,method:"get",mimetype:"text/json",load:function(type,data,evt){ +_c14._inFlight=false; +if(!dojo.lang.isArray(data)){ +var _c19=[]; +for(var key in data){ +_c19.push([data[key],key]); +} +data=_c19; +} +_c14._addToCache(_c10,data); +if(_c15==_c14._lastRequest){ +_c11(data); +} +}}); +this._inFlight=true; +}}); +dojo.declare("dojo.widget.basicComboBoxDataProvider",null,function(_c1b,node){ +this._data=[]; +this.searchLimit=30; +this.searchType="STARTSTRING"; +this.caseSensitive=false; +if(!dj_undef("dataUrl",_c1b)&&!dojo.string.isBlank(_c1b.dataUrl)){ +this._getData(_c1b.dataUrl); +}else{ +if((node)&&(node.nodeName.toLowerCase()=="select")){ +var opts=node.getElementsByTagName("option"); +var ol=opts.length; +var data=[]; +for(var x=0;x0)&&(ret.length>=this.searchLimit)){ +break; +} +var _c30=new String((!this.caseSensitive)?this._data[x][0].toLowerCase():this._data[x][0]); +if(_c30.length<_c2b.length){ +continue; +} +if(st=="STARTSTRING"){ +if(_c2b==_c30.substr(0,_c2b.length)){ +ret.push(this._data[x]); +} +}else{ +if(st=="SUBSTRING"){ +if(_c30.indexOf(_c2b)>=0){ +ret.push(this._data[x]); +} +}else{ +if(st=="STARTWORD"){ +var idx=_c30.indexOf(_c2b); +if(idx==0){ +ret.push(this._data[x]); +} +if(idx<=0){ +continue; +} +var _c32=false; +while(idx!=-1){ +if(" ,/(".indexOf(_c30.charAt(idx-1))!=-1){ +_c32=true; +break; +} +idx=_c30.indexOf(_c2b,idx+1); +} +if(!_c32){ +continue; +}else{ +ret.push(this._data[x]); +} +} +} +} +} +_c2c(ret); +},setData:function(_c33){ +this._data=_c33; +}}); +dojo.widget.defineWidget("dojo.widget.ComboBox",dojo.widget.HtmlWidget,{forceValidOption:false,searchType:"stringstart",dataProvider:null,autoComplete:true,searchDelay:100,dataUrl:"",fadeTime:200,maxListLength:8,mode:"local",selectedResult:null,dataProviderClass:"",buttonSrc:dojo.uri.moduleUri("dojo.widget","templates/images/combo_box_arrow.png"),dropdownToggle:"fade",templateString:"\r\n",templateCssString:".dojoComboBoxOuter {\r\n\tborder: 0px !important;\r\n\tmargin: 0px !important;\r\n\tpadding: 0px !important;\r\n\tbackground: transparent !important;\r\n\twhite-space: nowrap !important;\r\n}\r\n\r\n.dojoComboBox {\r\n\tborder: 1px inset #afafaf;\r\n\tmargin: 0px;\r\n\tpadding: 0px;\r\n\tvertical-align: middle !important;\r\n\tfloat: none !important;\r\n\tposition: static !important;\r\n\tdisplay: inline !important;\r\n}\r\n\r\n/* the input box */\r\ninput.dojoComboBox {\r\n\tborder-right-width: 0px !important; \r\n\tmargin-right: 0px !important;\r\n\tpadding-right: 0px !important;\r\n}\r\n\r\n/* the down arrow */\r\nimg.dojoComboBox {\r\n\tborder-left-width: 0px !important;\r\n\tpadding-left: 0px !important;\r\n\tmargin-left: 0px !important;\r\n}\r\n\r\n/* IE vertical-alignment calculations can be off by +-1 but these margins are collapsed away */\r\n.dj_ie img.dojoComboBox {\r\n\tmargin-top: 1px; \r\n\tmargin-bottom: 1px; \r\n}\r\n\r\n/* the drop down */\r\n.dojoComboBoxOptions {\r\n\tfont-family: Verdana, Helvetica, Garamond, sans-serif;\r\n\t/* font-size: 0.7em; */\r\n\tbackground-color: white;\r\n\tborder: 1px solid #afafaf;\r\n\tposition: absolute;\r\n\tz-index: 1000; \r\n\toverflow: auto;\r\n\tcursor: default;\r\n}\r\n\r\n.dojoComboBoxItem {\r\n\tpadding-left: 2px;\r\n\tpadding-top: 2px;\r\n\tmargin: 0px;\r\n}\r\n\r\n.dojoComboBoxItemEven {\r\n\tbackground-color: #f4f4f4;\r\n}\r\n\r\n.dojoComboBoxItemOdd {\r\n\tbackground-color: white;\r\n}\r\n\r\n.dojoComboBoxItemHighlight {\r\n\tbackground-color: #63709A;\r\n\tcolor: white;\r\n}\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/ComboBox.css"),setValue:function(_c34){ +this.comboBoxValue.value=_c34; +if(this.textInputNode.value!=_c34){ +this.textInputNode.value=_c34; +dojo.widget.html.stabile.setState(this.widgetId,this.getState(),true); +this.onValueChanged(_c34); +} +},onValueChanged:function(_c35){ +},getValue:function(){ +return this.comboBoxValue.value; +},getState:function(){ +return {value:this.getValue()}; +},setState:function(_c36){ +this.setValue(_c36.value); +},enable:function(){ +this.disabled=false; +this.textInputNode.removeAttribute("disabled"); +},disable:function(){ +this.disabled=true; +this.textInputNode.setAttribute("disabled",true); +},_getCaretPos:function(_c37){ +if(dojo.lang.isNumber(_c37.selectionStart)){ +return _c37.selectionStart; +}else{ +if(dojo.render.html.ie){ +var tr=document.selection.createRange().duplicate(); +var ntr=_c37.createTextRange(); +tr.move("character",0); +ntr.move("character",0); +try{ +ntr.setEndPoint("EndToEnd",tr); +return String(ntr.text).replace(/\r/g,"").length; +} +catch(e){ +return 0; +} +} +} +},_setCaretPos:function(_c3a,_c3b){ +_c3b=parseInt(_c3b); +this._setSelectedRange(_c3a,_c3b,_c3b); +},_setSelectedRange:function(_c3c,_c3d,end){ +if(!end){ +end=_c3c.value.length; +} +if(_c3c.setSelectionRange){ +_c3c.focus(); +_c3c.setSelectionRange(_c3d,end); +}else{ +if(_c3c.createTextRange){ +var _c3f=_c3c.createTextRange(); +with(_c3f){ +collapse(true); +moveEnd("character",end); +moveStart("character",_c3d); +select(); +} +}else{ +_c3c.value=_c3c.value; +_c3c.blur(); +_c3c.focus(); +var dist=parseInt(_c3c.value.length)-end; +var _c41=String.fromCharCode(37); +var tcc=_c41.charCodeAt(0); +for(var x=0;x0)){ +var cpos=this._getCaretPos(this.textInputNode); +if((cpos+1)>this.textInputNode.value.length){ +this.textInputNode.value+=_c56[0][0].substr(cpos); +this._setSelectedRange(this.textInputNode,cpos,this.textInputNode.value.length); +} +} +var even=true; +while(_c56.length){ +var tr=_c56.shift(); +if(tr){ +var td=document.createElement("div"); +td.appendChild(document.createTextNode(tr[0])); +td.setAttribute("resultName",tr[0]); +td.setAttribute("resultValue",tr[1]); +td.className="dojoComboBoxItem "+((even)?"dojoComboBoxItemEven":"dojoComboBoxItemOdd"); +even=(!even); +this.optionsListNode.appendChild(td); +} +} +this._showResultList(); +},_onFocusInput:function(){ +this._hasFocus=true; +},_onBlurInput:function(){ +this._hasFocus=false; +this._handleBlurTimer(true,500); +},_handleBlurTimer:function(_c5b,_c5c){ +if(this.blurTimer&&(_c5b||_c5c)){ +clearTimeout(this.blurTimer); +} +if(_c5c){ +this.blurTimer=dojo.lang.setTimeout(this,"_checkBlurred",_c5c); +} +},_onMouseOver:function(evt){ +if(!this._mouseover_list){ +this._handleBlurTimer(true,0); +this._mouseover_list=true; +} +},_onMouseOut:function(evt){ +var _c5f=evt.relatedTarget; +try{ +if(!_c5f||_c5f.parentNode!=this.optionsListNode){ +this._mouseover_list=false; +this._handleBlurTimer(true,100); +this._tryFocus(); +} +} +catch(e){ +} +},_isInputEqualToResult:function(_c60){ +var _c61=this.textInputNode.value; +if(!this.dataProvider.caseSensitive){ +_c61=_c61.toLowerCase(); +_c60=_c60.toLowerCase(); +} +return (_c61==_c60); +},_isValidOption:function(){ +var tgt=dojo.html.firstElement(this.optionsListNode); +var _c63=false; +while(!_c63&&tgt){ +if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){ +_c63=true; +}else{ +tgt=dojo.html.nextElement(tgt); +} +} +return _c63; +},_checkBlurred:function(){ +if(!this._hasFocus&&!this._mouseover_list){ +this._hideResultList(); +if(!this.textInputNode.value.length){ +this.setAllValues("",""); +return; +} +var _c64=this._isValidOption(); +if(this.forceValidOption&&!_c64){ +this.setAllValues("",""); +return; +} +if(!_c64){ +this.setSelectedValue(""); +} +} +},_selectOption:function(evt){ +var tgt=null; +if(!evt){ +evt={target:this._highlighted_option}; +} +if(!dojo.html.isDescendantOf(evt.target,this.optionsListNode)){ +if(!this.textInputNode.value.length){ +return; +} +tgt=dojo.html.firstElement(this.optionsListNode); +if(!tgt||!this._isInputEqualToResult(tgt.getAttribute("resultName"))){ +return; +} +}else{ +tgt=evt.target; +} +while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){ +tgt=tgt.parentNode; +if(tgt===dojo.body()){ +return false; +} +} +this.selectedResult=[tgt.getAttribute("resultName"),tgt.getAttribute("resultValue")]; +this.setAllValues(tgt.getAttribute("resultName"),tgt.getAttribute("resultValue")); +if(!evt.noHide){ +this._hideResultList(); +this._setSelectedRange(this.textInputNode,0,null); +} +this._tryFocus(); +},_clearResultList:function(){ +if(this.optionsListNode.innerHTML){ +this.optionsListNode.innerHTML=""; +} +},_hideResultList:function(){ +this.popupWidget.close(); +},_showResultList:function(){ +var _c67=this.optionsListNode.childNodes; +if(_c67.length){ +var _c68=Math.min(_c67.length,this.maxListLength); +with(this.optionsListNode.style){ +display=""; +if(_c68==_c67.length){ +height=""; +}else{ +height=_c68*dojo.html.getMarginBox(_c67[0]).height+"px"; +} +width=(dojo.html.getMarginBox(this.domNode).width-2)+"px"; +} +this.popupWidget.open(this.domNode,this,this.downArrowNode); +}else{ +this._hideResultList(); +} +},handleArrowClick:function(){ +this._handleBlurTimer(true,0); +this._tryFocus(); +if(this.popupWidget.isShowingNow){ +this._hideResultList(); +}else{ +this._startSearch(""); +} +},_tryFocus:function(){ +try{ +this.textInputNode.focus(); +} +catch(e){ +} +},_startSearchFromInput:function(){ +this._startSearch(this.textInputNode.value); +},_startSearch:function(key){ +this.dataProvider.startSearch(key,dojo.lang.hitch(this,"_openResultList")); +},postCreate:function(){ +this.onResize(); +dojo.event.connect(this.textInputNode,"onblur",this,"_onBlurInput"); +dojo.event.connect(this.textInputNode,"onfocus",this,"_onFocusInput"); +if(this.disabled){ +this.disable(); +} +var s=dojo.widget.html.stabile.getState(this.widgetId); +if(s){ +this.setState(s); +} +}}); +dojo.provide("struts.widget.ComboBox"); +struts.widget.ComboBoxDataProvider=function(_c6b,node){ +this.data=[]; +this.searchLimit=_c6b.searchLimit; +this.searchType="STARTSTRING"; +this.caseSensitive=false; +this._lastSearch=""; +this._lastSearchResults=null; +this.firstRequest=true; +this.cbox=_c6b; +this.formId=this.cbox.formId; +this.formFilter=this.cbox.formFilter; +this.transport=this.cbox.transport; +this.getData=function(url){ +dojo.html.show(this.cbox.indicator); +dojo.io.bind({url:url,formNode:dojo.byId(this.formId),formFilter:window[this.formFilter],transport:this.transport,handler:dojo.lang.hitch(this,function(type,data,evt){ +dojo.html.hide(this.cbox.indicator); +if(!this.firstRequest||type=="error"){ +this.cbox.notify.apply(this.cbox,[data,type,evt]); +} +this.firstRequest=false; +var _c71=null; +var _c72=data[dojo.string.isBlank(this.cbox.dataFieldName)?this.cbox.name:this.cbox.dataFieldName]; +if(!dojo.lang.isArray(data)){ +if(_c72){ +if(dojo.lang.isArray(_c72)){ +_c71=_c72; +}else{ +if(dojo.lang.isObject(_c72)){ +_c71=[]; +for(var key in _c72){ +_c71.push([key,_c72[key]]); +} +} +} +}else{ +var _c74=[]; +for(var key in data){ +if(dojo.string.startsWith(key,this.cbox.name)){ +_c71=data[key]; +break; +}else{ +_c74.push([key,data[key]]); +} +if(!_c71&&dojo.lang.isArray(data[key])&&!dojo.lang.isString(data[key])){ +_c71=data[key]; +} +} +if(!_c71){ +_c71=_c74; +} +} +data=_c71; +} +this.setData(data); +}),mimetype:"text/json"}); +}; +this.startSearch=function(_c75,_c76){ +this._preformSearch(_c75,_c76); +}; +this._preformSearch=function(_c77,_c78){ +var st=this.searchType; +var ret=[]; +if(!this.caseSensitive){ +_c77=_c77.toLowerCase(); +} +for(var x=0;x0)&&(ret.length>=this.searchLimit)){ +break; +} +var _c7c=new String((!this.caseSensitive)?this.data[x][0].toLowerCase():this.data[x][0]); +if(_c7c.length<_c77.length){ +continue; +} +if(st=="STARTSTRING"){ +if(_c77==_c7c.substr(0,_c77.length)){ +ret.push(this.data[x]); +} +}else{ +if(st=="SUBSTRING"){ +if(_c7c.indexOf(_c77)>=0){ +ret.push(this.data[x]); +} +}else{ +if(st=="STARTWORD"){ +var idx=_c7c.indexOf(_c77); +if(idx==0){ +ret.push(this.data[x]); +} +if(idx<=0){ +continue; +} +var _c7e=false; +while(idx!=-1){ +if(" ,/(".indexOf(_c7c.charAt(idx-1))!=-1){ +_c7e=true; +break; +} +idx=_c7c.indexOf(_c77,idx+1); +} +if(!_c7e){ +continue; +}else{ +ret.push(this.data[x]); +} +} +} +} +} +_c78(ret); +}; +this.addData=function(_c7f){ +this.data=this.data.concat(_c7f); +}; +this.setData=function(_c80){ +this.data=_c80; +for(var i=0;i0)){ +var cpos=this._getCaretPos(this.textInputNode); +if((cpos+1)>this.textInputNode.value.length){ +this.textInputNode.value+=_c8b[0][0].substr(cpos); +this._setSelectedRange(this.textInputNode,cpos,this.textInputNode.value.length); +} +} +var _c8d=this.textInputNode.value; +var even=true; +while(_c8b.length){ +var tr=_c8b.shift(); +if(tr){ +var td=document.createElement("div"); +var text=tr[0]; +var i=text.toLowerCase().indexOf(_c8d.toLowerCase()); +if(i>=0){ +var pre=text.substring(0,i); +var _c94=text.substring(i,i+_c8d.length); +var post=text.substring(i+_c8d.length); +if(!dojo.string.isBlank(pre)){ +td.appendChild(document.createTextNode(pre)); +} +var _c96=document.createElement("b"); +td.appendChild(_c96); +_c96.appendChild(document.createTextNode(_c94)); +td.appendChild(document.createTextNode(post)); +}else{ +td.appendChild(document.createTextNode(tr[0])); +} +td.setAttribute("resultName",tr[0]); +td.setAttribute("resultValue",tr[1]); +td.className="dojoComboBoxItem "+((even)?"dojoComboBoxItemEven":"dojoComboBoxItemOdd"); +even=(!even); +this.optionsListNode.appendChild(td); +} +} +this.showResultList(); +},postCreate:function(){ +struts.widget.ComboBox.superclass.postCreate.apply(this); +var self=this; +if(!dojo.string.isBlank(this.listenTopics)){ +var _c98=this.listenTopics.split(","); +for(var i=0;i<_c98.length;i++){ +dojo.event.topic.subscribe(_c98[i],function(){ +var _c9a={cancel:false}; +self.notify(this.widgetId,"before",_c9a); +if(_c9a.cancel){ +return; +} +self.clearValues(); +self.dataProvider.getData(self.dataUrl); +}); +} +} +if(!dojo.string.isBlank(this.notifyTopics)){ +this.notifyTopicsArray=this.notifyTopics.split(","); +} +if(!dojo.string.isBlank(this.beforeNotifyTopics)){ +this.beforeNotifyTopicsArray=this.beforeNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.afterNotifyTopics)){ +this.afterNotifyTopicsArray=this.afterNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.errorNotifyTopics)){ +this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.valueNotifyTopics)){ +this.valueNotifyTopicsArray=this.valueNotifyTopics.split(","); +} +this.comboBoxSelectionValue.name=dojo.string.isBlank(this.keyName)?this.name+"Key":this.keyName; +this.comboBoxValue.value=this.initialValue; +this.comboBoxSelectionValue.value=this.initialKey; +this.textInputNode.value=this.initialValue; +if(!dojo.string.isBlank(this.tabIndex)){ +this.textInputNode.tabIndex=this.tabIndex; +} +if(!this.visibleDownArrow){ +dojo.html.hide(this.downArrowNode); +} +if(!dojo.string.isBlank(this.searchType)){ +this.dataProvider.searchType=this.searchType.toUpperCase(); +} +},clearValues:function(){ +this.comboBoxValue.value=""; +this.comboBoxSelectionValue.value=""; +this.textInputNode.value=""; +},onValueChanged:function(data){ +this.notify(data,"valuechanged",null); +},notify:function(data,type,e){ +var self=this; +if(this.notifyTopicsArray){ +dojo.lang.forEach(this.notifyTopicsArray,function(_ca0){ +try{ +dojo.event.topic.publish(_ca0,data,type,e,self); +} +catch(ex){ +self.log(ex); +} +}); +} +var _ca1=null; +switch(type){ +case "before": +this.notifyTo(this.beforeNotifyTopicsArray,[e,this]); +break; +case "load": +this.notifyTo(this.afterNotifyTopicsArray,[data,e,this]); +break; +case "error": +this.notifyTo(this.errorNotifyTopicsArray,[data,e,this]); +break; +case "valuechanged": +this.notifyTo(this.valueNotifyTopicsArray,[this.getSelectedValue(),this.getSelectedKey(),this.getText(),this]); +break; +} +},notifyTo:function(_ca2,_ca3){ +var self=this; +if(_ca2){ +dojo.lang.forEach(_ca2,function(_ca5){ +try{ +dojo.event.topic.publishApply(_ca5,_ca3); +} +catch(ex){ +self.log(ex); +} +}); +} +},log:function(text){ +dojo.debug("["+(this.widgetId?this.widgetId:"unknown")+"] "+text); +},_startSearchFromInput:function(){ +var _ca7=this.textInputNode.value; +if(this.loadOnType){ +if(_ca7.length>=this.loadMinimum){ +var _ca8=this.dataUrl+(this.dataUrl.indexOf("?")>-1?"&":"?"); +_ca8+=this.name+"="+encodeURIComponent(_ca7); +this.dataProvider.getData(_ca8); +this._startSearch(_ca7); +}else{ +this._hideResultList(); +} +}else{ +this._startSearch(_ca7); +} +},setSelectedKey:function(key){ +var data=this.dataProvider.data; +for(element in data){ +var obj=data[element]; +if(obj[1].toString()==key){ +this.setValue(obj[0].toString()); +this.comboBoxSelectionValue.value=obj[1].toString(); +} +} +},getSelectedKey:function(){ +return this.comboBoxSelectionValue.value; +},getSelectedValue:function(){ +return this.comboBoxValue.value; +},getText:function(){ +return this.textInputNode.value; +}}); +dojo.provide("dojo.widget.DropdownContainer"); +dojo.widget.defineWidget("dojo.widget.DropdownContainer",dojo.widget.HtmlWidget,{inputWidth:"7em",id:"",inputId:"",inputName:"",iconURL:dojo.uri.moduleUri("dojo.widget","templates/images/combo_box_arrow.png"),copyClasses:false,iconAlt:"",containerToggle:"plain",containerToggleDuration:150,templateString:" \"${this.iconAlt}\"",templateCssPath:"",isContainer:true,attachTemplateNodes:function(){ +dojo.widget.DropdownContainer.superclass.attachTemplateNodes.apply(this,arguments); +this.popup=dojo.widget.createWidget("PopupContainer",{toggle:this.containerToggle,toggleDuration:this.containerToggleDuration}); +this.containerNode=this.popup.domNode; +},fillInTemplate:function(args,frag){ +this.domNode.appendChild(this.popup.domNode); +if(this.id){ +this.domNode.id=this.id; +} +if(this.inputId){ +this.inputNode.id=this.inputId; +} +if(this.inputName){ +this.inputNode.name=this.inputName; +} +this.inputNode.style.width=this.inputWidth; +this.inputNode.disabled=this.disabled; +if(this.copyClasses){ +this.inputNode.style=""; +this.inputNode.className=this.getFragNodeRef(frag).className; +} +dojo.event.connect(this.inputNode,"onchange",this,"onInputChange"); +},onIconClick:function(evt){ +if(this.disabled){ +return; +} +if(!this.popup.isShowingNow){ +this.popup.open(this.inputNode,this,this.buttonNode); +}else{ +this.popup.close(); +} +},hideContainer:function(){ +if(this.popup.isShowingNow){ +this.popup.close(); +} +},onInputChange:function(){ +},enable:function(){ +this.inputNode.disabled=false; +dojo.widget.DropdownContainer.superclass.enable.apply(this,arguments); +},disable:function(){ +this.inputNode.disabled=true; +dojo.widget.DropdownContainer.superclass.disable.apply(this,arguments); +}}); +dojo.provide("dojo.date.serialize"); +dojo.date.setIso8601=function(_caf,_cb0){ +var _cb1=(_cb0.indexOf("T")==-1)?_cb0.split(" "):_cb0.split("T"); +_caf=dojo.date.setIso8601Date(_caf,_cb1[0]); +if(_cb1.length==2){ +_caf=dojo.date.setIso8601Time(_caf,_cb1[1]); +} +return _caf; +}; +dojo.date.fromIso8601=function(_cb2){ +return dojo.date.setIso8601(new Date(0,0),_cb2); +}; +dojo.date.setIso8601Date=function(_cb3,_cb4){ +var _cb5="^([0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|"+"(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$"; +var d=_cb4.match(new RegExp(_cb5)); +if(!d){ +dojo.debug("invalid date string: "+_cb4); +return null; +} +var year=d[1]; +var _cb8=d[4]; +var date=d[6]; +var _cba=d[8]; +var week=d[10]; +var _cbc=d[12]?d[12]:1; +_cb3.setFullYear(year); +if(_cba){ +_cb3.setMonth(0); +_cb3.setDate(Number(_cba)); +}else{ +if(week){ +_cb3.setMonth(0); +_cb3.setDate(1); +var gd=_cb3.getDay(); +var day=gd?gd:7; +var _cbf=Number(_cbc)+(7*Number(week)); +if(day<=4){ +_cb3.setDate(_cbf+1-day); +}else{ +_cb3.setDate(_cbf+8-day); +} +}else{ +if(_cb8){ +_cb3.setDate(1); +_cb3.setMonth(_cb8-1); +} +if(date){ +_cb3.setDate(date); +} +} +} +return _cb3; +}; +dojo.date.fromIso8601Date=function(_cc0){ +return dojo.date.setIso8601Date(new Date(0,0),_cc0); +}; +dojo.date.setIso8601Time=function(_cc1,_cc2){ +var _cc3="Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$"; +var d=_cc2.match(new RegExp(_cc3)); +var _cc5=0; +if(d){ +if(d[0]!="Z"){ +_cc5=(Number(d[3])*60)+Number(d[5]); +_cc5*=((d[2]=="-")?1:-1); +} +_cc5-=_cc1.getTimezoneOffset(); +_cc2=_cc2.substr(0,_cc2.length-d[0].length); +} +var _cc6="^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(.([0-9]+))?)?)?$"; +d=_cc2.match(new RegExp(_cc6)); +if(!d){ +dojo.debug("invalid time string: "+_cc2); +return null; +} +var _cc7=d[1]; +var mins=Number((d[3])?d[3]:0); +var secs=(d[5])?d[5]:0; +var ms=d[7]?(Number("0."+d[7])*1000):0; +_cc1.setHours(_cc7); +_cc1.setMinutes(mins); +_cc1.setSeconds(secs); +_cc1.setMilliseconds(ms); +if(_cc5!==0){ +_cc1.setTime(_cc1.getTime()+_cc5*60000); +} +return _cc1; +}; +dojo.date.fromIso8601Time=function(_ccb){ +return dojo.date.setIso8601Time(new Date(0,0),_ccb); +}; +dojo.date.toRfc3339=function(_ccc,_ccd){ +if(!_ccc){ +_ccc=new Date(); +} +var _=dojo.string.pad; +var _ccf=[]; +if(_ccd!="timeOnly"){ +var date=[_(_ccc.getFullYear(),4),_(_ccc.getMonth()+1,2),_(_ccc.getDate(),2)].join("-"); +_ccf.push(date); +} +if(_ccd!="dateOnly"){ +var time=[_(_ccc.getHours(),2),_(_ccc.getMinutes(),2),_(_ccc.getSeconds(),2)].join(":"); +var _cd2=_ccc.getTimezoneOffset(); +time+=(_cd2>0?"-":"+")+_(Math.floor(Math.abs(_cd2)/60),2)+":"+_(Math.abs(_cd2)%60,2); +_ccf.push(time); +} +return _ccf.join("T"); +}; +dojo.date.fromRfc3339=function(_cd3){ +if(_cd3.indexOf("Tany")!=-1){ +_cd3=_cd3.replace("Tany",""); +} +var _cd4=new Date(); +return dojo.date.setIso8601(_cd4,_cd3); +}; +dojo.provide("dojo.date.common"); +dojo.date.setDayOfYear=function(_cd5,_cd6){ +_cd5.setMonth(0); +_cd5.setDate(_cd6); +return _cd5; +}; +dojo.date.getDayOfYear=function(_cd7){ +var _cd8=_cd7.getFullYear(); +var _cd9=new Date(_cd8-1,11,31); +return Math.floor((_cd7.getTime()-_cd9.getTime())/86400000); +}; +dojo.date.setWeekOfYear=function(_cda,week,_cdc){ +if(arguments.length==1){ +_cdc=0; +} +dojo.unimplemented("dojo.date.setWeekOfYear"); +}; +dojo.date.getWeekOfYear=function(_cdd,_cde){ +if(arguments.length==1){ +_cde=0; +} +var _cdf=new Date(_cdd.getFullYear(),0,1); +var day=_cdf.getDay(); +_cdf.setDate(_cdf.getDate()-day+_cde-(day>_cde?7:0)); +return Math.floor((_cdd.getTime()-_cdf.getTime())/604800000); +}; +dojo.date.setIsoWeekOfYear=function(_ce1,week,_ce3){ +if(arguments.length==1){ +_ce3=1; +} +dojo.unimplemented("dojo.date.setIsoWeekOfYear"); +}; +dojo.date.getIsoWeekOfYear=function(_ce4,_ce5){ +if(arguments.length==1){ +_ce5=1; +} +dojo.unimplemented("dojo.date.getIsoWeekOfYear"); +}; +dojo.date.shortTimezones=["IDLW","BET","HST","MART","AKST","PST","MST","CST","EST","AST","NFT","BST","FST","AT","GMT","CET","EET","MSK","IRT","GST","AFT","AGTT","IST","NPT","ALMT","MMT","JT","AWST","JST","ACST","AEST","LHST","VUT","NFT","NZT","CHAST","PHOT","LINT"]; +dojo.date.timezoneOffsets=[-720,-660,-600,-570,-540,-480,-420,-360,-300,-240,-210,-180,-120,-60,0,60,120,180,210,240,270,300,330,345,360,390,420,480,540,570,600,630,660,690,720,765,780,840]; +dojo.date.getDaysInMonth=function(_ce6){ +var _ce7=_ce6.getMonth(); +var days=[31,28,31,30,31,30,31,31,30,31,30,31]; +if(_ce7==1&&dojo.date.isLeapYear(_ce6)){ +return 29; +}else{ +return days[_ce7]; +} +}; +dojo.date.isLeapYear=function(_ce9){ +var year=_ce9.getFullYear(); +return (year%400==0)?true:(year%100==0)?false:(year%4==0)?true:false; +}; +dojo.date.getTimezoneName=function(_ceb){ +var str=_ceb.toString(); +var tz=""; +var _cee; +var pos=str.indexOf("("); +if(pos>-1){ +pos++; +tz=str.substring(pos,str.indexOf(")")); +}else{ +var pat=/([A-Z\/]+) \d{4}$/; +if((_cee=str.match(pat))){ +tz=_cee[1]; +}else{ +str=_ceb.toLocaleString(); +pat=/ ([A-Z\/]+)$/; +if((_cee=str.match(pat))){ +tz=_cee[1]; +} +} +} +return tz=="AM"||tz=="PM"?"":tz; +}; +dojo.date.getOrdinal=function(_cf1){ +var date=_cf1.getDate(); +if(date%100!=11&&date%10==1){ +return "st"; +}else{ +if(date%100!=12&&date%10==2){ +return "nd"; +}else{ +if(date%100!=13&&date%10==3){ +return "rd"; +}else{ +return "th"; +} +} +} +}; +dojo.date.compareTypes={DATE:1,TIME:2}; +dojo.date.compare=function(_cf3,_cf4,_cf5){ +var dA=_cf3; +var dB=_cf4||new Date(); +var now=new Date(); +with(dojo.date.compareTypes){ +var opt=_cf5||(DATE|TIME); +var d1=new Date((opt&DATE)?dA.getFullYear():now.getFullYear(),(opt&DATE)?dA.getMonth():now.getMonth(),(opt&DATE)?dA.getDate():now.getDate(),(opt&TIME)?dA.getHours():0,(opt&TIME)?dA.getMinutes():0,(opt&TIME)?dA.getSeconds():0); +var d2=new Date((opt&DATE)?dB.getFullYear():now.getFullYear(),(opt&DATE)?dB.getMonth():now.getMonth(),(opt&DATE)?dB.getDate():now.getDate(),(opt&TIME)?dB.getHours():0,(opt&TIME)?dB.getMinutes():0,(opt&TIME)?dB.getSeconds():0); +} +if(d1.valueOf()>d2.valueOf()){ +return 1; +} +if(d1.valueOf()0)?5:-5; +_d01=(incr>0)?((incr-5)/5):((incr+5)/5); +}else{ +days=mod; +_d01=parseInt(incr/5); +} +strt=dt.getDay(); +if(strt==6&&incr>0){ +adj=1; +}else{ +if(strt==0&&incr<0){ +adj=-1; +} +} +trgt=(strt+days); +if(trgt==0||trgt==6){ +adj=(incr>0)?2:-2; +} +sum.setDate(dat+(7*_d01)+days+adj); +break; +case HOUR: +sum.setHours(sum.getHours()+incr); +break; +case MINUTE: +sum.setMinutes(sum.getMinutes()+incr); +break; +case SECOND: +sum.setSeconds(sum.getSeconds()+incr); +break; +case MILLISECOND: +sum.setMilliseconds(sum.getMilliseconds()+incr); +break; +default: +break; +} +} +return sum; +}; +dojo.date.diff=function(dtA,dtB,_d09){ +if(typeof dtA=="number"){ +dtA=new Date(dtA); +} +if(typeof dtB=="number"){ +dtB=new Date(dtB); +} +var _d0a=dtB.getFullYear()-dtA.getFullYear(); +var _d0b=(dtB.getMonth()-dtA.getMonth())+(_d0a*12); +var _d0c=dtB.getTime()-dtA.getTime(); +var _d0d=_d0c/1000; +var _d0e=_d0d/60; +var _d0f=_d0e/60; +var _d10=_d0f/24; +var _d11=_d10/7; +var _d12=0; +with(dojo.date.dateParts){ +switch(_d09){ +case YEAR: +_d12=_d0a; +break; +case QUARTER: +var mA=dtA.getMonth(); +var mB=dtB.getMonth(); +var qA=Math.floor(mA/3)+1; +var qB=Math.floor(mB/3)+1; +qB+=(_d0a*4); +_d12=qB-qA; +break; +case MONTH: +_d12=_d0b; +break; +case WEEK: +_d12=parseInt(_d11); +break; +case DAY: +_d12=_d10; +break; +case WEEKDAY: +var days=Math.round(_d10); +var _d18=parseInt(days/7); +var mod=days%7; +if(mod==0){ +days=_d18*5; +}else{ +var adj=0; +var aDay=dtA.getDay(); +var bDay=dtB.getDay(); +_d18=parseInt(days/7); +mod=days%7; +var _d1d=new Date(dtA); +_d1d.setDate(_d1d.getDate()+(_d18*7)); +var _d1e=_d1d.getDay(); +if(_d10>0){ +switch(true){ +case aDay==6: +adj=-1; +break; +case aDay==0: +adj=0; +break; +case bDay==6: +adj=-1; +break; +case bDay==0: +adj=-2; +break; +case (_d1e+mod)>5: +adj=-2; +break; +default: +break; +} +}else{ +if(_d10<0){ +switch(true){ +case aDay==6: +adj=0; +break; +case aDay==0: +adj=1; +break; +case bDay==6: +adj=2; +break; +case bDay==0: +adj=1; +break; +case (_d1e+mod)<0: +adj=2; +break; +default: +break; +} +} +} +days+=adj; +days-=(_d18*2); +} +_d12=days; +break; +case HOUR: +_d12=_d0f; +break; +case MINUTE: +_d12=_d0e; +break; +case SECOND: +_d12=_d0d; +break; +case MILLISECOND: +_d12=_d0c; +break; +default: +break; +} +} +return Math.round(_d12); +}; +dojo.provide("dojo.date.supplemental"); +dojo.date.getFirstDayOfWeek=function(_d1f){ +var _d20={mv:5,ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,lb:6,ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,tn:6,ye:6,as:0,au:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,il:0,is:0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mo:0,mp:0,mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,vi:0,za:0,zw:0,et:0,mw:0,ng:0,tj:0,gb:0,sy:4}; +_d1f=dojo.hostenv.normalizeLocale(_d1f); +var _d21=_d1f.split("-")[1]; +var dow=_d20[_d21]; +return (typeof dow=="undefined")?1:dow; +}; +dojo.date.getWeekend=function(_d23){ +var _d24={eg:5,il:5,sy:5,"in":0,ae:4,bh:4,dz:4,iq:4,jo:4,kw:4,lb:4,ly:4,ma:4,om:4,qa:4,sa:4,sd:4,tn:4,ye:4}; +var _d25={ae:5,bh:5,dz:5,iq:5,jo:5,kw:5,lb:5,ly:5,ma:5,om:5,qa:5,sa:5,sd:5,tn:5,ye:5,af:5,ir:5,eg:6,il:6,sy:6}; +_d23=dojo.hostenv.normalizeLocale(_d23); +var _d26=_d23.split("-")[1]; +var _d27=_d24[_d26]; +var end=_d25[_d26]; +if(typeof _d27=="undefined"){ +_d27=6; +} +if(typeof end=="undefined"){ +end=0; +} +return {start:_d27,end:end}; +}; +dojo.date.isWeekend=function(_d29,_d2a){ +var _d2b=dojo.date.getWeekend(_d2a); +var day=(_d29||new Date()).getDay(); +if(_d2b.end<_d2b.start){ +_d2b.end+=7; +if(day<_d2b.start){ +day+=7; +} +} +return day>=_d2b.start&&day<=_d2b.end; +}; +dojo.provide("dojo.i18n.common"); +dojo.i18n.getLocalization=function(_d2d,_d2e,_d2f){ +dojo.hostenv.preloadLocalizations(); +_d2f=dojo.hostenv.normalizeLocale(_d2f); +var _d30=_d2f.split("-"); +var _d31=[_d2d,"nls",_d2e].join("."); +var _d32=dojo.hostenv.findModule(_d31,true); +var _d33; +for(var i=_d30.length;i>0;i--){ +var loc=_d30.slice(0,i).join("_"); +if(_d32[loc]){ +_d33=_d32[loc]; +break; +} +} +if(!_d33){ +_d33=_d32.ROOT; +} +if(_d33){ +var _d36=function(){ +}; +_d36.prototype=_d33; +return new _d36(); +} +dojo.raise("Bundle not found: "+_d2e+" in "+_d2d+" , locale="+_d2f); +}; +dojo.i18n.isLTR=function(_d37){ +var lang=dojo.hostenv.normalizeLocale(_d37).split("-")[0]; +var RTL={ar:true,fa:true,he:true,ur:true,yi:true}; +return !RTL[lang]; +}; +dojo.provide("dojo.date.format"); +(function(){ +dojo.date.format=function(_d3a,_d3b){ +if(typeof _d3b=="string"){ +dojo.deprecated("dojo.date.format","To format dates with POSIX-style strings, please use dojo.date.strftime instead","0.5"); +return dojo.date.strftime(_d3a,_d3b); +} +function formatPattern(_d3c,_d3d){ +return _d3d.replace(/([a-z])\1*/ig,function(_d3e){ +var s; +var c=_d3e.charAt(0); +var l=_d3e.length; +var pad; +var _d43=["abbr","wide","narrow"]; +switch(c){ +case "G": +if(l>3){ +dojo.unimplemented("Era format not implemented"); +} +s=info.eras[_d3c.getFullYear()<0?1:0]; +break; +case "y": +s=_d3c.getFullYear(); +switch(l){ +case 1: +break; +case 2: +s=String(s).substr(-2); +break; +default: +pad=true; +} +break; +case "Q": +case "q": +s=Math.ceil((_d3c.getMonth()+1)/3); +switch(l){ +case 1: +case 2: +pad=true; +break; +case 3: +case 4: +dojo.unimplemented("Quarter format not implemented"); +} +break; +case "M": +case "L": +var m=_d3c.getMonth(); +var _d46; +switch(l){ +case 1: +case 2: +s=m+1; +pad=true; +break; +case 3: +case 4: +case 5: +_d46=_d43[l-3]; +break; +} +if(_d46){ +var type=(c=="L")?"standalone":"format"; +var prop=["months",type,_d46].join("-"); +s=info[prop][m]; +} +break; +case "w": +var _d49=0; +s=dojo.date.getWeekOfYear(_d3c,_d49); +pad=true; +break; +case "d": +s=_d3c.getDate(); +pad=true; +break; +case "D": +s=dojo.date.getDayOfYear(_d3c); +pad=true; +break; +case "E": +case "e": +case "c": +var d=_d3c.getDay(); +var _d46; +switch(l){ +case 1: +case 2: +if(c=="e"){ +var _d4b=dojo.date.getFirstDayOfWeek(_d3b.locale); +d=(d-_d4b+7)%7; +} +if(c!="c"){ +s=d+1; +pad=true; +break; +} +case 3: +case 4: +case 5: +_d46=_d43[l-3]; +break; +} +if(_d46){ +var type=(c=="c")?"standalone":"format"; +var prop=["days",type,_d46].join("-"); +s=info[prop][d]; +} +break; +case "a": +var _d4c=(_d3c.getHours()<12)?"am":"pm"; +s=info[_d4c]; +break; +case "h": +case "H": +case "K": +case "k": +var h=_d3c.getHours(); +switch(c){ +case "h": +s=(h%12)||12; +break; +case "H": +s=h; +break; +case "K": +s=(h%12); +break; +case "k": +s=h||24; +break; +} +pad=true; +break; +case "m": +s=_d3c.getMinutes(); +pad=true; +break; +case "s": +s=_d3c.getSeconds(); +pad=true; +break; +case "S": +s=Math.round(_d3c.getMilliseconds()*Math.pow(10,l-3)); +break; +case "v": +case "z": +s=dojo.date.getTimezoneName(_d3c); +if(s){ +break; +} +l=4; +case "Z": +var _d4e=_d3c.getTimezoneOffset(); +var tz=[(_d4e<=0?"+":"-"),dojo.string.pad(Math.floor(Math.abs(_d4e)/60),2),dojo.string.pad(Math.abs(_d4e)%60,2)]; +if(l==4){ +tz.splice(0,0,"GMT"); +tz.splice(3,0,":"); +} +s=tz.join(""); +break; +case "Y": +case "u": +case "W": +case "F": +case "g": +case "A": +dojo.debug(_d3e+" modifier not yet implemented"); +s="?"; +break; +default: +dojo.raise("dojo.date.format: invalid pattern char: "+_d3d); +} +if(pad){ +s=dojo.string.pad(s,l); +} +return s; +}); +} +_d3b=_d3b||{}; +var _d50=dojo.hostenv.normalizeLocale(_d3b.locale); +var _d51=_d3b.formatLength||"full"; +var info=dojo.date._getGregorianBundle(_d50); +var str=[]; +var _d53=dojo.lang.curry(this,formatPattern,_d3a); +if(_d3b.selector!="timeOnly"){ +var _d54=_d3b.datePattern||info["dateFormat-"+_d51]; +if(_d54){ +str.push(_processPattern(_d54,_d53)); +} +} +if(_d3b.selector!="dateOnly"){ +var _d55=_d3b.timePattern||info["timeFormat-"+_d51]; +if(_d55){ +str.push(_processPattern(_d55,_d53)); +} +} +var _d56=str.join(" "); +return _d56; +}; +dojo.date.parse=function(_d57,_d58){ +_d58=_d58||{}; +var _d59=dojo.hostenv.normalizeLocale(_d58.locale); +var info=dojo.date._getGregorianBundle(_d59); +var _d5b=_d58.formatLength||"full"; +if(!_d58.selector){ +_d58.selector="dateOnly"; +} +var _d5c=_d58.datePattern||info["dateFormat-"+_d5b]; +var _d5d=_d58.timePattern||info["timeFormat-"+_d5b]; +var _d5e; +if(_d58.selector=="dateOnly"){ +_d5e=_d5c; +}else{ +if(_d58.selector=="timeOnly"){ +_d5e=_d5d; +}else{ +if(_d58.selector=="dateTime"){ +_d5e=_d5c+" "+_d5d; +}else{ +var msg="dojo.date.parse: Unknown selector param passed: '"+_d58.selector+"'."; +msg+=" Defaulting to date pattern."; +dojo.debug(msg); +_d5e=_d5c; +} +} +} +var _d60=[]; +var _d61=_processPattern(_d5e,dojo.lang.curry(this,_buildDateTimeRE,_d60,info,_d58)); +var _d62=new RegExp("^"+_d61+"$"); +var _d63=_d62.exec(_d57); +if(!_d63){ +return null; +} +var _d64=["abbr","wide","narrow"]; +var _d65=new Date(1972,0); +var _d66={}; +for(var i=1;i<_d63.length;i++){ +var grp=_d60[i-1]; +var l=grp.length; +var v=_d63[i]; +switch(grp.charAt(0)){ +case "y": +if(l!=2){ +_d65.setFullYear(v); +_d66.year=v; +}else{ +if(v<100){ +v=Number(v); +var year=""+new Date().getFullYear(); +var _d6c=year.substring(0,2)*100; +var _d6d=Number(year.substring(2,4)); +var _d6e=Math.min(_d6d+20,99); +var num=(v<_d6e)?_d6c+v:_d6c-100+v; +_d65.setFullYear(num); +_d66.year=num; +}else{ +if(_d58.strict){ +return null; +} +_d65.setFullYear(v); +_d66.year=v; +} +} +break; +case "M": +if(l>2){ +if(!_d58.strict){ +v=v.replace(/\./g,""); +v=v.toLowerCase(); +} +var _d70=info["months-format-"+_d64[l-3]].concat(); +for(var j=0;j<_d70.length;j++){ +if(!_d58.strict){ +_d70[j]=_d70[j].toLowerCase(); +} +if(v==_d70[j]){ +_d65.setMonth(j); +_d66.month=j; +break; +} +} +if(j==_d70.length){ +dojo.debug("dojo.date.parse: Could not parse month name: '"+v+"'."); +return null; +} +}else{ +_d65.setMonth(v-1); +_d66.month=v-1; +} +break; +case "E": +case "e": +if(!_d58.strict){ +v=v.toLowerCase(); +} +var days=info["days-format-"+_d64[l-3]].concat(); +for(var j=0;j23){ +dojo.debug("dojo.date.parse: Illegal hours value"); +return null; +} +_d65.setHours(v); +break; +case "m": +_d65.setMinutes(v); +break; +case "s": +_d65.setSeconds(v); +break; +case "S": +_d65.setMilliseconds(v); +break; +default: +dojo.unimplemented("dojo.date.parse: unsupported pattern char="+grp.charAt(0)); +} +} +if(_d66.year&&_d65.getFullYear()!=_d66.year){ +dojo.debug("Parsed year: '"+_d65.getFullYear()+"' did not match input year: '"+_d66.year+"'."); +return null; +} +if(_d66.month&&_d65.getMonth()!=_d66.month){ +dojo.debug("Parsed month: '"+_d65.getMonth()+"' did not match input month: '"+_d66.month+"'."); +return null; +} +if(_d66.date&&_d65.getDate()!=_d66.date){ +dojo.debug("Parsed day of month: '"+_d65.getDate()+"' did not match input day of month: '"+_d66.date+"'."); +return null; +} +return _d65; +}; +function _processPattern(_d76,_d77,_d78,_d79){ +var _d7a=function(x){ +return x; +}; +_d77=_d77||_d7a; +_d78=_d78||_d7a; +_d79=_d79||_d7a; +var _d7c=_d76.match(/(''|[^'])+/g); +var _d7d=false; +for(var i=0;i<_d7c.length;i++){ +if(!_d7c[i]){ +_d7c[i]=""; +}else{ +_d7c[i]=(_d7d?_d78:_d77)(_d7c[i]); +_d7d=!_d7d; +} +} +return _d79(_d7c.join("")); +} +function _buildDateTimeRE(_d7f,info,_d81,_d82){ +return _d82.replace(/([a-z])\1*/ig,function(_d83){ +var s; +var c=_d83.charAt(0); +var l=_d83.length; +switch(c){ +case "y": +s="\\d"+((l==2)?"{2,4}":"+"); +break; +case "M": +s=(l>2)?"\\S+":"\\d{1,2}"; +break; +case "d": +s="\\d{1,2}"; +break; +case "E": +s="\\S+"; +break; +case "h": +case "H": +case "K": +case "k": +s="\\d{1,2}"; +break; +case "m": +case "s": +s="[0-5]\\d"; +break; +case "S": +s="\\d{1,3}"; +break; +case "a": +var am=_d81.am||info.am||"AM"; +var pm=_d81.pm||info.pm||"PM"; +if(_d81.strict){ +s=am+"|"+pm; +}else{ +s=am; +s+=(am!=am.toLowerCase())?"|"+am.toLowerCase():""; +s+="|"; +s+=(pm!=pm.toLowerCase())?pm+"|"+pm.toLowerCase():pm; +} +break; +default: +dojo.unimplemented("parse of date format, pattern="+_d82); +} +if(_d7f){ +_d7f.push(_d83); +} +return "\\s*("+s+")\\s*"; +}); +} +})(); +dojo.date.strftime=function(_d89,_d8a,_d8b){ +var _d8c=null; +function _(s,n){ +return dojo.string.pad(s,n||2,_d8c||"0"); +} +var info=dojo.date._getGregorianBundle(_d8b); +function $(_d90){ +switch(_d90){ +case "a": +return dojo.date.getDayShortName(_d89,_d8b); +case "A": +return dojo.date.getDayName(_d89,_d8b); +case "b": +case "h": +return dojo.date.getMonthShortName(_d89,_d8b); +case "B": +return dojo.date.getMonthName(_d89,_d8b); +case "c": +return dojo.date.format(_d89,{locale:_d8b}); +case "C": +return _(Math.floor(_d89.getFullYear()/100)); +case "d": +return _(_d89.getDate()); +case "D": +return $("m")+"/"+$("d")+"/"+$("y"); +case "e": +if(_d8c==null){ +_d8c=" "; +} +return _(_d89.getDate()); +case "f": +if(_d8c==null){ +_d8c=" "; +} +return _(_d89.getMonth()+1); +case "g": +break; +case "G": +dojo.unimplemented("unimplemented modifier 'G'"); +break; +case "F": +return $("Y")+"-"+$("m")+"-"+$("d"); +case "H": +return _(_d89.getHours()); +case "I": +return _(_d89.getHours()%12||12); +case "j": +return _(dojo.date.getDayOfYear(_d89),3); +case "k": +if(_d8c==null){ +_d8c=" "; +} +return _(_d89.getHours()); +case "l": +if(_d8c==null){ +_d8c=" "; +} +return _(_d89.getHours()%12||12); +case "m": +return _(_d89.getMonth()+1); +case "M": +return _(_d89.getMinutes()); +case "n": +return "\n"; +case "p": +return info[_d89.getHours()<12?"am":"pm"]; +case "r": +return $("I")+":"+$("M")+":"+$("S")+" "+$("p"); +case "R": +return $("H")+":"+$("M"); +case "S": +return _(_d89.getSeconds()); +case "t": +return "\t"; +case "T": +return $("H")+":"+$("M")+":"+$("S"); +case "u": +return String(_d89.getDay()||7); +case "U": +return _(dojo.date.getWeekOfYear(_d89)); +case "V": +return _(dojo.date.getIsoWeekOfYear(_d89)); +case "W": +return _(dojo.date.getWeekOfYear(_d89,1)); +case "w": +return String(_d89.getDay()); +case "x": +return dojo.date.format(_d89,{selector:"dateOnly",locale:_d8b}); +case "X": +return dojo.date.format(_d89,{selector:"timeOnly",locale:_d8b}); +case "y": +return _(_d89.getFullYear()%100); +case "Y": +return String(_d89.getFullYear()); +case "z": +var _d91=_d89.getTimezoneOffset(); +return (_d91>0?"-":"+")+_(Math.floor(Math.abs(_d91)/60))+":"+_(Math.abs(_d91)%60); +case "Z": +return dojo.date.getTimezoneName(_d89); +case "%": +return "%"; +} +} +var _d92=""; +var i=0; +var _d94=0; +var _d95=null; +while((_d94=_d8a.indexOf("%",i))!=-1){ +_d92+=_d8a.substring(i,_d94++); +switch(_d8a.charAt(_d94++)){ +case "_": +_d8c=" "; +break; +case "-": +_d8c=""; +break; +case "0": +_d8c="0"; +break; +case "^": +_d95="upper"; +break; +case "*": +_d95="lower"; +break; +case "#": +_d95="swap"; +break; +default: +_d8c=null; +_d94--; +break; +} +var _d96=$(_d8a.charAt(_d94++)); +switch(_d95){ +case "upper": +_d96=_d96.toUpperCase(); +break; +case "lower": +_d96=_d96.toLowerCase(); +break; +case "swap": +var _d97=_d96.toLowerCase(); +var _d98=""; +var j=0; +var ch=""; +while(j<_d96.length){ +ch=_d96.charAt(j); +_d98+=(ch==_d97.charAt(j))?ch.toUpperCase():ch.toLowerCase(); +j++; +} +_d96=_d98; +break; +default: +break; +} +_d95=null; +_d92+=_d96; +i=_d94; +} +_d92+=_d8a.substring(i); +return _d92; +}; +(function(){ +var _d9b=[]; +dojo.date.addCustomFormats=function(_d9c,_d9d){ +_d9b.push({pkg:_d9c,name:_d9d}); +}; +dojo.date._getGregorianBundle=function(_d9e){ +var _d9f={}; +dojo.lang.forEach(_d9b,function(desc){ +var _da1=dojo.i18n.getLocalization(desc.pkg,desc.name,_d9e); +_d9f=dojo.lang.mixin(_d9f,_da1); +},this); +return _d9f; +}; +})(); +dojo.date.addCustomFormats("dojo.i18n.calendar","gregorian"); +dojo.date.addCustomFormats("dojo.i18n.calendar","gregorianExtras"); +dojo.date.getNames=function(item,type,use,_da5){ +var _da6; +var _da7=dojo.date._getGregorianBundle(_da5); +var _da8=[item,use,type]; +if(use=="standAlone"){ +_da6=_da7[_da8.join("-")]; +} +_da8[1]="format"; +return (_da6||_da7[_da8.join("-")]).concat(); +}; +dojo.date.getDayName=function(_da9,_daa){ +return dojo.date.getNames("days","wide","format",_daa)[_da9.getDay()]; +}; +dojo.date.getDayShortName=function(_dab,_dac){ +return dojo.date.getNames("days","abbr","format",_dac)[_dab.getDay()]; +}; +dojo.date.getMonthName=function(_dad,_dae){ +return dojo.date.getNames("months","wide","format",_dae)[_dad.getMonth()]; +}; +dojo.date.getMonthShortName=function(_daf,_db0){ +return dojo.date.getNames("months","abbr","format",_db0)[_daf.getMonth()]; +}; +dojo.date.toRelativeString=function(_db1){ +var now=new Date(); +var diff=(now-_db1)/1000; +var end=" ago"; +var _db5=false; +if(diff<0){ +_db5=true; +end=" from now"; +diff=-diff; +} +if(diff<60){ +diff=Math.round(diff); +return diff+" second"+(diff==1?"":"s")+end; +} +if(diff<60*60){ +diff=Math.round(diff/60); +return diff+" minute"+(diff==1?"":"s")+end; +} +if(diff<60*60*24){ +diff=Math.round(diff/3600); +return diff+" hour"+(diff==1?"":"s")+end; +} +if(diff<60*60*24*7){ +diff=Math.round(diff/(3600*24)); +if(diff==1){ +return _db5?"Tomorrow":"Yesterday"; +}else{ +return diff+" days"+end; +} +} +return dojo.date.format(_db1); +}; +dojo.date.toSql=function(_db6,_db7){ +return dojo.date.strftime(_db6,"%F"+!_db7?" %T":""); +}; +dojo.date.fromSql=function(_db8){ +var _db9=_db8.split(/[\- :]/g); +while(_db9.length<6){ +_db9.push(0); +} +return new Date(_db9[0],(parseInt(_db9[1],10)-1),_db9[2],_db9[3],_db9[4],_db9[5]); +}; +dojo.provide("dojo.widget.TimePicker"); +dojo.widget.defineWidget("dojo.widget.TimePicker",dojo.widget.HtmlWidget,function(){ +this.time=""; +this.useDefaultTime=false; +this.useDefaultMinutes=false; +this.storedTime=""; +this.currentTime={}; +this.classNames={selectedTime:"selectedItem"}; +this.any="any"; +this.selectedTime={hour:"",minute:"",amPm:"",anyTime:false}; +this.hourIndexMap=["",2,4,6,8,10,1,3,5,7,9,11,0]; +this.minuteIndexMap=[0,2,4,6,8,10,1,3,5,7,9,11]; +},{isContainer:false,templateString:"
\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
 ${this.calendar.field-hour}${this.calendar.field-minute} 
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
126
17
28
39
410
511
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
0030
0535
1040
1545
2050
2555
\r\n\t\t\t\t
 \r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
${this.calendar.am}${this.calendar.pm}
\r\n\t\t\t\t
\r\n\t\t\t\t\t
${this.widgetStrings.any}
\r\n\t\t\t\t
 
\r\n
\r\n",templateCssString:"/*Time Picker */\r\n.timePickerContainer {\r\n\twidth:122px;\r\n\tfont-family:Tahoma, Myriad, Helvetica, Arial, Verdana, sans-serif;\r\n\tfont-size:16px;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead {\r\n\tcolor:#293a4b;\r\n\tfont-size:0.9em;\r\n\tfont-weight:700;\r\n}\r\n\r\n.timeContainer thead td {\r\n\tpadding:0.25em;\r\n\tfont-size:0.80em;\r\n\tborder-bottom:1px solid #6782A8;\r\n}\r\n\r\n.timeCorner {\r\n\twidth:10px;\r\n}\r\n\r\n.cornerTopLeft {\r\n\tbackground: url(\"images/dpCurveTL.png\") top left no-repeat;\r\n}\r\n\r\n.cornerTopRight {\r\n\tbackground: url(\"images/dpCurveTR.png\") top right no-repeat;\r\n}\r\n\r\n.timeLabelContainer {\r\n\tbackground: url(\"images/dpMonthBg.png\") top left repeat-x;\r\n}\r\n\r\n.hours, .minutes, .timeBorder {\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n\r\n}\r\n\r\n.hours td, .minutes td {\r\n\tpadding:0.2em;\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n.minutes {\r\n\tborder-left:1px solid #f5d1db;\r\n}\r\n\r\n.hours {\r\n\tborder-right:1px solid #6782A8;\r\n}\r\n\r\n.hourSelector {\r\n\tborder-right:1px solid #6782A8;\r\n\tpadding:5px;\r\n\tpadding-right:10px;\r\n}\r\n\r\n.minutesSelector {\r\n\tpadding:5px;\r\n\tborder-left:1px solid #f5c7d4;\r\n\ttext-align:center;\r\n}\r\n\r\n.minutesHeading {\r\n\tpadding-left:9px !important;\r\n}\r\n\r\n.timeOptions {\r\n\tbackground-color:#F9C9D7;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft, .timeContainer .cornerBottomRight, .timeContainer .timeOptions {\r\n\tborder-top:1px solid #6782A8;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeContainer .cornerBottomRight {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeOptions {\r\n\tcolor:#fff;\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#fff;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.timeOptions .selectedItem {\r\n\tcolor:#fff !important;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.anyTimeContainer {\r\n\ttext-align:center;\r\n\tfont-weight:bold;\r\n\tfont-size:0.7em;\r\n\tpadding:0.1em;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff !important;\r\n}\r\n\r\n.amPmContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.amPmContainer td {\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n\r\n\r\n/*.timePickerContainer {\r\n\tmargin:1.75em 0 0.5em 0;\r\n\twidth:10em;\r\n\tfloat:left;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead td{\r\n\tborder-bottom:1px solid #e6e6e6;\r\n\tpadding:0 0.4em 0.2em 0.4em;\r\n}\r\n\r\n.timeContainer td {\r\n\tfont-size:0.9em;\r\n\tpadding:0 0.25em 0 0.25em;\r\n\ttext-align:left;\r\n\tcursor:pointer;cursor:hand;\r\n}\r\n\r\n.timeContainer td.minutesHeading {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\t\r\n}\r\n\r\n.timeContainer .minutes {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#3a3a3a;\r\n\tcolor:#ffffff;\r\n}*/\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/TimePicker.css"),postMixInProperties:function(_dba,frag){ +dojo.widget.TimePicker.superclass.postMixInProperties.apply(this,arguments); +this.calendar=dojo.i18n.getLocalization("dojo.i18n.calendar","gregorian",this.lang); +this.widgetStrings=dojo.i18n.getLocalization("dojo.widget","TimePicker",this.lang); +},fillInTemplate:function(args,frag){ +var _dbe=this.getFragNodeRef(frag); +dojo.html.copyStyle(this.domNode,_dbe); +if(args.value){ +if(args.value instanceof Date){ +this.storedTime=dojo.date.toRfc3339(args.value); +}else{ +this.storedTime=args.value; +} +} +this.initData(); +this.initUI(); +},initData:function(){ +if(this.storedTime.indexOf("T")!=-1&&this.storedTime.split("T")[1]&&this.storedTime!=" "&&this.storedTime.split("T")[1]!="any"){ +this.time=dojo.widget.TimePicker.util.fromRfcDateTime(this.storedTime,this.useDefaultMinutes,this.selectedTime.anyTime); +}else{ +if(this.useDefaultTime){ +this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",this.useDefaultMinutes,this.selectedTime.anyTime); +}else{ +this.selectedTime.anyTime=true; +this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",0,1); +} +} +},initUI:function(){ +if(!this.selectedTime.anyTime&&this.time){ +var _dbf=dojo.widget.TimePicker.util.toAmPmHour(this.time.getHours()); +var hour=_dbf[0]; +var isAm=_dbf[1]; +var _dc2=this.time.getMinutes(); +var _dc3=parseInt(_dc2/5); +this.onSetSelectedHour(this.hourIndexMap[hour]); +this.onSetSelectedMinute(this.minuteIndexMap[_dc3]); +this.onSetSelectedAmPm(isAm); +}else{ +this.onSetSelectedAnyTime(); +} +},setTime:function(date){ +if(date){ +this.selectedTime.anyTime=false; +this.setDateTime(dojo.date.toRfc3339(date)); +}else{ +this.selectedTime.anyTime=true; +} +this.initData(); +this.initUI(); +},setDateTime:function(_dc5){ +this.storedTime=_dc5; +},onClearSelectedHour:function(evt){ +this.clearSelectedHour(); +},onClearSelectedMinute:function(evt){ +this.clearSelectedMinute(); +},onClearSelectedAmPm:function(evt){ +this.clearSelectedAmPm(); +},onClearSelectedAnyTime:function(evt){ +this.clearSelectedAnyTime(); +if(this.selectedTime.anyTime){ +this.selectedTime.anyTime=false; +this.time=dojo.widget.TimePicker.util.fromRfcDateTime("",this.useDefaultMinutes); +this.initUI(); +} +},clearSelectedHour:function(){ +var _dca=this.hourContainerNode.getElementsByTagName("td"); +for(var i=0;i<_dca.length;i++){ +dojo.html.setClass(_dca.item(i),""); +} +},clearSelectedMinute:function(){ +var _dcc=this.minuteContainerNode.getElementsByTagName("td"); +for(var i=0;i<_dcc.length;i++){ +dojo.html.setClass(_dcc.item(i),""); +} +},clearSelectedAmPm:function(){ +var _dce=this.amPmContainerNode.getElementsByTagName("td"); +for(var i=0;i<_dce.length;i++){ +dojo.html.setClass(_dce.item(i),""); +} +},clearSelectedAnyTime:function(){ +dojo.html.setClass(this.anyTimeContainerNode,"anyTimeContainer"); +},onSetSelectedHour:function(evt){ +this.onClearSelectedAnyTime(); +this.onClearSelectedHour(); +this.setSelectedHour(evt); +this.onSetTime(); +},setSelectedHour:function(evt){ +if(evt&&evt.target){ +if(evt.target.nodeType==dojo.dom.ELEMENT_NODE){ +var _dd2=evt.target; +}else{ +var _dd2=evt.target.parentNode; +} +dojo.event.browser.stopEvent(evt); +dojo.html.setClass(_dd2,this.classNames.selectedTime); +this.selectedTime["hour"]=_dd2.innerHTML; +}else{ +if(!isNaN(evt)){ +var _dd3=this.hourContainerNode.getElementsByTagName("td"); +if(_dd3.item(evt)){ +dojo.html.setClass(_dd3.item(evt),this.classNames.selectedTime); +this.selectedTime["hour"]=_dd3.item(evt).innerHTML; +} +} +} +this.selectedTime.anyTime=false; +},onSetSelectedMinute:function(evt){ +this.onClearSelectedAnyTime(); +this.onClearSelectedMinute(); +this.setSelectedMinute(evt); +this.selectedTime.anyTime=false; +this.onSetTime(); +},setSelectedMinute:function(evt){ +if(evt&&evt.target){ +if(evt.target.nodeType==dojo.dom.ELEMENT_NODE){ +var _dd6=evt.target; +}else{ +var _dd6=evt.target.parentNode; +} +dojo.event.browser.stopEvent(evt); +dojo.html.setClass(_dd6,this.classNames.selectedTime); +this.selectedTime["minute"]=_dd6.innerHTML; +}else{ +if(!isNaN(evt)){ +var _dd7=this.minuteContainerNode.getElementsByTagName("td"); +if(_dd7.item(evt)){ +dojo.html.setClass(_dd7.item(evt),this.classNames.selectedTime); +this.selectedTime["minute"]=_dd7.item(evt).innerHTML; +} +} +} +},onSetSelectedAmPm:function(evt){ +this.onClearSelectedAnyTime(); +this.onClearSelectedAmPm(); +this.setSelectedAmPm(evt); +this.selectedTime.anyTime=false; +this.onSetTime(); +},setSelectedAmPm:function(evt){ +var _dda=evt.target; +if(evt&&_dda){ +if(_dda.nodeType!=dojo.dom.ELEMENT_NODE){ +_dda=_dda.parentNode; +} +dojo.event.browser.stopEvent(evt); +this.selectedTime.amPm=_dda.id; +dojo.html.setClass(_dda,this.classNames.selectedTime); +}else{ +evt=evt?0:1; +var _ddb=this.amPmContainerNode.getElementsByTagName("td"); +if(_ddb.item(evt)){ +this.selectedTime.amPm=_ddb.item(evt).id; +dojo.html.setClass(_ddb.item(evt),this.classNames.selectedTime); +} +} +},onSetSelectedAnyTime:function(evt){ +this.onClearSelectedHour(); +this.onClearSelectedMinute(); +this.onClearSelectedAmPm(); +this.setSelectedAnyTime(); +this.onSetTime(); +},setSelectedAnyTime:function(evt){ +this.selectedTime.anyTime=true; +dojo.html.setClass(this.anyTimeContainerNode,this.classNames.selectedTime+" "+"anyTimeContainer"); +},onClick:function(evt){ +dojo.event.browser.stopEvent(evt); +},onSetTime:function(){ +if(this.selectedTime.anyTime){ +this.time=new Date(); +var _ddf=dojo.widget.TimePicker.util.toRfcDateTime(this.time); +this.setDateTime(_ddf.split("T")[0]); +}else{ +var hour=12; +var _de1=0; +var isAm=false; +if(this.selectedTime["hour"]){ +hour=parseInt(this.selectedTime["hour"],10); +} +if(this.selectedTime["minute"]){ +_de1=parseInt(this.selectedTime["minute"],10); +} +if(this.selectedTime["amPm"]){ +isAm=(this.selectedTime["amPm"].toLowerCase()=="am"); +} +this.time=new Date(); +this.time.setHours(dojo.widget.TimePicker.util.fromAmPmHour(hour,isAm)); +this.time.setMinutes(_de1); +this.setDateTime(dojo.widget.TimePicker.util.toRfcDateTime(this.time)); +} +this.onValueChanged(this.time); +},onValueChanged:function(date){ +}}); +dojo.widget.TimePicker.util=new function(){ +this.toRfcDateTime=function(_de4){ +if(!_de4){ +_de4=new Date(); +} +_de4.setSeconds(0); +return dojo.date.strftime(_de4,"%Y-%m-%dT%H:%M:00%z"); +}; +this.fromRfcDateTime=function(_de5,_de6,_de7){ +var _de8=new Date(); +if(!_de5||_de5.indexOf("T")==-1){ +if(_de6){ +_de8.setMinutes(Math.floor(_de8.getMinutes()/5)*5); +}else{ +_de8.setMinutes(0); +} +}else{ +var _de9=_de5.split("T")[1].split(":"); +var _de8=new Date(); +_de8.setHours(_de9[0]); +_de8.setMinutes(_de9[1]); +} +return _de8; +}; +this.toAmPmHour=function(hour){ +var _deb=hour; +var isAm=true; +if(_deb==0){ +_deb=12; +}else{ +if(_deb>12){ +_deb=_deb-12; +isAm=false; +}else{ +if(_deb==12){ +isAm=false; +} +} +} +return [_deb,isAm]; +}; +this.fromAmPmHour=function(_ded,isAm){ +var hour=parseInt(_ded,10); +if(isAm&&hour==12){ +hour=0; +}else{ +if(!isAm&&hour<12){ +hour=hour+12; +} +} +return hour; +}; +}; +dojo.provide("dojo.widget.DropdownTimePicker"); +dojo.widget.defineWidget("dojo.widget.DropdownTimePicker",dojo.widget.DropdownContainer,{iconURL:dojo.uri.moduleUri("dojo.widget","templates/images/timeIcon.gif"),formatLength:"short",displayFormat:"",timeFormat:"",saveFormat:"",value:"",name:"",postMixInProperties:function(){ +dojo.widget.DropdownTimePicker.superclass.postMixInProperties.apply(this,arguments); +var _df0=dojo.i18n.getLocalization("dojo.widget","DropdownTimePicker",this.lang); +this.iconAlt=_df0.selectTime; +if(typeof (this.value)=="string"&&this.value.toLowerCase()=="today"){ +this.value=new Date(); +} +if(this.value&&isNaN(this.value)){ +var orig=this.value; +this.value=dojo.date.fromRfc3339(this.value); +if(!this.value){ +var d=dojo.date.format(new Date(),{selector:"dateOnly",datePattern:"yyyy-MM-dd"}); +var c=orig.split(":"); +for(var i=0;i\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\"↑\"\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\r\n",templateCssString:".datePickerContainer {\r\n\twidth:164px; /* needed for proper user styling */\r\n}\r\n\r\n.calendarContainer {\r\n/*\tborder:1px solid #566f8f;*/\r\n}\r\n\r\n.calendarBodyContainer {\r\n\twidth:100%; /* needed for the explode effect (explain?) */\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer thead tr td {\r\n\tcolor:#293a4b;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.25em;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer tbody tr td {\r\n\tcolor:#fff;\r\n\tfont:bold 0.7em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.4em;\r\n\tbackground: url(\"images/dpVertLine.gif\") top right repeat-y;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n}\r\n\r\n\r\n.monthWrapper {\r\n\tpadding-bottom:2px;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.monthContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.monthLabelContainer {\r\n\ttext-align:center;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\tbackground: url(\"images/dpMonthBg.png\") repeat-x top left !important;\r\n\tcolor:#293a4b;\r\n\tpadding:0.25em;\r\n}\r\n\r\n.monthCurve {\r\n\twidth:12px;\r\n}\r\n\r\n.monthCurveTL {\r\n\tbackground: url(\"images/dpCurveTL.png\") no-repeat top left !important;\r\n}\r\n\r\n.monthCurveTR {\r\n\t\tbackground: url(\"images/dpCurveTR.png\") no-repeat top right !important;\r\n}\r\n\r\n\r\n.yearWrapper {\r\n\tbackground: url(\"images/dpHorizLineFoot.gif\") top left repeat-x;\r\n\tpadding-top:2px;\r\n}\r\n\r\n.yearContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.yearContainer td {\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n}\r\n\r\n.yearContainer .yearLabel {\r\n\tmargin:0;\r\n\tpadding:0.45em 0 0.45em 0;\r\n\tcolor:#fff;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n}\r\n\r\n.curveBL {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.curveBR {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n\r\n.previousMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n\r\n.previousMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important\r\n}\r\n.currentMonth {\r\n}\r\n\r\n.currentMonthDisabled {\r\n\tbackground-color:#bbbbbc !important;\r\n\tcursor:default !important\r\n}\r\n.nextMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n.nextMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important;\r\n}\r\n\r\n.currentDate {\r\n\ttext-decoration:underline;\r\n\tfont-style:italic;\r\n}\r\n\r\n.selectedDate {\r\n\tbackground-color:#fff !important;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.yearLabel .selectedYear {\r\n\tpadding:0.2em;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.nextYear, .previousYear {\r\n\tcursor:pointer;cursor:hand;\r\n\tpadding:0;\r\n}\r\n\r\n.nextYear {\r\n\tmargin:0 0 0 0.55em;\r\n}\r\n\r\n.previousYear {\r\n\tmargin:0 0.55em 0 0;\r\n}\r\n\r\n.incrementControl {\r\n\tcursor:pointer;cursor:hand;\r\n\twidth:1em;\r\n}\r\n\r\n.increase {\r\n\tfloat:right;\r\n}\r\n\r\n.decrease {\r\n\tfloat:left;\r\n}\r\n\r\n.lastColumn {\r\n\tbackground-image:none !important;\r\n}\r\n\r\n\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/DatePicker.css"),postMixInProperties:function(){ +dojo.widget.DatePicker.superclass.postMixInProperties.apply(this,arguments); +if(!this.weekStartsOn){ +this.weekStartsOn=dojo.date.getFirstDayOfWeek(this.lang); +} +this.today=new Date(); +this.today.setHours(0,0,0,0); +if(typeof (this.value)=="string"&&this.value.toLowerCase()=="today"){ +this.value=new Date(); +}else{ +if(this.value&&(typeof this.value=="string")&&(this.value.split("-").length>2)){ +this.value=dojo.date.fromRfc3339(this.value); +this.value.setHours(0,0,0,0); +} +} +},fillInTemplate:function(args,frag){ +dojo.widget.DatePicker.superclass.fillInTemplate.apply(this,arguments); +var _e0e=this.getFragNodeRef(frag); +dojo.html.copyStyle(this.domNode,_e0e); +this.weekTemplate=dojo.dom.removeNode(this.calendarWeekTemplate); +this._preInitUI(this.value?this.value:this.today,false,true); +var _e0f=dojo.lang.unnest(dojo.date.getNames("days",this.dayWidth,"standAlone",this.lang)); +if(this.weekStartsOn>0){ +for(var i=0;ithis.endDate){ +_e14=new Date((_e14days){ +this._preInitUI(this.startDate,true,false); +_e17=new Date(this.firstDay); +} +this.curMonth=new Date(_e17); +this.curMonth.setDate(_e17.getDate()+6); +this.curMonth.setDate(1); +var _e1a=(_e17.getMonth()==this.curMonth.getMonth())?"current":"previous"; +} +if(_e16){ +this._initUI(days); +} +},_initUI:function(days){ +dojo.dom.removeChildren(this.calendarDatesContainerNode); +for(var i=0;ithis.endDate){ +_e27=_e29=_e2b=false; +} +if(_e28&&add(d,DAY,-1)this.endDate){ +_e29=_e2b=false; +} +if(_e2a&&add(d2,YEAR,-1)this.endDate){ +_e2b=false; +} +} +function enableControl(node,_e2e){ +dojo.html.setVisibility(node,_e2e?"":"hidden"); +} +enableControl(this.decreaseWeekNode,_e26); +enableControl(this.increaseWeekNode,_e27); +enableControl(this.decreaseMonthNode,_e28); +enableControl(this.increaseMonthNode,_e29); +enableControl(this.previousYearLabelNode,_e2a); +enableControl(this.nextYearLabelNode,_e2b); +},_incrementWeek:function(evt){ +var d=new Date(this.firstDay); +switch(evt.target){ +case this.increaseWeekNode.getElementsByTagName("img").item(0): +case this.increaseWeekNode: +var _e31=dojo.date.add(d,dojo.date.dateParts.WEEK,1); +if(_e31=this.startDate){ +d=dojo.date.add(d,dojo.date.dateParts.WEEK,-1); +} +break; +} +this._preInitUI(d,true,true); +},_incrementMonth:function(evt){ +var d=new Date(this.curMonth); +var _e34=new Date(this.firstDay); +switch(evt.currentTarget){ +case this.increaseMonthNode.getElementsByTagName("img").item(0): +case this.increaseMonthNode: +_e34=dojo.date.add(_e34,dojo.date.dateParts.DAY,this.displayWeeks*7); +if(_e34this.startDate){ +d=dojo.date.add(d,dojo.date.dateParts.MONTH,-1); +}else{ +var _e36=true; +} +break; +} +if(_e36){ +d=new Date(this.startDate); +}else{ +if(_e35){ +d=new Date(this.endDate); +} +} +this._preInitUI(d,false,true); +},_incrementYear:function(evt){ +var year=this.curMonth.getFullYear(); +var _e39=new Date(this.firstDay); +switch(evt.target){ +case this.nextYearLabelNode: +_e39=dojo.date.add(_e39,dojo.date.dateParts.YEAR,1); +if(_e39this.startDate){ +year--; +}else{ +var _e3b=true; +} +break; +} +var d; +if(_e3b){ +d=new Date(this.startDate); +}else{ +if(_e3a){ +d=new Date(this.endDate); +}else{ +d=new Date(year,this.curMonth.getMonth(),1); +} +} +this._preInitUI(d,false,true); +},onIncrementWeek:function(evt){ +evt.stopPropagation(); +if(!this.staticDisplay){ +this._incrementWeek(evt); +} +},onIncrementMonth:function(evt){ +evt.stopPropagation(); +if(!this.staticDisplay){ +this._incrementMonth(evt); +} +},onIncrementYear:function(evt){ +evt.stopPropagation(); +if(!this.staticDisplay){ +this._incrementYear(evt); +} +},_setMonthLabel:function(_e40){ +this.monthLabelNode.innerHTML=dojo.date.getNames("months","wide","standAlone",this.lang)[_e40]; +},_setYearLabels:function(year){ +var y=year-1; +var that=this; +function f(n){ +that[n+"YearLabelNode"].innerHTML=dojo.date.format(new Date(y++,0),{formatLength:"yearOnly",locale:that.lang}); +} +f("previous"); +f("current"); +f("next"); +},_getDateClassName:function(date,_e46){ +var _e47=this.classNames[_e46]; +if((!this.selectedIsUsed&&this.value)&&(Number(date)==Number(this.value))){ +_e47=this.classNames.selectedDate+" "+_e47; +this.selectedIsUsed=true; +} +if((!this.currentIsUsed)&&(Number(date)==Number(this.today))){ +_e47=_e47+" "+this.classNames.currentDate; +this.currentIsUsed=true; +} +return _e47; +},onClick:function(evt){ +dojo.event.browser.stopEvent(evt); +},_handleUiClick:function(evt){ +var _e4a=evt.target; +if(_e4a.nodeType!=dojo.dom.ELEMENT_NODE){ +_e4a=_e4a.parentNode; +} +dojo.event.browser.stopEvent(evt); +this.selectedIsUsed=this.todayIsUsed=false; +if(dojo.html.hasClass(_e4a,this.classNames["disabledPrevious"])||dojo.html.hasClass(_e4a,this.classNames["disabledCurrent"])||dojo.html.hasClass(_e4a,this.classNames["disabledNext"])){ +return; +} +this.clickedNode=_e4a; +this.setDate(new Date(Number(dojo.html.getAttribute(_e4a,"djDateValue")))); +},onValueChanged:function(date){ +},_isDisabledDate:function(_e4c){ +if(_e4cthis.endDate){ +return true; +} +return this.isDisabledDate(_e4c,this.lang); +},isDisabledDate:function(_e4d,_e4e){ +return false; +},_initFirstDay:function(_e4f,adj){ +var d=new Date(_e4f); +if(!adj){ +d.setDate(1); +} +d.setDate(d.getDate()-this._getAdjustedDay(d,this.weekStartsOn)); +d.setHours(0,0,0,0); +return d; +},_getAdjustedDay:function(_e52){ +var days=[0,1,2,3,4,5,6]; +if(this.weekStartsOn>0){ +for(var i=0;ithis.datePicker.endDate){ +this.inputNode.value=""; +} +this._syncValueNode(); +this.onValueChanged(this.getDate()); +this.hideContainer(); +},onValueChanged:function(_e5e){ +},onInputChange:function(){ +var _e5f=dojo.string.trim(this.inputNode.value); +if(_e5f){ +var _e60=dojo.date.parse(_e5f,{formatLength:this.formatLength,datePattern:this.displayFormat,selector:"dateOnly",locale:this.lang}); +if(!this.datePicker._isDisabledDate(_e60)){ +this.setDate(_e60); +} +}else{ +if(_e5f==""){ +this.datePicker.setDate(""); +} +this.valueNode.value=_e5f; +} +if(_e5f){ +this._updateText(); +} +},_syncValueNode:function(){ +var date=this.datePicker.value; +var _e62=""; +switch(this.saveFormat.toLowerCase()){ +case "rfc": +case "iso": +case "": +_e62=dojo.date.toRfc3339(date,"dateOnly"); +break; +case "posix": +case "unix": +_e62=Number(date); +break; +default: +if(date){ +_e62=dojo.date.format(date,{datePattern:this.saveFormat,selector:"dateOnly",locale:this.lang}); +} +} +this.valueNode.value=_e62; +},destroy:function(_e63){ +this.datePicker.destroy(_e63); +dojo.widget.DropdownDatePicker.superclass.destroy.apply(this,arguments); +}}); +dojo.provide("struts.widget.StrutsDatePicker"); +dojo.widget.defineWidget("struts.widget.StrutsDatePicker",dojo.widget.DropdownDatePicker,{widgetType:"StrutsDatePicker",valueNotifyTopics:"",valueNotifyTopicsArray:null,tabIndex:"",postCreate:function(){ +struts.widget.StrutsDatePicker.superclass.postCreate.apply(this,arguments); +if(this.extraArgs["class"]){ +dojo.html.setClass(this.inputNode,this.extraArgs["class"]); +} +if(this.extraArgs.style){ +dojo.html.setStyleText(this.inputNode,this.extraArgs.style); +} +if(!dojo.string.isBlank(this.valueNotifyTopics)){ +this.valueNotifyTopicsArray=this.valueNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.tabIndex)){ +this.inputNode.tabIndex=this.tabIndex; +} +},_syncValueNode:function(){ +var date=this.datePicker.value; +var _e65=""; +switch(this.saveFormat.toLowerCase()){ +case "rfc": +case "iso": +case "": +_e65=dojo.date.toRfc3339(date); +break; +case "posix": +case "unix": +_e65=Number(date); +break; +default: +if(date){ +_e65=dojo.date.format(date,{datePattern:this.saveFormat,selector:"dateOnly",locale:this.lang}); +} +} +this.valueNode.value=_e65; +},_updateText:function(){ +struts.widget.StrutsDatePicker.superclass._updateText.apply(this,arguments); +if(this.valueNotifyTopicsArray!=null){ +for(var i=0;i",selectedChild:"",fillInTemplate:function(args,frag){ +var _e8d=this.getFragNodeRef(frag); +dojo.html.copyStyle(this.domNode,_e8d); +dojo.widget.PageContainer.superclass.fillInTemplate.apply(this,arguments); +},postCreate:function(args,frag){ +if(this.children.length){ +dojo.lang.forEach(this.children,this._setupChild,this); +var _e90; +if(this.selectedChild){ +this.selectChild(this.selectedChild); +}else{ +for(var i=0;i0){ +this.selectChild(this.children[0],true); +} +} +},selectChild:function(page,_e96){ +page=dojo.widget.byId(page); +this.correspondingPageButton=_e96; +if(this.selectedChildWidget){ +this._hideChild(this.selectedChildWidget); +} +this.selectedChildWidget=page; +this.selectedChild=page.widgetId; +this._showChild(page); +page.isFirstChild=(page==this.children[0]); +page.isLastChild=(page==this.children[this.children.length-1]); +dojo.event.topic.publish(this.widgetId+"-selectChild",page); +},forward:function(){ +var _e97=dojo.lang.find(this.children,this.selectedChildWidget); +this.selectChild(this.children[_e97+1]); +},back:function(){ +var _e98=dojo.lang.find(this.children,this.selectedChildWidget); +this.selectChild(this.children[_e98-1]); +},onResized:function(){ +if(this.doLayout&&this.selectedChildWidget){ +with(this.selectedChildWidget.domNode.style){ +top=dojo.html.getPixelValue(this.containerNode,"padding-top",true); +left=dojo.html.getPixelValue(this.containerNode,"padding-left",true); +} +var _e99=dojo.html.getContentBox(this.containerNode); +this.selectedChildWidget.resizeTo(_e99.width,_e99.height); +} +},_showChild:function(page){ +if(this.doLayout){ +var _e9b=dojo.html.getContentBox(this.containerNode); +page.resizeTo(_e9b.width,_e9b.height); +} +page.selected=true; +page.show(); +},_hideChild:function(page){ +page.selected=false; +page.hide(); +},closeChild:function(page){ +var _e9e=page.onClose(this,page); +if(_e9e){ +this.removeChild(page); +page.destroy(); +} +},destroy:function(){ +this._beingDestroyed=true; +dojo.event.topic.destroy(this.widgetId+"-addChild"); +dojo.event.topic.destroy(this.widgetId+"-removeChild"); +dojo.event.topic.destroy(this.widgetId+"-selectChild"); +dojo.widget.PageContainer.superclass.destroy.apply(this,arguments); +}}); +dojo.widget.defineWidget("dojo.widget.PageController",dojo.widget.HtmlWidget,{templateString:"",isContainer:true,containerId:"",buttonWidget:"PageButton","class":"dojoPageController",fillInTemplate:function(){ +dojo.html.addClass(this.domNode,this["class"]); +dojo.widget.wai.setAttr(this.domNode,"waiRole","role","tablist"); +},postCreate:function(){ +this.pane2button={}; +var _e9f=dojo.widget.byId(this.containerId); +if(_e9f){ +dojo.lang.forEach(_e9f.children,this.onAddChild,this); +} +dojo.event.topic.subscribe(this.containerId+"-addChild",this,"onAddChild"); +dojo.event.topic.subscribe(this.containerId+"-removeChild",this,"onRemoveChild"); +dojo.event.topic.subscribe(this.containerId+"-selectChild",this,"onSelectChild"); +},destroy:function(){ +dojo.event.topic.unsubscribe(this.containerId+"-addChild",this,"onAddChild"); +dojo.event.topic.unsubscribe(this.containerId+"-removeChild",this,"onRemoveChild"); +dojo.event.topic.unsubscribe(this.containerId+"-selectChild",this,"onSelectChild"); +dojo.widget.PageController.superclass.destroy.apply(this,arguments); +},onAddChild:function(page){ +var _ea1=dojo.widget.createWidget(this.buttonWidget,{label:page.label,closeButton:page.closable}); +this.addChild(_ea1); +this.domNode.appendChild(_ea1.domNode); +this.pane2button[page]=_ea1; +page.controlButton=_ea1; +var _ea2=this; +dojo.event.connect(_ea1,"onClick",function(){ +_ea2.onButtonClick(page); +}); +dojo.event.connect(_ea1,"onCloseButtonClick",function(){ +_ea2.onCloseButtonClick(page); +}); +},onRemoveChild:function(page){ +if(this._currentChild==page){ +this._currentChild=null; +} +var _ea4=this.pane2button[page]; +if(_ea4){ +_ea4.destroy(); +} +this.pane2button[page]=null; +},onSelectChild:function(page){ +if(this._currentChild){ +var _ea6=this.pane2button[this._currentChild]; +_ea6.clearSelected(); +} +var _ea7=this.pane2button[page]; +_ea7.setSelected(); +this._currentChild=page; +},onButtonClick:function(page){ +var _ea9=dojo.widget.byId(this.containerId); +_ea9.selectChild(page,false,this); +},onCloseButtonClick:function(page){ +var _eab=dojo.widget.byId(this.containerId); +_eab.closeChild(page); +},onKey:function(evt){ +if((evt.keyCode==evt.KEY_RIGHT_ARROW)||(evt.keyCode==evt.KEY_LEFT_ARROW)){ +var _ead=0; +var next=null; +var _ead=dojo.lang.find(this.children,this.pane2button[this._currentChild]); +if(evt.keyCode==evt.KEY_RIGHT_ARROW){ +next=this.children[(_ead+1)%this.children.length]; +}else{ +next=this.children[(_ead+(this.children.length-1))%this.children.length]; +} +dojo.event.browser.stopEvent(evt); +next.onClick(); +} +}}); +dojo.widget.defineWidget("dojo.widget.PageButton",dojo.widget.HtmlWidget,{templateString:""+"${this.label}"+"[X]"+"",label:"foo",closeButton:false,onClick:function(){ +this.focus(); +},onCloseButtonMouseOver:function(){ +dojo.html.addClass(this.closeButtonNode,"closeHover"); +},onCloseButtonMouseOut:function(){ +dojo.html.removeClass(this.closeButtonNode,"closeHover"); +},onCloseButtonClick:function(evt){ +},setSelected:function(){ +dojo.html.addClass(this.domNode,"current"); +this.titleNode.setAttribute("tabIndex","0"); +},clearSelected:function(){ +dojo.html.removeClass(this.domNode,"current"); +this.titleNode.setAttribute("tabIndex","-1"); +},focus:function(){ +if(this.titleNode.focus){ +this.titleNode.focus(); +} +}}); +dojo.lang.extend(dojo.widget.Widget,{label:"",selected:false,closable:false,onClose:function(){ +return true; +}}); +dojo.provide("dojo.widget.TabContainer"); +dojo.widget.defineWidget("dojo.widget.TabContainer",dojo.widget.PageContainer,{labelPosition:"top",closeButton:"none",templateString:null,templateString:"
\r\n\t
\r\n\t
\r\n
\r\n",templateCssString:".dojoTabContainer {\r\n\tposition : relative;\r\n}\r\n\r\n.dojoTabPaneWrapper {\r\n\tborder : 1px solid #6290d2;\r\n\t_zoom: 1; /* force IE6 layout mode so top border doesnt disappear */\r\n\tdisplay: block;\r\n\tclear: both;\r\n\toverflow: hidden;\r\n}\r\n\r\n.dojoTabLabels-top {\r\n\tposition : relative;\r\n\ttop : 0px;\r\n\tleft : 0px;\r\n\toverflow : visible;\r\n\tmargin-bottom : -1px;\r\n\twidth : 100%;\r\n\tz-index: 2;\t/* so the bottom of the tab label will cover up the border of dojoTabPaneWrapper */\r\n}\r\n\r\n.dojoTabNoLayout.dojoTabLabels-top .dojoTab {\r\n\tmargin-bottom: -1px;\r\n\t_margin-bottom: 0px; /* IE filter so top border lines up correctly */\r\n}\r\n\r\n.dojoTab {\r\n\tposition : relative;\r\n\tfloat : left;\r\n\tpadding-left : 9px;\r\n\tborder-bottom : 1px solid #6290d2;\r\n\tbackground : url(images/tab_left.gif) no-repeat left top;\r\n\tcursor: pointer;\r\n\twhite-space: nowrap;\r\n\tz-index: 3;\r\n}\r\n\r\n.dojoTab div {\r\n\tdisplay : block;\r\n\tpadding : 4px 15px 4px 6px;\r\n\tbackground : url(images/tab_top_right.gif) no-repeat right top;\r\n\tcolor : #333;\r\n\tfont-size : 90%;\r\n}\r\n\r\n.dojoTab .close {\r\n\tdisplay : inline-block;\r\n\theight : 12px;\r\n\twidth : 12px;\r\n\tpadding : 0 12px 0 0;\r\n\tmargin : 0 -10px 0 10px;\r\n\tcursor : default;\r\n\tfont-size: small;\r\n}\r\n\r\n.dojoTab .closeImage {\r\n\tbackground : url(images/tab_close.gif) no-repeat right top;\r\n}\r\n\r\n.dojoTab .closeHover {\r\n\tbackground-image : url(images/tab_close_h.gif);\r\n}\r\n\r\n.dojoTab.current {\r\n\tpadding-bottom : 1px;\r\n\tborder-bottom : 0;\r\n\tbackground-position : 0 -150px;\r\n}\r\n\r\n.dojoTab.current div {\r\n\tpadding-bottom : 5px;\r\n\tmargin-bottom : -1px;\r\n\tbackground-position : 100% -150px;\r\n}\r\n\r\n/* bottom tabs */\r\n\r\n.dojoTabLabels-bottom {\r\n\tposition : relative;\r\n\tbottom : 0px;\r\n\tleft : 0px;\r\n\toverflow : visible;\r\n\tmargin-top : -1px;\r\n\twidth : 100%;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabNoLayout.dojoTabLabels-bottom {\r\n\tposition : relative;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab {\r\n\tborder-top : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tbackground : url(images/tab_bot_left.gif) no-repeat left bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab div {\r\n\tbackground : url(images/tab_bot_right.gif) no-repeat right bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab.current {\r\n\tborder-top : 0;\r\n\tbackground : url(images/tab_bot_left_curr.gif) no-repeat left bottom;\r\n}\r\n\r\n.dojoTabLabels-bottom .dojoTab.current div {\r\n\tpadding-top : 4px;\r\n\tbackground : url(images/tab_bot_right_curr.gif) no-repeat right bottom;\r\n}\r\n\r\n/* right-h tabs */\r\n\r\n.dojoTabLabels-right-h {\r\n\toverflow : visible;\r\n\tmargin-left : -1px;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab {\r\n\tpadding-left : 0;\r\n\tborder-left : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tbackground : url(images/tab_bot_right.gif) no-repeat right bottom;\r\n\tfloat : none;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab div {\r\n\tpadding : 4px 15px 4px 15px;\r\n}\r\n\r\n.dojoTabLabels-right-h .dojoTab.current {\r\n\tborder-left : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n}\r\n\r\n/* left-h tabs */\r\n\r\n.dojoTabLabels-left-h {\r\n\toverflow : visible;\r\n\tmargin-right : -1px;\r\n\tz-index: 2;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab {\r\n\tborder-right : 1px solid #6290d2;\r\n\tborder-bottom : 0;\r\n\tfloat : none;\r\n\tbackground : url(images/tab_top_left.gif) no-repeat left top;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab.current {\r\n\tborder-right : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n\tpadding-bottom : 0;\r\n\tbackground : url(images/tab_top_left.gif) no-repeat 0 -150px;\r\n}\r\n\r\n.dojoTabLabels-left-h .dojoTab div {\r\n\tbackground : 0;\r\n\tborder-bottom : 1px solid #6290d2;\r\n}\r\n",templateCssPath:dojo.uri.moduleUri("dojo.widget","templates/TabContainer.css"),selectedTab:"",postMixInProperties:function(){ +if(this.selectedTab){ +dojo.deprecated("selectedTab deprecated, use selectedChild instead, will be removed in","0.5"); +this.selectedChild=this.selectedTab; +} +if(this.closeButton!="none"){ +dojo.deprecated("closeButton deprecated, use closable='true' on each child instead, will be removed in","0.5"); +} +dojo.widget.TabContainer.superclass.postMixInProperties.apply(this,arguments); +},fillInTemplate:function(){ +this.tablist=dojo.widget.createWidget("TabController",{id:this.widgetId+"_tablist",labelPosition:this.labelPosition,doLayout:this.doLayout,containerId:this.widgetId},this.tablistNode); +dojo.widget.TabContainer.superclass.fillInTemplate.apply(this,arguments); +},postCreate:function(args,frag){ +dojo.widget.TabContainer.superclass.postCreate.apply(this,arguments); +this.onResized(); +},_setupChild:function(tab){ +if(this.closeButton=="tab"||this.closeButton=="pane"){ +tab.closable=true; +} +dojo.html.addClass(tab.domNode,"dojoTabPane"); +dojo.widget.TabContainer.superclass._setupChild.apply(this,arguments); +},onResized:function(){ +if(!this.doLayout){ +return; +} +var _eb3=this.labelPosition.replace(/-h/,""); +var _eb4=[{domNode:this.tablist.domNode,layoutAlign:_eb3},{domNode:this.containerNode,layoutAlign:"client"}]; +dojo.widget.html.layout(this.domNode,_eb4); +if(this.selectedChildWidget){ +var _eb5=dojo.html.getContentBox(this.containerNode); +this.selectedChildWidget.resizeTo(_eb5.width,_eb5.height); +} +},selectTab:function(tab,_eb7){ +dojo.deprecated("use selectChild() rather than selectTab(), selectTab() will be removed in","0.5"); +this.selectChild(tab,_eb7); +},onKey:function(e){ +if(e.keyCode==e.KEY_UP_ARROW&&e.ctrlKey){ +var _eb9=this.correspondingTabButton||this.selectedTabWidget.tabButton; +_eb9.focus(); +dojo.event.browser.stopEvent(e); +}else{ +if(e.keyCode==e.KEY_DELETE&&e.altKey){ +if(this.selectedChildWidget.closable){ +this.closeChild(this.selectedChildWidget); +dojo.event.browser.stopEvent(e); +} +} +} +},destroy:function(){ +this.tablist.destroy(); +dojo.widget.TabContainer.superclass.destroy.apply(this,arguments); +}}); +dojo.widget.defineWidget("dojo.widget.TabController",dojo.widget.PageController,{templateString:"
",labelPosition:"top",doLayout:true,"class":"",buttonWidget:"TabButton",postMixInProperties:function(){ +if(!this["class"]){ +this["class"]="dojoTabLabels-"+this.labelPosition+(this.doLayout?"":" dojoTabNoLayout"); +} +dojo.widget.TabController.superclass.postMixInProperties.apply(this,arguments); +}}); +dojo.widget.defineWidget("dojo.widget.TabButton",dojo.widget.PageButton,{templateString:"
"+"
"+"${this.label}"+""+"
"+"
",postMixInProperties:function(){ +this.closeButtonStyle=this.closeButton?"":"display: none"; +dojo.widget.TabButton.superclass.postMixInProperties.apply(this,arguments); +},fillInTemplate:function(){ +dojo.html.disableSelection(this.titleNode); +dojo.widget.TabButton.superclass.fillInTemplate.apply(this,arguments); +},onCloseButtonClick:function(evt){ +evt.stopPropagation(); +dojo.widget.TabButton.superclass.onCloseButtonClick.apply(this,arguments); +}}); +dojo.widget.defineWidget("dojo.widget.a11y.TabButton",dojo.widget.TabButton,{imgPath:dojo.uri.moduleUri("dojo.widget","templates/images/tab_close.gif"),templateString:"
"+"
"+"${this.label}"+"[x]"+"
"+"
"}); +dojo.provide("struts.widget.StrutsTabContainer"); +dojo.widget.defineWidget("struts.widget.StrutsTabContainer",dojo.widget.TabContainer,{widgetType:"StrutsTabContainer",afterSelectTabNotifyTopics:"",afterSelectTabNotifyTopicsArray:null,beforeSelectTabNotifyTopics:"",beforeSelectTabNotifyTopicsArray:null,disabledTabCssClass:"strutsDisabledTab",postCreate:function(){ +struts.widget.StrutsTabContainer.superclass.postCreate.apply(this); +if(!dojo.string.isBlank(this.beforeSelectTabNotifyTopics)){ +this.beforeSelectTabNotifyTopicsArray=this.beforeSelectTabNotifyTopics.split(","); +} +if(!dojo.string.isBlank(this.afterSelectTabNotifyTopics)){ +this.afterSelectTabNotifyTopicsArray=this.afterSelectTabNotifyTopics.split(","); +} +if(this.disabledTabCssClass){ +dojo.lang.forEach(this.children,function(div){ +if(div.disabled){ +this.disableTab(div); +} +}); +} +},selectChild:function(tab,_ebd){ +if(!tab.disabled){ +var _ebe={"cancel":false}; +if(this.beforeSelectTabNotifyTopicsArray){ +var self=this; +dojo.lang.forEach(this.beforeSelectTabNotifyTopicsArray,function(_ec0){ +try{ +dojo.event.topic.publish(_ec0,_ebe,tab,self); +} +catch(ex){ +dojo.debug(ex); +} +}); +} +if(!_ebe.cancel){ +struts.widget.StrutsTabContainer.superclass.selectChild.apply(this,[tab,_ebd]); +if(this.afterSelectTabNotifyTopicsArray){ +var self=this; +dojo.lang.forEach(this.afterSelectTabNotifyTopicsArray,function(_ec1){ +try{ +dojo.event.topic.publish(_ec1,tab,self); +} +catch(ex){ +dojo.debug(ex); +} +}); +} +} +} +},disableTab:function(t){ +var _ec3=this.getTabWidget(t); +_ec3.disabled=true; +dojo.html.addClass(_ec3.controlButton.domNode,this.disabledTabCssClass); +},enableTab:function(t){ +var _ec5=this.getTabWidget(t); +_ec5.disabled=false; +dojo.html.removeClass(_ec5.controlButton.domNode,this.disabledTabCssClass); +},getTabWidget:function(t){ +if(dojo.lang.isNumber(t)){ +return this.children[t]; +}else{ +if(dojo.lang.isString(t)){ +return dojo.widget.byId(t); +}else{ +return t; +} +} +}}); +dojo.provide("dojo.widget.TreeNode"); +dojo.widget.defineWidget("dojo.widget.TreeNode",dojo.widget.HtmlWidget,function(){ +this.actionsDisabled=[]; +},{widgetType:"TreeNode",loadStates:{UNCHECKED:"UNCHECKED",LOADING:"LOADING",LOADED:"LOADED"},actions:{MOVE:"MOVE",REMOVE:"REMOVE",EDIT:"EDIT",ADDCHILD:"ADDCHILD"},isContainer:true,lockLevel:0,templateString:("
"+" "+"\t\t${this.title} "+" "+"${this.afterLabel} "+"
"+"
").replace(/(>|<)\s+/g,"$1"),childIconSrc:"",childIconFolderSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/closed.gif"),childIconDocumentSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/document.gif"),childIcon:null,isTreeNode:true,objectId:"",afterLabel:"",afterLabelNode:null,expandIcon:null,title:"",object:"",isFolder:false,labelNode:null,titleNode:null,imgs:null,expandLevel:"",tree:null,depth:0,isExpanded:false,state:null,domNodeInitialized:false,isFirstChild:function(){ +return this.getParentIndex()==0?true:false; +},isLastChild:function(){ +return this.getParentIndex()==this.parent.children.length-1?true:false; +},lock:function(){ +return this.tree.lock.apply(this,arguments); +},unlock:function(){ +return this.tree.unlock.apply(this,arguments); +},isLocked:function(){ +return this.tree.isLocked.apply(this,arguments); +},cleanLock:function(){ +return this.tree.cleanLock.apply(this,arguments); +},actionIsDisabled:function(_ec7){ +var _ec8=this; +var _ec9=false; +if(this.tree.strictFolders&&_ec7==this.actions.ADDCHILD&&!this.isFolder){ +_ec9=true; +} +if(dojo.lang.inArray(_ec8.actionsDisabled,_ec7)){ +_ec9=true; +} +if(this.isLocked()){ +_ec9=true; +} +return _ec9; +},getInfo:function(){ +var info={widgetId:this.widgetId,objectId:this.objectId,index:this.getParentIndex(),isFolder:this.isFolder}; +return info; +},initialize:function(args,frag){ +this.state=this.loadStates.UNCHECKED; +for(var i=0;i0){ +for(var i=0;i<_ece;i++){ +var img=this.tree.makeBlankImg(); +this.imgs.unshift(img); +dojo.html.insertBefore(this.imgs[0],this.domNode.firstChild); +} +} +if(_ece<0){ +for(var i=0;i<-_ece;i++){ +this.imgs.shift(); +dojo.html.removeNode(this.domNode.firstChild); +} +} +},markLoading:function(){ +this._markLoadingSavedIcon=this.expandIcon.src; +this.expandIcon.src=this.tree.expandIconSrcLoading; +},unMarkLoading:function(){ +if(!this._markLoadingSavedIcon){ +return; +} +var im=new Image(); +im.src=this.tree.expandIconSrcLoading; +if(this.expandIcon.src==im.src){ +this.expandIcon.src=this._markLoadingSavedIcon; +} +this._markLoadingSavedIcon=null; +},setFolder:function(){ +dojo.event.connect(this.expandIcon,"onclick",this,"onTreeClick"); +this.expandIcon.src=this.isExpanded?this.tree.expandIconSrcMinus:this.tree.expandIconSrcPlus; +this.isFolder=true; +},createDOMNode:function(tree,_ed3){ +this.tree=tree; +this.depth=_ed3; +this.imgs=[]; +for(var i=0;i-1?"&":"?")+"nodeId="+this.widgetId; +var self=this; +this.markLoading(); +dojo.io.bind({url:_ee8,useCache:false,preventCache:true,handler:function(type,data,e){ +if(type=="load"){ +if(data){ +dojo.lang.forEach(data,function(_eed){ +var _eee=dojo.widget.createWidget("struts:StrutsTreeNode",{title:_eed.label,isFolder:_eed.hasChildren,widgetId:_eed.id}); +self.addChild(_eee); +}); +} +} +self.unMarkLoading(); +},mimetype:"text/json"}); +} +}}); +dojo.provide("dojo.json"); +dojo.json={jsonRegistry:new dojo.AdapterRegistry(),register:function(name,_ef0,wrap,_ef2){ +dojo.json.jsonRegistry.register(name,_ef0,wrap,_ef2); +},evalJson:function(json){ +try{ +return eval("("+json+")"); +} +catch(e){ +dojo.debug(e); +return json; +} +},serialize:function(o){ +var _ef5=typeof (o); +if(_ef5=="undefined"){ +return "undefined"; +}else{ +if((_ef5=="number")||(_ef5=="boolean")){ +return o+""; +}else{ +if(o===null){ +return "null"; +} +} +} +if(_ef5=="string"){ +return dojo.string.escapeString(o); +} +var me=arguments.callee; +var _ef7; +if(typeof (o.__json__)=="function"){ +_ef7=o.__json__(); +if(o!==_ef7){ +return me(_ef7); +} +} +if(typeof (o.json)=="function"){ +_ef7=o.json(); +if(o!==_ef7){ +return me(_ef7); +} +} +if(_ef5!="function"&&typeof (o.length)=="number"){ +var res=[]; +for(var i=0;i_f29.getParentIndex()){ +_f2b--; +} +return _f2b; +},onDrop:function(e){ +var _f2d=this.position; +this.onDragOut(e); +var _f2e=e.dragObject.treeNode; +if(!dojo.lang.isObject(_f2e)){ +dojo.raise("TreeNode not found in dragObject"); +} +if(_f2d=="onto"){ +return this.controller.move(_f2e,this.treeNode,0); +}else{ +var _f2f=this.getTargetParentIndex(_f2e,_f2d); +return this.controller.move(_f2e,this.treeNode.parent,_f2f); +} +}}); +dojo.dnd.TreeDNDController=function(_f30){ +this.treeController=_f30; +this.dragSources={}; +this.dropTargets={}; +}; +dojo.lang.extend(dojo.dnd.TreeDNDController,{listenTree:function(tree){ +dojo.event.topic.subscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); +dojo.event.topic.subscribe(tree.eventNames.moveFrom,this,"onMoveFrom"); +dojo.event.topic.subscribe(tree.eventNames.moveTo,this,"onMoveTo"); +dojo.event.topic.subscribe(tree.eventNames.addChild,this,"onAddChild"); +dojo.event.topic.subscribe(tree.eventNames.removeNode,this,"onRemoveNode"); +dojo.event.topic.subscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); +},unlistenTree:function(tree){ +dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); +dojo.event.topic.unsubscribe(tree.eventNames.moveFrom,this,"onMoveFrom"); +dojo.event.topic.unsubscribe(tree.eventNames.moveTo,this,"onMoveTo"); +dojo.event.topic.unsubscribe(tree.eventNames.addChild,this,"onAddChild"); +dojo.event.topic.unsubscribe(tree.eventNames.removeNode,this,"onRemoveNode"); +dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); +},onTreeDestroy:function(_f33){ +this.unlistenTree(_f33.source); +},onCreateDOMNode:function(_f34){ +this.registerDNDNode(_f34.source); +},onAddChild:function(_f35){ +this.registerDNDNode(_f35.child); +},onMoveFrom:function(_f36){ +var _f37=this; +dojo.lang.forEach(_f36.child.getDescendants(),function(node){ +_f37.unregisterDNDNode(node); +}); +},onMoveTo:function(_f39){ +var _f3a=this; +dojo.lang.forEach(_f39.child.getDescendants(),function(node){ +_f3a.registerDNDNode(node); +}); +},registerDNDNode:function(node){ +if(!node.tree.DNDMode){ +return; +} +var _f3d=null; +var _f3e=null; +if(!node.actionIsDisabled(node.actions.MOVE)){ +var _f3d=new dojo.dnd.TreeDragSource(node.labelNode,this,node.tree.widgetId,node); +this.dragSources[node.widgetId]=_f3d; +} +var _f3e=new dojo.dnd.TreeDropTarget(node.labelNode,this.treeController,node.tree.DNDAcceptTypes,node); +this.dropTargets[node.widgetId]=_f3e; +},unregisterDNDNode:function(node){ +if(this.dragSources[node.widgetId]){ +dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]); +delete this.dragSources[node.widgetId]; +} +if(this.dropTargets[node.widgetId]){ +dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]); +delete this.dropTargets[node.widgetId]; +} +}}); +dojo.provide("dojo.widget.TreeBasicController"); +dojo.widget.defineWidget("dojo.widget.TreeBasicController",dojo.widget.HtmlWidget,{widgetType:"TreeBasicController",DNDController:"",dieWithTree:false,initialize:function(args,frag){ +if(this.DNDController=="create"){ +this.DNDController=new dojo.dnd.TreeDNDController(this); +} +},listenTree:function(tree){ +dojo.event.topic.subscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); +dojo.event.topic.subscribe(tree.eventNames.treeClick,this,"onTreeClick"); +dojo.event.topic.subscribe(tree.eventNames.treeCreate,this,"onTreeCreate"); +dojo.event.topic.subscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); +if(this.DNDController){ +this.DNDController.listenTree(tree); +} +},unlistenTree:function(tree){ +dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode,this,"onCreateDOMNode"); +dojo.event.topic.unsubscribe(tree.eventNames.treeClick,this,"onTreeClick"); +dojo.event.topic.unsubscribe(tree.eventNames.treeCreate,this,"onTreeCreate"); +dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy,this,"onTreeDestroy"); +},onTreeDestroy:function(_f44){ +var tree=_f44.source; +this.unlistenTree(tree); +if(this.dieWithTree){ +this.destroy(); +} +},onCreateDOMNode:function(_f46){ +var node=_f46.source; +if(node.expandLevel>0){ +this.expandToLevel(node,node.expandLevel); +} +},onTreeCreate:function(_f48){ +var tree=_f48.source; +var _f4a=this; +if(tree.expandLevel){ +dojo.lang.forEach(tree.children,function(_f4b){ +_f4a.expandToLevel(_f4b,tree.expandLevel-1); +}); +} +},expandToLevel:function(node,_f4d){ +if(_f4d==0){ +return; +} +var _f4e=node.children; +var _f4f=this; +var _f50=function(node,_f52){ +this.node=node; +this.expandLevel=_f52; +this.process=function(){ +for(var i=0;i",isExpanded:true,isTree:true,objectId:"",controller:"",selector:"",menu:"",expandLevel:"",blankIconSrc:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_blank.gif"),gridIconSrcT:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_t.gif"),gridIconSrcL:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_l.gif"),gridIconSrcV:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_v.gif"),gridIconSrcP:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_p.gif"),gridIconSrcC:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_c.gif"),gridIconSrcX:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_x.gif"),gridIconSrcY:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_y.gif"),gridIconSrcZ:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_grid_z.gif"),expandIconSrcPlus:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_expand_plus.gif"),expandIconSrcMinus:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_expand_minus.gif"),expandIconSrcLoading:dojo.uri.moduleUri("dojo.widget","templates/images/Tree/treenode_loading.gif"),iconWidth:18,iconHeight:18,showGrid:true,showRootGrid:true,actionIsDisabled:function(_f7d){ +var _f7e=this; +return dojo.lang.inArray(_f7e.actionsDisabled,_f7d); +},actions:{ADDCHILD:"ADDCHILD"},getInfo:function(){ +var info={widgetId:this.widgetId,objectId:this.objectId}; +return info; +},initializeController:function(){ +if(this.controller!="off"){ +if(this.controller){ +this.controller=dojo.widget.byId(this.controller); +}else{ +this.controller=dojo.widget.createWidget("TreeBasicController",{DNDController:(this.DNDMode?"create":""),dieWithTree:true}); +} +this.controller.listenTree(this); +}else{ +this.controller=null; +} +},initializeSelector:function(){ +if(this.selector!="off"){ +if(this.selector){ +this.selector=dojo.widget.byId(this.selector); +}else{ +this.selector=dojo.widget.createWidget("TreeSelector",{dieWithTree:true}); +} +this.selector.listenTree(this); +}else{ +this.selector=null; +} +},initialize:function(args,frag){ +var _f82=this; +for(name in this.eventNamesDefault){ +if(dojo.lang.isUndefined(this.eventNames[name])){ +this.eventNames[name]=this.widgetId+"/"+this.eventNamesDefault[name]; +} +} +for(var i=0;i0){ +_fa1[_fa2-1].updateExpandGridColumn(); +} +if(_fa0 instanceof dojo.widget.Tree&&_fa2==0&&_fa1.length>0){ +_fa1[0].updateExpandGrid(); +} +_f9f.parent=_f9f.tree=null; +return _f9f; +},markLoading:function(){ +},unMarkLoading:function(){ +},lock:function(){ +!this.lockLevel&&this.markLoading(); +this.lockLevel++; +},unlock:function(){ +if(!this.lockLevel){ +dojo.raise("unlock: not locked"); +} +this.lockLevel--; +!this.lockLevel&&this.unMarkLoading(); +},isLocked:function(){ +var node=this; +while(true){ +if(node.lockLevel){ +return true; +} +if(node instanceof dojo.widget.Tree){ +break; +} +node=node.parent; +} +return false; +},flushLock:function(){ +this.lockLevel=0; +this.unMarkLoading(); +}}); +dojo.provide("struts.widget.StrutsTree"); +dojo.widget.defineWidget("struts.widget.StrutsTree",dojo.widget.Tree,{widgetType:"StrutsTree",href:"",errorNotifyTopics:"",errorNotifyTopicsArray:null,postCreate:function(){ +struts.widget.StrutsTree.superclass.postCreate.apply(this); +if(!dojo.string.isBlank(this.errorNotifyTopics)){ +this.errorNotifyTopicsArray=this.errorNotifyTopics.split(","); +} +var self=this; +if(!dojo.string.isBlank(this.href)){ +dojo.io.bind({url:this.href,useCache:false,preventCache:true,handler:function(type,data,e){ +if(type=="load"){ +if(data){ +dojo.lang.forEach(data,function(_fa8){ +var _fa9=dojo.widget.createWidget("struts:StrutsTreeNode",{title:_fa8.label,isFolder:_fa8.hasChildren,widgetId:_fa8.id}); +self.addChild(_fa9); +}); +} +}else{ +if(self.errorNotifyTopicsArray){ +dojo.lang.forEach(self.errorNotifyTopicsArray,function(_faa){ +try{ +dojo.event.topic.publish(_faa,data,e,self); +} +catch(ex){ +dojo.debug(ex); +} +}); +} +} +},mimetype:"text/json"}); +} +}}); +dojo.kwCompoundRequire({common:["struts.widget.Bind","struts.widget.BindDiv","struts.widget.BindAnchor","struts.widget.ComboBox","struts.widget.StrutsTimePicker","struts.widget.StrutsDatePicker","struts.widget.BindEvent","struts.widget.StrutsTreeSelector","struts.widget.StrutsTabContainer","struts.widget.StrutsTreeNode","struts.widget.StrutsTree"]}); +dojo.provide("struts.widget.*"); diff --git a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js index 41293de74..36f2497b7 100644 --- a/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js +++ b/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js @@ -1,13 +1,3 @@ -/* - Copyright (c) 2004-2006, The Dojo Foundation - All Rights Reserved. - - Licensed under the Academic Free License version 2.1 or above OR the - modified BSD license. For more information on Dojo licensing, see: - - http://dojotoolkit.org/community/licensing.shtml -*/ - if(typeof dojo == "undefined"){ // TODOC: HOW TO DOC THE BELOW? @@ -921,7 +911,7 @@ dojo.hostenv.searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Fu //These two functions are placed outside of preloadLocalizations //So that the xd loading can use/override them. -dojo.hostenv.localesGenerated /***BUILD:localesGenerated***/; // value will be inserted here at build time, if necessary +dojo.hostenv.localesGenerated =["ROOT","es-es","es","it-it","pt-br","de","fr-fr","zh-cn","pt","en-us","zh","fr","zh-tw","it","en-gb","xx","de-de","ko-kr","ja-jp","ko","en","ja"]; // value will be inserted here at build time, if necessary dojo.hostenv.registerNlsPrefix = function(){ // summary: @@ -22087,3 +22077,9277 @@ dojo.widget.defineWidget( } ); +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +dojo.provide("struts.widget.Bind"); + + + + + +dojo.widget.defineWidget( + "struts.widget.Bind", + dojo.widget.HtmlWidget, { + widgetType : "Bind", + executeScripts : false, + scriptSeparation : false, + targets : "", + targetsArray : null, + href : "", + handler : "", + + //messages + loadingText : "Loading...", + errorText : "", + showError : true, + showLoading : false, + + //pub/sub events + listenTopics : "", + notifyTopics : "", + notifyTopicsArray : null, + beforeNotifyTopics : "", + beforeNotifyTopicsArray : null, + afterNotifyTopics : "", + afterNotifyTopicsArray : null, + errorNotifyTopics : "", + errorNotifyTopicsArray : null, + + formId : "", + formFilter : "", + formNode : null, + + events : "", + indicator : "", + + parseContent : true, + + highlightColor : "", + highlightDuration : 2000, + + validate : false, + ajaxAfterValidation : false, + + //used for scripts downloading & caching + cacheContent : true, + //run script on its own scope + scriptSeparation : true, + //scope for the cript separation + scriptScope : null, + transport : "", + + postCreate : function() { + var self = this; + + //attach listeners + if(!dojo.string.isBlank(this.listenTopics)) { + this.log("Listening to " + this.listenTopics + " to refresh"); + var topics = this.listenTopics.split(","); + if(topics) { + dojo.lang.forEach(topics, function(topic){ + dojo.event.topic.subscribe(topic, self, "reloadContents"); + }); + } + } + + //topics + if(!dojo.string.isBlank(this.notifyTopics)) { + this.notifyTopicsArray = this.notifyTopics.split(","); + } + + //before topics + if(!dojo.string.isBlank(this.beforeNotifyTopics)) { + this.beforeNotifyTopicsArray = this.beforeNotifyTopics.split(","); + } + + //after topics + if(!dojo.string.isBlank(this.afterNotifyTopics)) { + this.afterNotifyTopicsArray = this.afterNotifyTopics.split(","); + } + + //error topics + if(!dojo.string.isBlank(this.errorNotifyTopics)) { + this.errorNotifyTopicsArray = this.errorNotifyTopics.split(","); + } + + if(!dojo.string.isBlank(this.targets)) { + //split targets + this.targetsArray = this.targets.split(","); + } + + if(!dojo.string.isBlank(this.events)) { + var eventsArray = this.events.split(","); + if(eventsArray && this.domNode) { + dojo.lang.forEach(eventsArray, function(event){ + dojo.event.connect(self.domNode, event, function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + self.reloadContents(); + }); + }); + } + } + + if(dojo.string.isBlank(this.formId)) { + //no formId, see if we are inside a form + this.formNode = dojo.dom.getFirstAncestorByTag(this.domNode, "form"); + } else { + this.formNode = dojo.byId(this.formId); + } + + if(this.formNode && dojo.string.isBlank(this.href)) { + this.href = this.formNode.action; + } + }, + + highlight : function() { + if(!dojo.string.isBlank(this.highlightColor)) { + var nodes = []; + //add nodes to array + dojo.lang.forEach(this.targetsArray, function(target) { + var node = dojo.byId(target); + if(node) { + nodes.push(node); + } + }); + var effect = dojo.lfx.html.highlight(nodes, this.highlightColor, this.highlightDuration); + effect.play(); + } + }, + + log : function(text) { + dojo.debug("[" + (this.widgetId ? this.widgetId : "unknown") + "] " + text); + }, + + setContent : function(text) { + if(this.targetsArray) { + var self = this; + var xmlParser = new dojo.xml.Parse(); + dojo.lang.forEach(this.targetsArray, function(target) { + var node = dojo.byId(target); + if(node) { + node.innerHTML = text; + + if(self.parseContent && text != self.loadingText){ + var frag = xmlParser.parseElement(node, null, true); + dojo.widget.getParser().createSubComponents(frag, dojo.widget.byId(target)); + } + } else { + self.log("Unable to find target: " + node); + } + }); + } + }, + + bindHandler : function(type, data, e) { + //hide indicator + dojo.html.hide(this.indicator); + + //publish topics + this.notify(data, type, e); + + if(type == "load") { + if(this.validate) { + StrutsUtils.clearValidationErrors(this.formNode); + //validation is active for this action + var errors = StrutsUtils.getValidationErrors(data); + if(errors && errors.fieldErrors) { + //validation failed + StrutsUtils.showValidationErrors(this.formNode, errors); + return; + } else { + //validation passed + if(!this.ajaxAfterValidation && this.formNode) { + //regular submit + this.formNode.submit(); + return; + } + } + } + + // no validation or validation passed + if(this.executeScripts) { + //parse text to extract content and javascript + var parsed = this.parse(data); + + //update targets content + this.setContent(parsed.text); + + //execute scripts + this._executeScripts(parsed.scripts); + } + else { + this.setContent(data); + } + this.highlight(); + } else { + if(this.showError) { + var message = dojo.string.isBlank(this.errorText) ? e.message : this.errorText; + this.setContent(message); + } + } + }, + + notify : function(data, type, e) { + var self = this; + //general topics + if(this.notifyTopicsArray) { + dojo.lang.forEach(this.notifyTopicsArray, function(topic) { + try { + dojo.event.topic.publish(topic, data, type, e, self); + } catch(ex){ + self.log(ex); + } + }); + } + + //before, after and error topics + var topicsArray = null; + switch(type) { + case "before": + this.notifyTo(this.beforeNotifyTopicsArray, null, e); + break; + case "load": + this.notifyTo(this.afterNotifyTopicsArray, data, e); + break; + case "error": + this.notifyTo(this.errorNotifyTopicsArray, data, e); + break; + } + }, + + notifyTo : function(topicsArray, data, e) { + var self = this; + if(topicsArray) { + dojo.lang.forEach(topicsArray, function(topic) { + try { + if(data != null) { + dojo.event.topic.publish(topic, data, e, self); + } else { + dojo.event.topic.publish(topic, e, self); + } + } catch(ex){ + self.log(ex); + } + }); + } + }, + + onDownloadStart : function(event) { + if(this.showLoading && !dojo.string.isBlank(this.loadingText)) { + event.text = this.loadingText; + } + }, + + reloadContents : function(evt) { + if(!dojo.string.isBlank(this.handler)) { + //use custom handler + this.log("Invoking handler: " + this.handler); + window[this.handler](this, this.domNode); + } + else { + try { + var self = this; + var request = {cancel: false}; + this.notify(this.widgetId, "before", request); + if(request.cancel) { + this.log("Request canceled"); + return; + } + + //if the href is null, we still publish the notify topics + if(dojo.string.isBlank(this.href)) { + return; + } + + //if there is a parent form, and it has a "onsubmit" + //execute it, validation is usually there, except is validation == true + //on which case it is ajax validation, instead of client side + if(!this.validate && this.formNode && this.formNode.onsubmit != null) { + var makeRequest = this.formNode.onsubmit.call(evt); + if(makeRequest != null && !makeRequest) { + this.log("Request canceled by 'onsubmit' of the form"); + return; + } + } + + //show indicator + dojo.html.show(this.indicator); + if(this.showLoading) { + this.setContent(this.loadingText); + } + + var tmpHref = this.href; + tmpHref = tmpHref + (tmpHref.indexOf("?") > -1 ? "&" : "?") + "struts.enableJSONValidation=true"; + if(!this.ajaxAfterValidation && this.validate) { + tmpHref = tmpHref + (tmpHref.indexOf("?") > -1 ? "&" : "?") + "struts.validateOnly=true"; + } + + if(dojo.dom.isTag(this.domNode, "INPUT", "input") + && this.events == "onclick" + && this.domNode.type == "submit" + && !dojo.string.isBlank(this.domNode.name) + && !dojo.string.isBlank(this.domNode.value)) { + var enc = /utf/i.test("") ? encodeURIComponent : dojo.string.encodeAscii + tmpHref = tmpHref + (tmpHref.indexOf("?") > -1 ? "&" : "?") + enc(this.domNode.name) + "=" + enc(this.domNode.value); + } + + dojo.io.bind({ + url: tmpHref, + useCache: false, + preventCache: true, + formNode: self.formNode, + formFilter: window[self.formFilter], + transport: self.transport, + handler: function(type, data, e) { + dojo.lang.hitch(self, "bindHandler")(type, data, e); + }, + mimetype: "text/html" + }); + } + catch(ex) { + if(this.showError) { + var message = dojo.string.isBlank(this.errorText) ? ex : this.errorText; + this.setContent(message); + } + } + } + }, + + //from Dojo's ContentPane + parse : function(s) { + this.log("Parsing: " + s); + var match = []; + var tmp = []; + var scripts = []; + while(match){ + match = s.match(/]*)>([\s\S]*?)<\/script>/i); + if(!match){ break; } + if(match[1]){ + attr = match[1].match(/src=(['"]?)([^"']*)\1/i); + if(attr){ + // remove a dojo.js or dojo.js.uncompressed.js from remoteScripts + // we declare all files with dojo.js as bad, regardless of folder + var tmp2 = attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/); + if(tmp2 > -1){ + this.log("Security note! inhibit:"+attr[2]+" from beeing loaded again."); + } + } + } + if(match[2]){ + // strip out all djConfig variables from script tags nodeValue + // this is ABSOLUTLY needed as reinitialize djConfig after dojo is initialised + // makes a dissaster greater than Titanic, update remove writeIncludes() to + var sc = match[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g, ""); + if(!sc){ continue; } + + // cut out all dojo.require (...) calls, if we have execute + // scripts false widgets dont get there require calls + // does suck out possible widgetpackage registration as well + tmp = []; + while(tmp){ + tmp = sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/); + if(!tmp){ break;} + sc = sc.replace(tmp[0], ""); + } + scripts.push(sc); + } + s = s.replace(/]*>[\s\S]*?<\/script>/i, ""); + } + + return { + text: s, + scripts: scripts + }; + }, + + //from Dojo content pane + _executeScripts : function (scripts) { + var self = this; + var tmp = "", code = ""; + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].path) { + dojo.io.bind(this._cacheSetting({"url":scripts[i].path, "load":function (type, scriptStr) { + dojo.lang.hitch(self, tmp = ";" + scriptStr); + }, "error":function (type, error) { + error.text = type + " downloading remote script"; + self._handleDefaults.call(self, error, "onExecError", "debug"); + }, "mimetype":"text/plain", "sync":true}, this.cacheContent)); + code += tmp; + } else { + code += scripts[i]; + } + } + try { + if (this.scriptSeparation) { + delete this.scriptScope; + this.scriptScope = new (new Function("_container_", code + "; return this;"))(self); + } else { + var djg = dojo.global(); + if (djg.execScript) { + djg.execScript(code); + } else { + var djd = dojo.doc(); + var sc = djd.createElement("script"); + sc.appendChild(djd.createTextNode(code)); + (this.containerNode || this.domNode).appendChild(sc); + } + } + } + catch (e) { + e.text = "Error running scripts from content:\n" + e.description; + this.log(e); + } + }, + + _cacheSetting : function (bindObj, useCache) { + for (var x in this.bindArgs) { + if (dojo.lang.isUndefined(bindObj[x])) { + bindObj[x] = this.bindArgs[x]; + } + } + if (dojo.lang.isUndefined(bindObj.useCache)) { + bindObj.useCache = useCache; + } + if (dojo.lang.isUndefined(bindObj.preventCache)) { + bindObj.preventCache = !useCache; + } + if (dojo.lang.isUndefined(bindObj.mimetype)) { + bindObj.mimetype = "text/html"; + } + return bindObj; + } + +}); + + + + +dojo.provide("dojo.lang.timing.Timer"); + + +dojo.lang.timing.Timer = function(/*int*/ interval){ + // summary: Timer object executes an "onTick()" method repeatedly at a specified interval. + // repeatedly at a given interval. + // interval: Interval between function calls, in milliseconds. + this.timer = null; + this.isRunning = false; + this.interval = interval; + + this.onStart = null; + this.onStop = null; +}; + +dojo.extend(dojo.lang.timing.Timer, { + onTick : function(){ + // summary: Method called every time the interval passes. Override to do something useful. + }, + + setInterval : function(interval){ + // summary: Reset the interval of a timer, whether running or not. + // interval: New interval, in milliseconds. + if (this.isRunning){ + dj_global.clearInterval(this.timer); + } + this.interval = interval; + if (this.isRunning){ + this.timer = dj_global.setInterval(dojo.lang.hitch(this, "onTick"), this.interval); + } + }, + + start : function(){ + // summary: Start the timer ticking. + // description: Calls the "onStart()" handler, if defined. + // Note that the onTick() function is not called right away, + // only after first interval passes. + if (typeof this.onStart == "function"){ + this.onStart(); + } + this.isRunning = true; + this.timer = dj_global.setInterval(dojo.lang.hitch(this, "onTick"), this.interval); + }, + + stop : function(){ + // summary: Stop the timer. + // description: Calls the "onStop()" handler, if defined. + if (typeof this.onStop == "function"){ + this.onStop(); + } + this.isRunning = false; + dj_global.clearInterval(this.timer); + } +}); + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +dojo.provide("struts.widget.BindDiv"); + + + + + +dojo.widget.defineWidget( + "struts.widget.BindDiv", + dojo.widget.ContentPane, { + widgetType : "BindDiv", + + //from ContentPane + href : "", + extractContent : false, + parseContent : false, + cacheContent : false, + refreshOnShow : false, + executeScripts : false, + preload : true, + + //update times + updateFreq : 0, + delay : 0, + autoStart : true, + timer : null, + + //messages + loadingText : "Loading...", + showLoading : false, + errorText : "", + showError : true, + + //pub/sub events + listenTopics : "", + notifyTopics : "", + notifyTopicsArray : null, + stopTimerListenTopics : "", + startTimerListenTopics : "", + beforeNotifyTopics : "", + beforeNotifyTopicsArray : null, + afterNotifyTopics : "", + afterNotifyTopicsArray : null, + errorNotifyTopics : "", + errorNotifyTopicsArray : null, + + + //callbacks + beforeLoading : "", + afterLoading : "", + + formId : "", + formFilter : "", + + indicator: "", + + //make dojo process the content + parseContent : true, + + highlightColor : "", + highlightDuration : 2000, + + //only used when inside a tabbedpanel + disabled : false, + + transport : "", + + onDownloadStart : function(event) { + if(!this.showLoading) { + event.returnValue = false; + return; + } + if(this.showLoading && !dojo.string.isBlank(this.loadingText)) { + event.text = this.loadingText; + } + }, + + highlight : function() { + if(!dojo.string.isBlank(this.highlightColor)) { + var effect = dojo.lfx.html.highlight([this.domNode], this.highlightColor, this.highlightDuration); + effect.play(); + } + }, + + onDownloadError : function(event) { + this.onError(event); + }, + + onContentError : function(event) { + this.onError(event); + }, + + onExecError : function(event) { + this.onError(event); + }, + + onError : function(event) { + if(this.showError) { + if(!dojo.string.isBlank(this.errorText)) { + event.text = this.errorText; + } + } else { + event.text = ""; + } + }, + + notify : function(data, type, e) { + if(this.notifyTopicsArray) { + var self = this; + dojo.lang.forEach(this.notifyTopicsArray, function(topic) { + try { + dojo.event.topic.publish(topic, data, type, e, self); + } catch(ex) { + self.log(ex); + } + }); + } + + //before, after and error topics + var topicsArray = null; + switch(type) { + case "before": + this.notifyTo(this.beforeNotifyTopicsArray, null, e); + break; + case "load": + this.notifyTo(this.afterNotifyTopicsArray, data, e); + break; + case "error": + this.notifyTo(this.errorNotifyTopicsArray, data, e); + break; + } + }, + + notifyTo : function(topicsArray, data, e) { + var self = this; + if(topicsArray) { + dojo.lang.forEach(topicsArray, function(topic) { + try { + if(data != null) { + dojo.event.topic.publish(topic, data, e, self); + } else { + dojo.event.topic.publish(topic, e, self); + } + } catch(ex){ + self.log(ex); + } + }); + } + }, + + postCreate : function(args, frag) { + if (this.handler !== "") { + this.setHandler(this.handler); + } + + var self = this; + var hitchedRefresh = function() { + dojo.lang.hitch(self, "refresh")(); + }; + var hitchedStartTimer = function() { + dojo.lang.hitch(self, "startTimer")(); + }; + + if(this.updateFreq > 0) { + //there is a timer + this.timer = new dojo.lang.timing.Timer(this.updateFreq); + this.timer.onTick = hitchedRefresh; + + if(this.autoStart) { + //start the timer + if(this.delay > 0) { + //start time after delay + dojo.lang.setTimeout(hitchedStartTimer, this.delay); + } else { + //start timer now + this.startTimer(); + } + } + } else { + //no timer + if(this.delay > 0) { + //load after delay + dojo.lang.setTimeout(hitchedRefresh, this.delay); + } + } + + //attach listeners + if(!dojo.string.isBlank(this.listenTopics)) { + this.log("Listening to " + this.listenTopics + " to refresh"); + var topics = this.listenTopics.split(","); + if(topics) { + dojo.lang.forEach(topics, function(topic){ + dojo.event.topic.subscribe(topic, self, "refresh"); + }); + } + } + + if(!dojo.string.isBlank(this.stopTimerListenTopics)) { + this.log("Listening to " + this.stopTimerListenTopics + " to stop timer"); + var stopTopics = this.stopTimerListenTopics.split(","); + if(stopTopics) { + dojo.lang.forEach(stopTopics, function(topic){ + dojo.event.topic.subscribe(topic, self, "stopTimer"); + }); + } + } + + if(!dojo.string.isBlank(this.startTimerListenTopics)) { + this.log("Listening to " + this.stopTimerListenTopics + " to start timer"); + var startTopics = this.startTimerListenTopics.split(","); + if(startTopics) { + dojo.lang.forEach(startTopics, function(topic){ + dojo.event.topic.subscribe(topic, self, "startTimer"); + }); + } + } + + //notify topics + if(!dojo.string.isBlank(this.notifyTopics)) { + this.notifyTopicsArray = this.notifyTopics.split(","); + } + + //before topics + if(!dojo.string.isBlank(this.beforeNotifyTopics)) { + this.beforeNotifyTopicsArray = this.beforeNotifyTopics.split(","); + } + + //after topics + if(!dojo.string.isBlank(this.afterNotifyTopics)) { + this.afterNotifyTopicsArray = this.afterNotifyTopics.split(","); + } + + //error topics + if(!dojo.string.isBlank(this.errorNotifyTopics)) { + this.errorNotifyTopicsArray = this.errorNotifyTopics.split(","); + } + + if(this.isShowing() && this.preload && this.updateFreq <= 0 && this.delay <= 0) { + this.refresh(); + } + }, + + _downloadExternalContent: function(url, useCache) { + + var request = {cancel: false}; + this.notify(this.widgetId, "before", request); + if(request.cancel) { + return; + } + + //show indicator + dojo.html.show(this.indicator); + + this._handleDefaults("Loading...", "onDownloadStart"); + var self = this; + dojo.io.bind({ + url: url, + useCache: useCache, + preventCache: !useCache, + mimetype: "text/html", + formNode: dojo.byId(self.formId), + formFilter: window[self.formFilter], + transport: self.transport, + handler: function(type, data, e) { + //hide indicator + dojo.html.hide(self.indicator); + + self.notify(data, type, e); + + if(type == "load") { + self.onDownloadEnd.call(self, url, data); + self.highlight(); + } else { + // works best when from a live server instead of from file system + self._handleDefaults.call(self, "Error loading '" + url + "' (" + e.status + " "+ e.statusText + ")", "onDownloadError"); + self.onLoad(); + } + } + }); + }, + + log : function(text) { + dojo.debug("[" + this.widgetId + "] " + text); + }, + + stopTimer : function() { + if(this.timer && this.timer.isRunning) { + this.log("stopping timer"); + this.timer.stop(); + } + }, + + startTimer : function() { + if(this.timer && !this.timer.isRunning) { + this.log("starting timer with update interval " + this.updateFreq); + this.timer.start(); + } + }, + + //from Dojo's ContentPane + //TODO: remove when fixed on Dojo (WW-1869) + splitAndFixPaths:function (s, url) { + var titles = [], scripts = [], tmp = []; + var match = [], requires = [], attr = [], styles = []; + var str = "", path = "", fix = "", tagFix = "", tag = "", origPath = ""; + if (!url) { + url = "./"; + } + if (s) { + var regex = /]*>([\s\S]*?)<\/title>/i; + while (match = regex.exec(s)) { + titles.push(match[1]); + s = s.substring(0, match.index) + s.substr(match.index + match[0].length); + } + if (this.adjustPaths) { + var regexFindTag = /<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i; + var regexFindAttr = /\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@!]+?)\2/i; + var regexProtocols = /^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/; + while (tag = regexFindTag.exec(s)) { + str += s.substring(0, tag.index); + s = s.substring((tag.index + tag[0].length), s.length); + tag = tag[0]; + tagFix = ""; + while (attr = regexFindAttr.exec(tag)) { + path = ""; + origPath = attr[3]; + switch (attr[1].toLowerCase()) { + case "src": + case "href": + if (regexProtocols.exec(origPath)) { + path = origPath; + } else { + path = (new dojo.uri.Uri(url, origPath).toString()); + } + break; + case "style": + path = dojo.html.fixPathsInCssText(origPath, url); + break; + default: + path = origPath; + } + fix = " " + attr[1] + "=" + attr[2] + path + attr[2]; + tagFix += tag.substring(0, attr.index) + fix; + tag = tag.substring((attr.index + attr[0].length), tag.length); + } + str += tagFix + tag; + } + s = str + s; + } + regex = /(?:<(style)[^>]*>([\s\S]*?)<\/style>|]*rel=['"]?stylesheet['"]?[^>]*)>)/i; + while (match = regex.exec(s)) { + if (match[1] && match[1].toLowerCase() == "style") { + styles.push(dojo.html.fixPathsInCssText(match[2], url)); + } else { + if (attr = match[3].match(/href=(['"]?)([^'">]*)\1/i)) { + styles.push({path:attr[2]}); + } + } + s = s.substring(0, match.index) + s.substr(match.index + match[0].length); + } + var regex = /]*)>([\s\S]*?)<\/script>/i; + var regexSrc = /src=(['"]?)([^"']*)\1/i; + var regexDojoJs = /.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/; + var regexInvalid = /(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g; + var regexRequires = /dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix|registerModulePath)|defineNamespace)\((['"]).*?\1\)\s*;?/; + while (match = regex.exec(s)) { + if (this.executeScripts && match[1]) { + if (attr = regexSrc.exec(match[1])) { + if (regexDojoJs.exec(attr[2])) { + dojo.debug("Security note! inhibit:" + attr[2] + " from being loaded again."); + } else { + scripts.push({path:attr[2]}); + } + } + } + if (match[2]) { + var sc = match[2].replace(regexInvalid, ""); + if (!sc) { + continue; + } + while (tmp = regexRequires.exec(sc)) { + requires.push(tmp[0]); + sc = sc.substring(0, tmp.index) + sc.substr(tmp.index + tmp[0].length); + } + if (this.executeScripts) { + scripts.push(sc); + } + } + s = s.substr(0, match.index) + s.substr(match.index + match[0].length); + } + if (this.extractContent) { + match = s.match(/]*>\s*([\s\S]+)\s*<\/body>/im); + if (match) { + s = match[1]; + } + } + if (this.executeScripts && this.scriptSeparation) { + var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*?\S=)((['"])[^>]*scriptScope[^>]*>)/; + var regexAttr = /([\s'";:\(])scriptScope(.*)/; + str = ""; + while (tag = regex.exec(s)) { + tmp = ((tag[3] == "'") ? "\"" : "'"); + fix = ""; + str += s.substring(0, tag.index) + tag[1]; + while (attr = regexAttr.exec(tag[2])) { + tag[2] = tag[2].substring(0, attr.index) + attr[1] + "dojo.widget.byId(" + tmp + this.widgetId + tmp + ").scriptScope" + attr[2]; + } + str += tag[2]; + s = s.substr(tag.index + tag[0].length); + } + s = str + s; + } + } + return {"xml":s, "styles":styles, "titles":titles, "requires":requires, "scripts":scripts, "url":url}; + } +}); + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +dojo.provide("struts.widget.BindAnchor"); + + + + + +dojo.widget.defineWidget( + "struts.widget.BindAnchor", + struts.widget.Bind, { + widgetType : "BindAnchor", + + events: "onclick", + + postCreate : function() { + struts.widget.BindAnchor.superclass.postCreate.apply(this); + this.domNode.href = "#"; + } +}); + + + + +dojo.provide("dojo.widget.html.stabile"); + +dojo.widget.html.stabile = { + // summary: Maintain state of widgets when user hits back/forward button + + // Characters to quote in single-quoted regexprs + _sqQuotables: new RegExp("([\\\\'])", "g"), + + // Current depth. + _depth: 0, + + // Set to true when calling v.toString, to sniff for infinite + // recursion. + _recur: false, + + // Levels of nesting of Array and object displays. + // If when >= depth, no display or array or object internals. + depthLimit: 2 +}; + +//// PUBLIC METHODS + +dojo.widget.html.stabile.getState = function(id){ + // summary + // Get the state stored for the widget with the given ID, or undefined + // if none. + + dojo.widget.html.stabile.setup(); + return dojo.widget.html.stabile.widgetState[id]; +} + +dojo.widget.html.stabile.setState = function(id, state, isCommit){ + // summary + // Set the state stored for the widget with the given ID. If isCommit + // is true, commits all widget state to more stable storage. + + dojo.widget.html.stabile.setup(); + dojo.widget.html.stabile.widgetState[id] = state; + if(isCommit){ + dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState); + } +} + +dojo.widget.html.stabile.setup = function(){ + // summary + // Sets up widgetState: a hash keyed by widgetId, maps to an object + // or array writable with "describe". If there is data in the widget + // storage area, use it, otherwise initialize an empty object. + + if(!dojo.widget.html.stabile.widgetState){ + var text = dojo.widget.html.stabile._getStorage().value; + dojo.widget.html.stabile.widgetState = text ? dj_eval("("+text+")") : {}; + } +} + +dojo.widget.html.stabile.commit = function(state){ + // summary + // Commits all widget state to more stable storage, so if the user + // navigates away and returns, it can be restored. + + dojo.widget.html.stabile._getStorage().value = dojo.widget.html.stabile.description(state); +} + +dojo.widget.html.stabile.description = function(v, showAll){ + // summary + // Return a JSON "description string" for the given value. + // Supports only core JavaScript types with literals, plus Date, + // and cyclic structures are unsupported. + // showAll defaults to false -- if true, this becomes a simple symbolic + // object dumper, but you cannot "eval" the output. + + // Save and later restore dojo.widget.html.stabile._depth; + var depth = dojo.widget.html.stabile._depth; + + var describeThis = function() { + return this.description(this, true); + } + + try { + + if(v===void(0)){ + return "undefined"; + } + if(v===null){ + return "null"; + } + if(typeof(v)=="boolean" || typeof(v)=="number" + || v instanceof Boolean || v instanceof Number){ + return v.toString(); + } + + if(typeof(v)=="string" || v instanceof String){ + // Quote strings and their contents as required. + // Replacing by $& fails in IE 5.0 + var v1 = v.replace(dojo.widget.html.stabile._sqQuotables, "\\$1"); + v1 = v1.replace(/\n/g, "\\n"); + v1 = v1.replace(/\r/g, "\\r"); + // Any other important special cases? + return "'"+v1+"'"; + } + + if(v instanceof Date){ + // Create a data constructor. + return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")"; + } + + var d; + if(v instanceof Array || v.push){ + // "push" test needed for KHTML/Safari, don't know why -cp + + if(depth>=dojo.widget.html.stabile.depthLimit) + return "[ ... ]"; + + d = "["; + var first = true; + dojo.widget.html.stabile._depth++; + for(var i=0; i=dojo.widget.html.stabile.depthLimit) + return "{ ... }"; + + // Instanceof Hash is good, or if we just use Objects, + // we can say v.constructor==Object. + // IE (5?) lacks hasOwnProperty, but perhaps objects do not always + // have prototypes?? + if(typeof(v.hasOwnProperty)!="function" && v.prototype){ + throw new Error("description: "+v+" not supported by script engine"); + } + var first = true; + d = "{"; + dojo.widget.html.stabile._depth++; + for(var key in v){ + // Skip values that are functions or undefined. + if(v[key]==void(0) || typeof(v[key])=="function") + continue; + if(first){ + first = false; + }else{ + d += ", "; + } + var kd = key; + // If the key is not a legal identifier, use its description. + // For strings this will quote the stirng. + if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){ + kd = arguments.callee(key, showAll); + } + d += kd+": "+arguments.callee(v[key], showAll); + } + return d+"}"; + } + + if(showAll){ + if(dojo.widget.html.stabile._recur){ + // Save the original definitions of toString; + var objectToString = Object.prototype.toString; + return objectToString.apply(v, []); + }else{ + dojo.widget.html.stabile._recur = true; + return v.toString(); + } + }else{ + // log("Description? "+v.toString()+", "+typeof(v)); + throw new Error("Unknown type: "+v); + return "'unknown'"; + } + + } finally { + // Always restore the global current depth. + dojo.widget.html.stabile._depth = depth; + } + +} + + + +//// PRIVATE TO MODULE + +dojo.widget.html.stabile._getStorage = function(){ + // summary + // Gets an object (form field) with a read/write "value" property. + + if (dojo.widget.html.stabile.dataField) { + return dojo.widget.html.stabile.dataField; + } + var form = document.forms._dojo_form; + return dojo.widget.html.stabile.dataField = form ? form.stabile : {value: ""}; +} + + +dojo.provide("dojo.widget.ComboBox"); + + + + + + + + + +dojo.declare( + "dojo.widget.incrementalComboBoxDataProvider", + null, + function(options){ + // summary: + // Reference implementation / interface for Combobox incremental data provider. + // This class takes a search string and returns values that match + // that search string. The filtering of values (to find values matching given + // search string) is done on the server. + // + // options: + // Structure containing {dataUrl: "foo.js?search={searchString}"} or similar data. + // dataUrl is a URL that is passed the search string a returns a JSON structure + // showing the matching values, like [ ["Alabama","AL"], ["Alaska","AK"], ["American Samoa","AS"] ] + + this.searchUrl = options.dataUrl; + + // TODO: cache doesn't work + this._cache = {}; + + this._inFlight = false; + this._lastRequest = null; + + // allowCache: Boolean + // Setting to use/not use cache for previously seen values + // TODO: caching doesn't work. + // TODO: read the setting for this value from the widget parameters + this.allowCache = false; + }, + { + _addToCache: function(/*String*/ keyword, /*Array*/ data){ + if(this.allowCache){ + this._cache[keyword] = data; + } + }, + + startSearch: function(/*String*/ searchStr, /*Function*/ callback){ + // summary: + // Start the search for patterns that match searchStr, and call + // specified callback functions with the results + // searchStr: + // The characters the user has typed into the . + // callback: + // This function will be called with the result, as an + // array of label/value pairs (the value is used for the Select widget). Example: + // [ ["Alabama","AL"], ["Alaska","AK"], ["American Samoa","AS"] ] + + if(this._inFlight){ + // FIXME: implement backoff! + } + var tss = encodeURIComponent(searchStr); + var realUrl = dojo.string.substituteParams(this.searchUrl, {"searchString": tss}); + var _this = this; + var request = this._lastRequest = dojo.io.bind({ + url: realUrl, + method: "get", + mimetype: "text/json", + load: function(type, data, evt){ + _this._inFlight = false; + if(!dojo.lang.isArray(data)){ + var arrData = []; + for(var key in data){ + arrData.push([data[key], key]); + } + data = arrData; + } + _this._addToCache(searchStr, data); + if (request == _this._lastRequest){ + callback(data); + } + } + }); + this._inFlight = true; + } + } +); + +dojo.declare( + "dojo.widget.basicComboBoxDataProvider", + null, + function(/*Object*/ options, /*DomNode*/ node){ + // summary: + // Reference implementation / interface for Combobox data provider. + // This class takes a search string and returns values that match + // that search string. All possible values for the combobox are downloaded + // on initialization, and then startSearch() runs locally, + // merely filting that downloaded list, to find values matching search string + // + // NOTE: this data provider is designed as a naive reference + // implementation, and as such it is written more for readability than + // speed. A deployable data provider would implement lookups, search + // caching (and invalidation), and a significantly less naive data + // structure for storage of items. + // + // options: Object + // Options object. Example: + // { + // dataUrl: String (URL to query to get list of possible drop down values), + // setAllValues: Function (callback for setting initially selected value) + // } + // The return format for dataURL is (for example) + // [ ["Alabama","AL"], ["Alaska","AK"], ["American Samoa","AS"] ... ] + // + // node: + // Pointer to the domNode in the original markup. + // This is needed in the case when the list of values is embedded + // in the html like box, + // automatically copy the first entry displayed in the drop down list to + // the field + autoComplete: true, + + // searchDelay: Integer + // Delay in milliseconds between when user types something and we start + // searching based on that value + searchDelay: 100, + + // dataUrl: String + // URL argument passed to data provider object (class name specified in "dataProviderClass") + // An example of the URL format for the default data provider is + // "remoteComboBoxData.js?search=%{searchString}" + dataUrl: "", + + // fadeTime: Integer + // Milliseconds duration of fadeout for drop down box + fadeTime: 200, + + // maxListLength: Integer + // Limits list to X visible rows, scroll on rest + maxListLength: 8, + + // mode: String + // Mode must be specified unless dataProviderClass is specified. + // "local" to inline search string, "remote" for JSON-returning live search + // or "html" for dumber live search. + mode: "local", + + // selectedResult: Array + // (Read only) array specifying the value/label that the user selected + selectedResult: null, + + // dataProviderClass: String + // Name of data provider class (code that maps a search string to a list of values) + // The class must match the interface demonstrated by dojo.widget.incrementalComboBoxDataProvider + dataProviderClass: "", + + // buttonSrc: URI + // URI for the down arrow icon to the right of the input box. + buttonSrc: dojo.uri.moduleUri("dojo.widget", "templates/images/combo_box_arrow.png"), + + // dropdownToggle: String + // Animation effect for showing/displaying drop down box + dropdownToggle: "fade", + + templateString:"\r\n", + templateCssString:".dojoComboBoxOuter {\r\n\tborder: 0px !important;\r\n\tmargin: 0px !important;\r\n\tpadding: 0px !important;\r\n\tbackground: transparent !important;\r\n\twhite-space: nowrap !important;\r\n}\r\n\r\n.dojoComboBox {\r\n\tborder: 1px inset #afafaf;\r\n\tmargin: 0px;\r\n\tpadding: 0px;\r\n\tvertical-align: middle !important;\r\n\tfloat: none !important;\r\n\tposition: static !important;\r\n\tdisplay: inline !important;\r\n}\r\n\r\n/* the input box */\r\ninput.dojoComboBox {\r\n\tborder-right-width: 0px !important; \r\n\tmargin-right: 0px !important;\r\n\tpadding-right: 0px !important;\r\n}\r\n\r\n/* the down arrow */\r\nimg.dojoComboBox {\r\n\tborder-left-width: 0px !important;\r\n\tpadding-left: 0px !important;\r\n\tmargin-left: 0px !important;\r\n}\r\n\r\n/* IE vertical-alignment calculations can be off by +-1 but these margins are collapsed away */\r\n.dj_ie img.dojoComboBox {\r\n\tmargin-top: 1px; \r\n\tmargin-bottom: 1px; \r\n}\r\n\r\n/* the drop down */\r\n.dojoComboBoxOptions {\r\n\tfont-family: Verdana, Helvetica, Garamond, sans-serif;\r\n\t/* font-size: 0.7em; */\r\n\tbackground-color: white;\r\n\tborder: 1px solid #afafaf;\r\n\tposition: absolute;\r\n\tz-index: 1000; \r\n\toverflow: auto;\r\n\tcursor: default;\r\n}\r\n\r\n.dojoComboBoxItem {\r\n\tpadding-left: 2px;\r\n\tpadding-top: 2px;\r\n\tmargin: 0px;\r\n}\r\n\r\n.dojoComboBoxItemEven {\r\n\tbackground-color: #f4f4f4;\r\n}\r\n\r\n.dojoComboBoxItemOdd {\r\n\tbackground-color: white;\r\n}\r\n\r\n.dojoComboBoxItemHighlight {\r\n\tbackground-color: #63709A;\r\n\tcolor: white;\r\n}\r\n",templateCssPath: dojo.uri.moduleUri("dojo.widget", "templates/ComboBox.css"), + + setValue: function(/*String*/ value){ + // summary: Sets the value of the combobox + this.comboBoxValue.value = value; + if (this.textInputNode.value != value){ // prevent mucking up of selection + this.textInputNode.value = value; + // only change state and value if a new value is set + dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true); + this.onValueChanged(value); + } + }, + + onValueChanged: function(/*String*/ value){ + // summary: callback when value changes, for user to attach to + }, + + getValue: function(){ + // summary: Rerturns combo box value + return this.comboBoxValue.value; + }, + + getState: function(){ + // summary: + // Used for saving state of ComboBox when navigates to a new + // page, in case they then hit the browser's "Back" button. + return {value: this.getValue()}; + }, + + setState: function(/*Object*/ state){ + // summary: + // Used for restoring state of ComboBox when has navigated to a new + // page but then hits browser's "Back" button. + this.setValue(state.value); + }, + + enable:function(){ + this.disabled=false; + this.textInputNode.removeAttribute("disabled"); + }, + + disable: function(){ + this.disabled = true; + this.textInputNode.setAttribute("disabled",true); + }, + + _getCaretPos: function(/*DomNode*/ element){ + // khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22 + if(dojo.lang.isNumber(element.selectionStart)){ + // FIXME: this is totally borked on Moz < 1.3. Any recourse? + return element.selectionStart; + }else if(dojo.render.html.ie){ + // in the case of a mouse click in a popup being handled, + // then the document.selection is not the textarea, but the popup + // var r = document.selection.createRange(); + // hack to get IE 6 to play nice. What a POS browser. + var tr = document.selection.createRange().duplicate(); + var ntr = element.createTextRange(); + tr.move("character",0); + ntr.move("character",0); + try { + // If control doesnt have focus, you get an exception. + // Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes). + // There appears to be no workaround for this - googled for quite a while. + ntr.setEndPoint("EndToEnd", tr); + return String(ntr.text).replace(/\r/g,"").length; + } catch (e){ + return 0; // If focus has shifted, 0 is fine for caret pos. + } + + } + }, + + _setCaretPos: function(/*DomNode*/ element, /*Number*/ location){ + location = parseInt(location); + this._setSelectedRange(element, location, location); + }, + + _setSelectedRange: function(/*DomNode*/ element, /*Number*/ start, /*Number*/ end){ + if(!end){ end = element.value.length; } // NOTE: Strange - should be able to put caret at start of text? + // Mozilla + // parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130 + if(element.setSelectionRange){ + element.focus(); + element.setSelectionRange(start, end); + }else if(element.createTextRange){ // IE + var range = element.createTextRange(); + with(range){ + collapse(true); + moveEnd('character', end); + moveStart('character', start); + select(); + } + }else{ //otherwise try the event-creation hack (our own invention) + // do we need these? + element.value = element.value; + element.blur(); + element.focus(); + // figure out how far back to go + var dist = parseInt(element.value.length)-end; + var tchar = String.fromCharCode(37); + var tcc = tchar.charCodeAt(0); + for(var x = 0; x < dist; x++){ + var te = document.createEvent("KeyEvents"); + te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc); + element.dispatchEvent(te); + } + } + }, + + _handleKeyEvents: function(/*Event*/ evt){ + // summary: handles keyboard events + if(evt.ctrlKey || evt.altKey || !evt.key){ return; } + + // reset these + this._prev_key_backspace = false; + this._prev_key_esc = false; + + var k = dojo.event.browser.keys; + var doSearch = true; + + switch(evt.key){ + case k.KEY_DOWN_ARROW: + if(!this.popupWidget.isShowingNow){ + this._startSearchFromInput(); + } + this._highlightNextOption(); + dojo.event.browser.stopEvent(evt); + return; + case k.KEY_UP_ARROW: + this._highlightPrevOption(); + dojo.event.browser.stopEvent(evt); + return; + case k.KEY_TAB: + // using linux alike tab for autocomplete + if(!this.autoComplete && this.popupWidget.isShowingNow && this._highlighted_option){ + dojo.event.browser.stopEvent(evt); + this._selectOption({ 'target': this._highlighted_option, 'noHide': false}); + + // put caret last + this._setSelectedRange(this.textInputNode, this.textInputNode.value.length, null); + }else{ + this._selectOption(); + return; + } + break; + case k.KEY_ENTER: + // prevent submitting form if we press enter with list open + if(this.popupWidget.isShowingNow){ + dojo.event.browser.stopEvent(evt); + } + if(this.autoComplete){ + this._selectOption(); + return; + } + // fallthrough + case " ": + if(this.popupWidget.isShowingNow && this._highlighted_option){ + dojo.event.browser.stopEvent(evt); + this._selectOption(); + this._hideResultList(); + return; + } + break; + case k.KEY_ESCAPE: + this._hideResultList(); + this._prev_key_esc = true; + return; + case k.KEY_BACKSPACE: + this._prev_key_backspace = true; + if(!this.textInputNode.value.length){ + this.setAllValues("", ""); + this._hideResultList(); + doSearch = false; + } + break; + case k.KEY_RIGHT_ARROW: // fall through + case k.KEY_LEFT_ARROW: // fall through + doSearch = false; + break; + default:// non char keys (F1-F12 etc..) shouldn't open list + if(evt.charCode==0){ + doSearch = false; + } + } + + if(this.searchTimer){ + clearTimeout(this.searchTimer); + } + if(doSearch){ + // if we have gotten this far we dont want to keep our highlight + this._blurOptionNode(); + + // need to wait a tad before start search so that the event bubbles through DOM and we have value visible + this.searchTimer = setTimeout(dojo.lang.hitch(this, this._startSearchFromInput), this.searchDelay); + } + }, + + compositionEnd: function(/*Event*/ evt){ + // summary: When inputting characters using an input method, such as Asian + // languages, it will generate this event instead of onKeyDown event + evt.key = evt.keyCode; + this._handleKeyEvents(evt); + }, + + onKeyUp: function(/*Event*/ evt){ + // summary: callback on key up event + this.setValue(this.textInputNode.value); + }, + + setSelectedValue: function(/*String*/ value){ + // summary: + // This sets a hidden value associated w/the displayed value. + // The hidden value (and this function) shouldn't be used; if + // you need a hidden value then use Select widget instead of ComboBox. + // TODO: remove? + // FIXME, not sure what to do here! + this.comboBoxSelectionValue.value = value; + }, + + setAllValues: function(/*String*/ value1, /*String*/ value2){ + // summary: + // This sets the displayed value and hidden value. + // The hidden value (and this function) shouldn't be used; if + // you need a hidden value then use Select widget instead of ComboBox. + this.setSelectedValue(value2); + this.setValue(value1); + }, + + _focusOptionNode: function(/*DomNode*/ node){ + // summary: does the actual highlight + if(this._highlighted_option != node){ + this._blurOptionNode(); + this._highlighted_option = node; + dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight"); + } + }, + + _blurOptionNode: function(){ + // sumary: removes highlight on highlighted + if(this._highlighted_option){ + dojo.html.removeClass(this._highlighted_option, "dojoComboBoxItemHighlight"); + this._highlighted_option = null; + } + }, + + _highlightNextOption: function(){ + if((!this._highlighted_option) || !this._highlighted_option.parentNode){ + this._focusOptionNode(this.optionsListNode.firstChild); + }else if(this._highlighted_option.nextSibling){ + this._focusOptionNode(this._highlighted_option.nextSibling); + } + dojo.html.scrollIntoView(this._highlighted_option); + }, + + _highlightPrevOption: function(){ + if(this._highlighted_option && this._highlighted_option.previousSibling){ + this._focusOptionNode(this._highlighted_option.previousSibling); + }else{ + this._highlighted_option = null; + this._hideResultList(); + return; + } + dojo.html.scrollIntoView(this._highlighted_option); + }, + + _itemMouseOver: function(/*Event*/ evt){ + if (evt.target === this.optionsListNode){ return; } + this._focusOptionNode(evt.target); + dojo.html.addClass(this._highlighted_option, "dojoComboBoxItemHighlight"); + }, + + _itemMouseOut: function(/*Event*/ evt){ + if (evt.target === this.optionsListNode){ return; } + this._blurOptionNode(); + }, + + onResize: function(){ + // summary: this function is called when the input area has changed size + var inputSize = dojo.html.getContentBox(this.textInputNode); + if( inputSize.height <= 0 ){ + // need more time to calculate size + dojo.lang.setTimeout(this, "onResize", 100); + return; + } + var buttonSize = { width: inputSize.height, height: inputSize.height}; + dojo.html.setContentBox(this.downArrowNode, buttonSize); + }, + + fillInTemplate: function(/*Object*/ args, /*Object*/ frag){ + // there's some browser specific CSS in ComboBox.css + dojo.html.applyBrowserClass(this.domNode); + + var source = this.getFragNodeRef(frag); + if (! this.name && source.name){ this.name = source.name; } + this.comboBoxValue.name = this.name; + this.comboBoxSelectionValue.name = this.name+"_selected"; + + /* different nodes get different parts of the style */ + dojo.html.copyStyle(this.domNode, source); + dojo.html.copyStyle(this.textInputNode, source); + dojo.html.copyStyle(this.downArrowNode, source); + with (this.downArrowNode.style){ // calculate these later + width = "0px"; + height = "0px"; + } + + // Use specified data provider class; if no class is specified + // then use comboboxDataProvider or incrmentalComboBoxDataProvider + // depending on setting of mode + var dpClass; + if(this.dataProviderClass){ + if(typeof this.dataProviderClass == "string"){ + dpClass = dojo.evalObjPath(this.dataProviderClass) + }else{ + dpClass = this.dataProviderClass; + } + }else{ + if(this.mode == "remote"){ + dpClass = dojo.widget.incrementalComboBoxDataProvider; + }else{ + dpClass = dojo.widget.basicComboBoxDataProvider; + } + } + this.dataProvider = new dpClass(this, this.getFragNodeRef(frag)); + + this.popupWidget = new dojo.widget.createWidget("PopupContainer", + {toggle: this.dropdownToggle, toggleDuration: this.toggleDuration}); + dojo.event.connect(this, 'destroy', this.popupWidget, 'destroy'); + this.optionsListNode = this.popupWidget.domNode; + this.domNode.appendChild(this.optionsListNode); + dojo.html.addClass(this.optionsListNode, 'dojoComboBoxOptions'); + dojo.event.connect(this.optionsListNode, 'onclick', this, '_selectOption'); + dojo.event.connect(this.optionsListNode, 'onmouseover', this, '_onMouseOver'); + dojo.event.connect(this.optionsListNode, 'onmouseout', this, '_onMouseOut'); + + // TODO: why does onmouseover and onmouseout connect to two separate handlers??? + dojo.event.connect(this.optionsListNode, "onmouseover", this, "_itemMouseOver"); + dojo.event.connect(this.optionsListNode, "onmouseout", this, "_itemMouseOut"); + }, + + _openResultList: function(/*Array*/ results){ + if (this.disabled){ + return; + } + this._clearResultList(); + if(!results.length){ + this._hideResultList(); + } + + if( (this.autoComplete)&& + (results.length)&& + (!this._prev_key_backspace)&& + (this.textInputNode.value.length > 0)){ + var cpos = this._getCaretPos(this.textInputNode); + // only try to extend if we added the last character at the end of the input + if((cpos+1) > this.textInputNode.value.length){ + // only add to input node as we would overwrite Capitalisation of chars + this.textInputNode.value += results[0][0].substr(cpos); + // build a new range that has the distance from the earlier + // caret position to the end of the first string selected + this._setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length); + } + } + + var even = true; + while(results.length){ + var tr = results.shift(); + if(tr){ + var td = document.createElement("div"); + td.appendChild(document.createTextNode(tr[0])); + td.setAttribute("resultName", tr[0]); + td.setAttribute("resultValue", tr[1]); + td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd"); + even = (!even); + this.optionsListNode.appendChild(td); + } + } + + // show our list (only if we have content, else nothing) + this._showResultList(); + }, + + _onFocusInput: function(){ + this._hasFocus = true; + }, + + _onBlurInput: function(){ + this._hasFocus = false; + this._handleBlurTimer(true, 500); + }, + + _handleBlurTimer: function(/*Boolean*/clear, /*Number*/ millisec){ + // summary: collect all blur timers issues here + if(this.blurTimer && (clear || millisec)){ + clearTimeout(this.blurTimer); + } + if(millisec){ // we ignore that zero is false and never sets as that never happens in this widget + this.blurTimer = dojo.lang.setTimeout(this, "_checkBlurred", millisec); + } + }, + + _onMouseOver: function(/*Event*/ evt){ + // summary: needed in IE and Safari as inputTextNode loses focus when scrolling optionslist + if(!this._mouseover_list){ + this._handleBlurTimer(true, 0); + this._mouseover_list = true; + } + }, + + _onMouseOut:function(/*Event*/ evt){ + // summary: needed in IE and Safari as inputTextNode loses focus when scrolling optionslist + var relTarget = evt.relatedTarget; + try { // fixes #1807 + if(!relTarget || relTarget.parentNode != this.optionsListNode){ + this._mouseover_list = false; + this._handleBlurTimer(true, 100); + this._tryFocus(); + } + }catch(e){} + }, + + _isInputEqualToResult: function(/*String*/ result){ + var input = this.textInputNode.value; + if(!this.dataProvider.caseSensitive){ + input = input.toLowerCase(); + result = result.toLowerCase(); + } + return (input == result); + }, + + _isValidOption: function(){ + var tgt = dojo.html.firstElement(this.optionsListNode); + var isValidOption = false; + while(!isValidOption && tgt){ + if(this._isInputEqualToResult(tgt.getAttribute("resultName"))){ + isValidOption = true; + }else{ + tgt = dojo.html.nextElement(tgt); + } + } + return isValidOption; + }, + + _checkBlurred: function(){ + if(!this._hasFocus && !this._mouseover_list){ + this._hideResultList(); + // clear the list if the user empties field and moves away. + if(!this.textInputNode.value.length){ + this.setAllValues("", ""); + return; + } + + var isValidOption = this._isValidOption(); + // enforce selection from option list + if(this.forceValidOption && !isValidOption){ + this.setAllValues("", ""); + return; + } + if(!isValidOption){// clear + this.setSelectedValue(""); + } + } + }, + + _selectOption: function(/*Event*/ evt){ + var tgt = null; + if(!evt){ + evt = { target: this._highlighted_option }; + } + + if(!dojo.html.isDescendantOf(evt.target, this.optionsListNode)){ + // handle autocompletion where the the user has hit ENTER or TAB + + // if the input is empty do nothing + if(!this.textInputNode.value.length){ + return; + } + tgt = dojo.html.firstElement(this.optionsListNode); + + // user has input value not in option list + if(!tgt || !this._isInputEqualToResult(tgt.getAttribute("resultName"))){ + return; + } + // otherwise the user has accepted the autocompleted value + }else{ + tgt = evt.target; + } + + while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){ + tgt = tgt.parentNode; + if(tgt === dojo.body()){ + return false; + } + } + + this.selectedResult = [tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")]; + this.setAllValues(tgt.getAttribute("resultName"), tgt.getAttribute("resultValue")); + if(!evt.noHide){ + this._hideResultList(); + this._setSelectedRange(this.textInputNode, 0, null); + } + this._tryFocus(); + }, + + _clearResultList: function(){ + if(this.optionsListNode.innerHTML){ + this.optionsListNode.innerHTML = ""; // browser natively knows how to collect this memory + } + }, + + _hideResultList: function(){ + this.popupWidget.close(); + }, + + _showResultList: function(){ + // Our dear friend IE doesnt take max-height so we need to calculate that on our own every time + var childs = this.optionsListNode.childNodes; + if(childs.length){ + var visibleCount = Math.min(childs.length,this.maxListLength); + + with(this.optionsListNode.style) + { + display = ""; + if(visibleCount == childs.length){ + //no scrollbar is required, so unset height to let browser calcuate it, + //as in css, overflow is already set to auto + height = ""; + }else{ + //show it first to get the correct dojo.style.getOuterHeight(childs[0]) + //FIXME: shall we cache the height of the item? + height = visibleCount * dojo.html.getMarginBox(childs[0]).height +"px"; + } + width = (dojo.html.getMarginBox(this.domNode).width-2)+"px"; + } + this.popupWidget.open(this.domNode, this, this.downArrowNode); + }else{ + this._hideResultList(); + } + }, + + handleArrowClick: function(){ + // summary: callback when arrow is clicked + this._handleBlurTimer(true, 0); + this._tryFocus(); + if(this.popupWidget.isShowingNow){ + this._hideResultList(); + }else{ + // forces full population of results, if they click + // on the arrow it means they want to see more options + this._startSearch(""); + } + }, + + _tryFocus: function(){ + try { + this.textInputNode.focus(); + } catch (e){ + // element isn't focusable if disabled, or not visible etc - not easy to test for. + }; + }, + + _startSearchFromInput: function(){ + this._startSearch(this.textInputNode.value); + }, + + _startSearch: function(/*String*/ key){ + this.dataProvider.startSearch(key, dojo.lang.hitch(this, "_openResultList")); + }, + + postCreate: function(){ + this.onResize(); + + // TODO: add these attach events to template + dojo.event.connect(this.textInputNode, "onblur", this, "_onBlurInput"); + dojo.event.connect(this.textInputNode, "onfocus", this, "_onFocusInput"); + + if (this.disabled){ + this.disable(); + } + var s = dojo.widget.html.stabile.getState(this.widgetId); + if (s){ + this.setState(s); + } + } + } +); + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +dojo.provide("struts.widget.ComboBox"); + + + + +struts.widget.ComboBoxDataProvider = function(combobox, node){ + this.data = []; + this.searchLimit = combobox.searchLimit; + this.searchType = "STARTSTRING"; // may also be "STARTWORD" or "SUBSTRING" + this.caseSensitive = false; + // for caching optimizations + this._lastSearch = ""; + this._lastSearchResults = null; + + this.firstRequest = true; + + this.cbox = combobox; + this.formId = this.cbox.formId; + this.formFilter = this.cbox.formFilter; + this.transport = this.cbox.transport; + + this.getData = function(/*String*/ url){ + //show indicator + dojo.html.show(this.cbox.indicator); + + dojo.io.bind({ + url: url, + formNode: dojo.byId(this.formId), + formFilter: window[this.formFilter], + transport: this.transport, + handler: dojo.lang.hitch(this, function(type, data, evt) { + //hide indicator + dojo.html.hide(this.cbox.indicator); + + //if notifyTopics is published on the first request (onload) + //the value of listeners will be reset + if(!this.firstRequest || type == "error") { + this.cbox.notify.apply(this.cbox, [data, type, evt]); + } + + this.firstRequest = false; + var arrData = null; + var dataByName = data[dojo.string.isBlank(this.cbox.dataFieldName) ? this.cbox.name : this.cbox.dataFieldName]; + if(!dojo.lang.isArray(data)) { + //if there is a dataFieldName, take it + if(dataByName) { + if(dojo.lang.isArray(dataByName)) { + //ok, it is an array + arrData = dataByName; + } else if(dojo.lang.isObject(dataByName)) { + //it is an object, treat it like a map + arrData = []; + for(var key in dataByName){ + arrData.push([key, dataByName[key]]); + } + } + } else { + //try to find a match + var tmpArrData = []; + for(var key in data){ + //does it start with the field name? take it + if(dojo.string.startsWith(key, this.cbox.name)) { + arrData = data[key]; + break; + } else { + //if nathing else is found, we will use values in this + //object as the data + tmpArrData.push([key, data[key]]); + } + //grab the first array found, we will use it if nothing else + //is found + if(!arrData && dojo.lang.isArray(data[key]) && !dojo.lang.isString(data[key])) { + arrData = data[key]; + } + } + if(!arrData) { + arrData = tmpArrData; + } + } + + data = arrData; + } + this.setData(data); + }), + mimetype: "text/json" + }); + }; + + this.startSearch = function (searchStr, callback) { + // FIXME: need to add timeout handling here!! + this._preformSearch(searchStr, callback); + }; + + this._preformSearch = function(/*String*/ searchStr, callback){ + // + // NOTE: this search is LINEAR, which means that it exhibits perhaps + // the worst possible speed characteristics of any search type. It's + // written this way to outline the responsibilities and interfaces for + // a search. + // + var st = this.searchType; + // FIXME: this is just an example search, which means that we implement + // only a linear search without any of the attendant (useful!) optimizations + var ret = []; + if(!this.caseSensitive){ + searchStr = searchStr.toLowerCase(); + } + for(var x=0; x 0) && (ret.length >= this.searchLimit)) { + break; + } + // FIXME: we should avoid copies if possible! + var dataLabel = new String((!this.caseSensitive) ? this.data[x][0].toLowerCase() : this.data[x][0]); + if(dataLabel.length < searchStr.length){ + // this won't ever be a good search, will it? What if we start + // to support regex search? + continue; + } + + if(st == "STARTSTRING"){ + if(searchStr == dataLabel.substr(0, searchStr.length)){ + ret.push(this.data[x]); + } + }else if(st == "SUBSTRING"){ + // this one is a gimmie + if(dataLabel.indexOf(searchStr) >= 0){ + ret.push(this.data[x]); + } + }else if(st == "STARTWORD"){ + // do a substring search and then attempt to determine if the + // preceeding char was the beginning of the string or a + // whitespace char. + var idx = dataLabel.indexOf(searchStr); + if(idx == 0){ + // implicit match + ret.push(this.data[x]); + } + if(idx <= 0){ + // if we didn't match or implicily matched, march onward + continue; + } + // otherwise, we have to go figure out if the match was at the + // start of a word... + // this code is taken almost directy from nWidgets + var matches = false; + while(idx!=-1){ + // make sure the match either starts whole string, or + // follows a space, or follows some punctuation + if(" ,/(".indexOf(dataLabel.charAt(idx-1)) != -1){ + // FIXME: what about tab chars? + matches = true; break; + } + idx = dataLabel.indexOf(searchStr, idx+1); + } + if(!matches){ + continue; + }else{ + ret.push(this.data[x]); + } + } + } + callback(ret); + }; + + this.addData = function(/*Array*/ pairs){ + // FIXME: incredibly naive and slow! + this.data = this.data.concat(pairs); + }; + + this.setData = function(/*Array*/ pdata){ + // populate this.data and initialize lookup structures + this.data = pdata; + //all ellements must be a key and value pair + for(var i = 0; i < this.data.length; i++) { + var element = this.data[i]; + if(!dojo.lang.isArray(element)) { + this.data[i] = [element, element]; + } + } + }; + + + if(!dojo.string.isBlank(this.cbox.dataUrl) && this.cbox.preload){ + this.getData(this.cbox.dataUrl); + } else { + // check to see if we can populate the list from here yet + var opts = node.getElementsByTagName("option"); + var ol = opts.length; + var data = []; + for(var x=0; x 0)){ + var cpos = this._getCaretPos(this.textInputNode); + // only try to extend if we added the last character at the end of the input + if((cpos+1) > this.textInputNode.value.length){ + // only add to input node as we would overwrite Capitalisation of chars + this.textInputNode.value += results[0][0].substr(cpos); + // build a new range that has the distance from the earlier + // caret position to the end of the first string selected + this._setSelectedRange(this.textInputNode, cpos, this.textInputNode.value.length); + } + } + var typedText = this.textInputNode.value; + var even = true; + while(results.length){ + var tr = results.shift(); + if(tr){ + var td = document.createElement("div"); + var text = tr[0]; + var i = text.toLowerCase().indexOf(typedText.toLowerCase()); + if(i >= 0) { + var pre = text.substring(0, i); + var matched = text.substring(i, i + typedText.length); + var post = text.substring(i + typedText.length); + + if(!dojo.string.isBlank(pre)) { + td.appendChild(document.createTextNode(pre)); + } + var boldNode = document.createElement("b"); + td.appendChild(boldNode); + boldNode.appendChild(document.createTextNode(matched)); + td.appendChild(document.createTextNode(post)); + } else { + td.appendChild(document.createTextNode(tr[0])); + } + + td.setAttribute("resultName", tr[0]); + td.setAttribute("resultValue", tr[1]); + td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd"); + even = (!even); + this.optionsListNode.appendChild(td); + } + } + + // show our list (only if we have content, else nothing) + this.showResultList(); + }, + + postCreate : function() { + struts.widget.ComboBox.superclass.postCreate.apply(this); + var self = this; + //events + if(!dojo.string.isBlank(this.listenTopics)) { + var topics = this.listenTopics.split(","); + for(var i = 0; i < topics.length; i++) { + dojo.event.topic.subscribe(topics[i], function() { + var request = {cancel: false}; + self.notify(this.widgetId, "before", request); + if(request.cancel) { + return; + } + self.clearValues(); + self.dataProvider.getData(self.dataUrl); + }); + } + } + + //notify topics + if(!dojo.string.isBlank(this.notifyTopics)) { + this.notifyTopicsArray = this.notifyTopics.split(","); + } + + //before topics + if(!dojo.string.isBlank(this.beforeNotifyTopics)) { + this.beforeNotifyTopicsArray = this.beforeNotifyTopics.split(","); + } + + //after topics + if(!dojo.string.isBlank(this.afterNotifyTopics)) { + this.afterNotifyTopicsArray = this.afterNotifyTopics.split(","); + } + + //error topics + if(!dojo.string.isBlank(this.errorNotifyTopics)) { + this.errorNotifyTopicsArray = this.errorNotifyTopics.split(","); + } + + //value topics + if(!dojo.string.isBlank(this.valueNotifyTopics)) { + this.valueNotifyTopicsArray = this.valueNotifyTopics.split(","); + } + + //better name + this.comboBoxSelectionValue.name = dojo.string.isBlank(this.keyName) ? this.name + "Key" : this.keyName; + + //init values + this.comboBoxValue.value = this.initialValue; + this.comboBoxSelectionValue.value = this.initialKey; + this.textInputNode.value = this.initialValue; + + //tabindex + if(!dojo.string.isBlank(this.tabIndex)) { + this.textInputNode.tabIndex = this.tabIndex; + } + + //hide arrow? + if(!this.visibleDownArrow) { + dojo.html.hide(this.downArrowNode); + } + + //search type + if(!dojo.string.isBlank(this.searchType)) { + this.dataProvider.searchType = this.searchType.toUpperCase(); + } + }, + + clearValues : function() { + this.comboBoxValue.value = ""; + this.comboBoxSelectionValue.value = ""; + this.textInputNode.value = ""; + }, + + onValueChanged : function(data) { + this.notify(data, "valuechanged", null); + }, + + notify : function(data, type, e) { + var self = this; + //general topics + if(this.notifyTopicsArray) { + dojo.lang.forEach(this.notifyTopicsArray, function(topic) { + try { + dojo.event.topic.publish(topic, data, type, e, self); + } catch(ex){ + self.log(ex); + } + }); + } + + //before, after and error topics + var topicsArray = null; + switch(type) { + case "before": + this.notifyTo(this.beforeNotifyTopicsArray, [e, this]); + break; + case "load": + this.notifyTo(this.afterNotifyTopicsArray, [data, e, this]); + break; + case "error": + this.notifyTo(this.errorNotifyTopicsArray, [data, e, this]); + break; + case "valuechanged": + this.notifyTo(this.valueNotifyTopicsArray, [this.getSelectedValue(), this.getSelectedKey(), this.getText(), this]); + break; + } + }, + + notifyTo : function(topicsArray, params) { + var self = this; + if(topicsArray) { + dojo.lang.forEach(topicsArray, function(topic) { + try { + dojo.event.topic.publishApply(topic, params); + } catch(ex){ + self.log(ex); + } + }); + } + }, + + log : function(text) { + dojo.debug("[" + (this.widgetId ? this.widgetId : "unknown") + "] " + text); + }, + + _startSearchFromInput: function() { + var searchStr = this.textInputNode.value; + if(this.loadOnType) { + if(searchStr.length >= this.loadMinimum) { + var nuHref = this.dataUrl + (this.dataUrl.indexOf("?") > -1 ? "&" : "?"); + nuHref += this.name + '=' + encodeURIComponent(searchStr); + this.dataProvider.getData(nuHref); + this._startSearch(searchStr); + } else { + this._hideResultList(); + } + } + else { + this._startSearch(searchStr); + } + }, + + setSelectedKey : function(key) { + var data = this.dataProvider.data; + for(element in data) { + var obj = data[element]; + if(obj[1].toString() == key) { + this.setValue(obj[0].toString()); + this.comboBoxSelectionValue.value = obj[1].toString(); + } + } + }, + + getSelectedKey : function() { + return this.comboBoxSelectionValue.value; + }, + + getSelectedValue : function() { + return this.comboBoxValue.value; + }, + + getText : function() { + return this.textInputNode.value; + } +}); + +dojo.provide("dojo.widget.DropdownContainer"); + + + + + + + + + +dojo.widget.defineWidget( + "dojo.widget.DropdownContainer", + dojo.widget.HtmlWidget, + { + // summary: + // provides an input box and a button for a dropdown. + // In subclass, the dropdown can be specified. + + // inputWidth: String: width of the input box + inputWidth: "7em", + + // id: String: id of this widget + id: "", + + // inputId: String: id of the input box + inputId: "", + + // inputName: String: name of the input box + inputName: "", + + // iconURL: dojo.uri.Uri: icon for the dropdown button + iconURL: dojo.uri.moduleUri("dojo.widget", "templates/images/combo_box_arrow.png"), + + // copyClass: + // should we use the class properties on the source node instead + // of our own styles? + copyClasses: false, + + // iconAlt: dojo.uri.Uri: alt text for the dropdown button icon + iconAlt: "", + + // containerToggle: String: toggle property of the dropdown + containerToggle: "plain", + + // containerToggleDuration: Integer: toggle duration property of the dropdown + containerToggleDuration: 150, + + templateString: ' ${this.iconAlt}', + templateCssPath: "", + isContainer: true, + + attachTemplateNodes: function(){ + // summary: use attachTemplateNodes to specify containerNode, as fillInTemplate is too late for this + dojo.widget.DropdownContainer.superclass.attachTemplateNodes.apply(this, arguments); + this.popup = dojo.widget.createWidget("PopupContainer", {toggle: this.containerToggle, toggleDuration: this.containerToggleDuration}); + this.containerNode = this.popup.domNode; + }, + + fillInTemplate: function(args, frag){ + this.domNode.appendChild(this.popup.domNode); + if(this.id) { this.domNode.id = this.id; } + if(this.inputId){ this.inputNode.id = this.inputId; } + if(this.inputName){ this.inputNode.name = this.inputName; } + this.inputNode.style.width = this.inputWidth; + this.inputNode.disabled = this.disabled; + + if(this.copyClasses){ + this.inputNode.style = ""; + this.inputNode.className = this.getFragNodeRef(frag).className; + } + + + dojo.event.connect(this.inputNode, "onchange", this, "onInputChange"); + }, + + onIconClick: function(/*Event*/ evt){ + if(this.disabled) return; + if(!this.popup.isShowingNow){ + this.popup.open(this.inputNode, this, this.buttonNode); + }else{ + this.popup.close(); + } + }, + + hideContainer: function(){ + // summary: hide the dropdown + if(this.popup.isShowingNow){ + this.popup.close(); + } + }, + + onInputChange: function(){ + // summary: signal for changes in the input box + }, + + enable: function() { + // summary: enable this widget to accept user input + this.inputNode.disabled = false; + dojo.widget.DropdownContainer.superclass.enable.apply(this, arguments); + }, + + disable: function() { + // summary: lock this widget so that the user can't change the value + this.inputNode.disabled = true; + dojo.widget.DropdownContainer.superclass.disable.apply(this, arguments); + } + } +); + +dojo.provide("dojo.date.serialize"); + + + +/* ISO 8601 Functions + *********************/ + +dojo.date.setIso8601 = function(/*Date*/dateObject, /*String*/formattedString){ + // summary: sets a Date object based on an ISO 8601 formatted string (uses date and time) + var comps = (formattedString.indexOf("T") == -1) ? formattedString.split(" ") : formattedString.split("T"); + dateObject = dojo.date.setIso8601Date(dateObject, comps[0]); + if(comps.length == 2){ dateObject = dojo.date.setIso8601Time(dateObject, comps[1]); } + return dateObject; /* Date or null */ +}; + +dojo.date.fromIso8601 = function(/*String*/formattedString){ + // summary: returns a Date object based on an ISO 8601 formatted string (uses date and time) + return dojo.date.setIso8601(new Date(0, 0), formattedString); +}; + +dojo.date.setIso8601Date = function(/*String*/dateObject, /*String*/formattedString){ + // summary: sets a Date object based on an ISO 8601 formatted string (date only) + var regexp = "^([0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|" + + "(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$"; + var d = formattedString.match(new RegExp(regexp)); + if(!d){ + dojo.debug("invalid date string: " + formattedString); + return null; // null + } + var year = d[1]; + var month = d[4]; + var date = d[6]; + var dayofyear = d[8]; + var week = d[10]; + var dayofweek = d[12] ? d[12] : 1; + + dateObject.setFullYear(year); + + if(dayofyear){ + dateObject.setMonth(0); + dateObject.setDate(Number(dayofyear)); + } + else if(week){ + dateObject.setMonth(0); + dateObject.setDate(1); + var gd = dateObject.getDay(); + var day = gd ? gd : 7; + var offset = Number(dayofweek) + (7 * Number(week)); + + if(day <= 4){ dateObject.setDate(offset + 1 - day); } + else{ dateObject.setDate(offset + 8 - day); } + } else{ + if(month){ + dateObject.setDate(1); + dateObject.setMonth(month - 1); + } + if(date){ dateObject.setDate(date); } + } + + return dateObject; // Date +}; + +dojo.date.fromIso8601Date = function(/*String*/formattedString){ + // summary: returns a Date object based on an ISO 8601 formatted string (date only) + return dojo.date.setIso8601Date(new Date(0, 0), formattedString); +}; + +dojo.date.setIso8601Time = function(/*Date*/dateObject, /*String*/formattedString){ + // summary: sets a Date object based on an ISO 8601 formatted string (time only) + + // first strip timezone info from the end + var timezone = "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$"; + var d = formattedString.match(new RegExp(timezone)); + + var offset = 0; // local time if no tz info + if(d){ + if(d[0] != 'Z'){ + offset = (Number(d[3]) * 60) + Number(d[5]); + offset *= ((d[2] == '-') ? 1 : -1); + } + offset -= dateObject.getTimezoneOffset(); + formattedString = formattedString.substr(0, formattedString.length - d[0].length); + } + + // then work out the time + var regexp = "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$"; + d = formattedString.match(new RegExp(regexp)); + if(!d){ + dojo.debug("invalid time string: " + formattedString); + return null; // null + } + var hours = d[1]; + var mins = Number((d[3]) ? d[3] : 0); + var secs = (d[5]) ? d[5] : 0; + var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0; + + dateObject.setHours(hours); + dateObject.setMinutes(mins); + dateObject.setSeconds(secs); + dateObject.setMilliseconds(ms); + + if(offset !== 0){ + dateObject.setTime(dateObject.getTime() + offset * 60000); + } + return dateObject; // Date +}; + +dojo.date.fromIso8601Time = function(/*String*/formattedString){ + // summary: returns a Date object based on an ISO 8601 formatted string (date only) + return dojo.date.setIso8601Time(new Date(0, 0), formattedString); +}; + + +/* RFC-3339 Date Functions + *************************/ + +dojo.date.toRfc3339 = function(/*Date?*/dateObject, /*String?*/selector){ +// summary: +// Format a JavaScript Date object as a string according to RFC 3339 +// +// dateObject: +// A JavaScript date, or the current date and time, by default +// +// selector: +// "dateOnly" or "timeOnly" to format selected portions of the Date object. +// Date and time will be formatted by default. + +//FIXME: tolerate Number, string input? + if(!dateObject){ + dateObject = new Date(); + } + + var _ = dojo.string.pad; + var formattedDate = []; + if(selector != "timeOnly"){ + var date = [_(dateObject.getFullYear(),4), _(dateObject.getMonth()+1,2), _(dateObject.getDate(),2)].join('-'); + formattedDate.push(date); + } + if(selector != "dateOnly"){ + var time = [_(dateObject.getHours(),2), _(dateObject.getMinutes(),2), _(dateObject.getSeconds(),2)].join(':'); + var timezoneOffset = dateObject.getTimezoneOffset(); + time += (timezoneOffset > 0 ? "-" : "+") + + _(Math.floor(Math.abs(timezoneOffset)/60),2) + ":" + + _(Math.abs(timezoneOffset)%60,2); + formattedDate.push(time); + } + return formattedDate.join('T'); // String +}; + +dojo.date.fromRfc3339 = function(/*String*/rfcDate){ +// summary: +// Create a JavaScript Date object from a string formatted according to RFC 3339 +// +// rfcDate: +// A string such as 2005-06-30T08:05:00-07:00 +// "any" is also supported in place of a time. + + // backwards compatible support for use of "any" instead of just not + // including the time + if(rfcDate.indexOf("Tany")!=-1){ + rfcDate = rfcDate.replace("Tany",""); + } + var dateObject = new Date(); + return dojo.date.setIso8601(dateObject, rfcDate); // Date or null +}; + +dojo.provide("dojo.date.common"); + + +/* Supplementary Date Functions + *******************************/ + +dojo.date.setDayOfYear = function(/*Date*/dateObject, /*Number*/dayOfYear){ + // summary: sets dateObject according to day of the year (1..366) + dateObject.setMonth(0); + dateObject.setDate(dayOfYear); + return dateObject; // Date +} + +dojo.date.getDayOfYear = function(/*Date*/dateObject){ + // summary: gets the day of the year as represented by dateObject + var fullYear = dateObject.getFullYear(); + var lastDayOfPrevYear = new Date(fullYear-1, 11, 31); + return Math.floor((dateObject.getTime() - + lastDayOfPrevYear.getTime()) / 86400000); // Number +} + + +dojo.date.setWeekOfYear = function(/*Date*/dateObject, /*Number*/week, /*Number*/firstDay){ + if(arguments.length == 1){ firstDay = 0; } // Sunday + dojo.unimplemented("dojo.date.setWeekOfYear"); +} + +dojo.date.getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDay){ + if(arguments.length == 1){ firstDay = 0; } // Sunday + + // work out the first day of the year corresponding to the week + var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1); + var day = firstDayOfYear.getDay(); + firstDayOfYear.setDate(firstDayOfYear.getDate() - + day + firstDay - (day > firstDay ? 7 : 0)); + + return Math.floor((dateObject.getTime() - + firstDayOfYear.getTime()) / 604800000); +} + +dojo.date.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week, /*Number*/firstDay){ + // summary: unimplemented + if (arguments.length == 1) { firstDay = 1; } // Monday + dojo.unimplemented("dojo.date.setIsoWeekOfYear"); +} + +dojo.date.getIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDay) { + // summary: unimplemented + if (arguments.length == 1) { firstDay = 1; } // Monday + dojo.unimplemented("dojo.date.getIsoWeekOfYear"); +} + + +/* Informational Functions + **************************/ + +//DEPRECATED: These timezone arrays will be deprecated in 0.5 +dojo.date.shortTimezones = ["IDLW", "BET", "HST", "MART", "AKST", "PST", "MST", + "CST", "EST", "AST", "NFT", "BST", "FST", "AT", "GMT", "CET", "EET", "MSK", + "IRT", "GST", "AFT", "AGTT", "IST", "NPT", "ALMT", "MMT", "JT", "AWST", + "JST", "ACST", "AEST", "LHST", "VUT", "NFT", "NZT", "CHAST", "PHOT", + "LINT"]; +dojo.date.timezoneOffsets = [-720, -660, -600, -570, -540, -480, -420, -360, + -300, -240, -210, -180, -120, -60, 0, 60, 120, 180, 210, 240, 270, 300, + 330, 345, 360, 390, 420, 480, 540, 570, 600, 630, 660, 690, 720, 765, 780, + 840]; +/* +dojo.date.timezones = ["International Date Line West", "Bering Standard Time", + "Hawaiian Standard Time", "Marquesas Time", "Alaska Standard Time", + "Pacific Standard Time (USA)", "Mountain Standard Time", + "Central Standard Time (USA)", "Eastern Standard Time (USA)", + "Atlantic Standard Time", "Newfoundland Time", "Brazil Standard Time", + "Fernando de Noronha Standard Time (Brazil)", "Azores Time", + "Greenwich Mean Time", "Central Europe Time", "Eastern Europe Time", + "Moscow Time", "Iran Standard Time", "Gulf Standard Time", + "Afghanistan Time", "Aqtobe Time", "Indian Standard Time", "Nepal Time", + "Almaty Time", "Myanmar Time", "Java Time", + "Australian Western Standard Time", "Japan Standard Time", + "Australian Central Standard Time", "Lord Hove Standard Time (Australia)", + "Vanuata Time", "Norfolk Time (Australia)", "New Zealand Standard Time", + "Chatham Standard Time (New Zealand)", "Phoenix Islands Time (Kribati)", + "Line Islands Time (Kribati)"]; +*/ + +dojo.date.getDaysInMonth = function(/*Date*/dateObject){ + // summary: returns the number of days in the month used by dateObject + var month = dateObject.getMonth(); + var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if (month == 1 && dojo.date.isLeapYear(dateObject)) { return 29; } // Number + else { return days[month]; } // Number +} + +dojo.date.isLeapYear = function(/*Date*/dateObject){ +// summary: +// Determines if the year of the dateObject is a leap year +// +// description: +// Leap years are years with an additional day YYYY-02-29, where the year +// number is a multiple of four with the following exception: If a year +// is a multiple of 100, then it is only a leap year if it is also a +// multiple of 400. For example, 1900 was not a leap year, but 2000 is one. + + var year = dateObject.getFullYear(); + return (year%400 == 0) ? true : (year%100 == 0) ? false : (year%4 == 0) ? true : false; // Boolean +} + +// FIXME: This is not localized +dojo.date.getTimezoneName = function(/*Date*/dateObject){ +// summary: +// Get the user's time zone as provided by the browser +// +// dateObject: needed because the timezone may vary with time (daylight savings) +// +// description: +// Try to get time zone info from toString or toLocaleString +// method of the Date object -- UTC offset is not a time zone. +// See http://www.twinsun.com/tz/tz-link.htm +// Note: results may be inconsistent across browsers. + + var str = dateObject.toString(); // Start looking in toString + var tz = ''; // The result -- return empty string if nothing found + var match; + + // First look for something in parentheses -- fast lookup, no regex + var pos = str.indexOf('('); + if (pos > -1) { + pos++; + tz = str.substring(pos, str.indexOf(')')); + } + // If at first you don't succeed ... + else{ + // If IE knows about the TZ, it appears before the year + // Capital letters or slash before a 4-digit year + // at the end of string + var pat = /([A-Z\/]+) \d{4}$/; + if((match = str.match(pat))) { + tz = match[1]; + } + // Some browsers (e.g. Safari) glue the TZ on the end + // of toLocaleString instead of putting it in toString + else{ + str = dateObject.toLocaleString(); + // Capital letters or slash -- end of string, + // after space + pat = / ([A-Z\/]+)$/; + if((match = str.match(pat))) { + tz = match[1]; + } + } + } + + // Make sure it doesn't somehow end up return AM or PM + return tz == 'AM' || tz == 'PM' ? '' : tz; //String +} + + +//FIXME: not localized +dojo.date.getOrdinal = function(dateObject){ + // summary: returns the appropriate suffix (English only) for the day of the month, e.g. 'st' for 1, 'nd' for 2, etc.) + var date = dateObject.getDate(); + + if(date%100 != 11 && date%10 == 1){ return "st"; } // String + else if(date%100 != 12 && date%10 == 2){ return "nd"; } // String + else if(date%100 != 13 && date%10 == 3){ return "rd"; } // String + else{ return "th"; } // String +} + + +/* compare and add + ******************/ +dojo.date.compareTypes={ + // summary + // bitmask for comparison operations. + DATE:1, TIME:2 +}; +dojo.date.compare=function(/* Date */ dateA, /* Date */ dateB, /* dojo.date.compareTypes */ options){ + // summary + // Compare two date objects by date, time, or both. Returns 0 if equal, positive if a > b, else negative. + var dA=dateA; + var dB=dateB||new Date(); + var now=new Date(); + //FIXME: shorten this code + with(dojo.date.compareTypes){ + var opt=options||(DATE|TIME); + var d1=new Date( + (opt&DATE)?dA.getFullYear():now.getFullYear(), + (opt&DATE)?dA.getMonth():now.getMonth(), + (opt&DATE)?dA.getDate():now.getDate(), + (opt&TIME)?dA.getHours():0, + (opt&TIME)?dA.getMinutes():0, + (opt&TIME)?dA.getSeconds():0 + ); + var d2=new Date( + (opt&DATE)?dB.getFullYear():now.getFullYear(), + (opt&DATE)?dB.getMonth():now.getMonth(), + (opt&DATE)?dB.getDate():now.getDate(), + (opt&TIME)?dB.getHours():0, + (opt&TIME)?dB.getMinutes():0, + (opt&TIME)?dB.getSeconds():0 + ); + } + if(d1.valueOf()>d2.valueOf()){ + return 1; // int + } + if(d1.valueOf() 0) ? 5 : -5; + weeks = (incr > 0) ? ((incr-5)/5) : ((incr+5)/5); + } + else { + days = mod; + weeks = parseInt(incr/5); + } + // Get weekday value for orig date param + strt = dt.getDay(); + // Orig date is Sat / positive incrementer + // Jump over Sun + if (strt == 6 && incr > 0) { + adj = 1; + } + // Orig date is Sun / negative incrementer + // Jump back over Sat + else if (strt == 0 && incr < 0) { + adj = -1; + } + // Get weekday val for the new date + trgt = (strt + days); + // New date is on Sat or Sun + if (trgt == 0 || trgt == 6) { + adj = (incr > 0) ? 2 : -2; + } + // Increment by number of weeks plus leftover days plus + // weekend adjustments + sum.setDate(dat + (7*weeks) + days + adj); + break; + case HOUR: + sum.setHours(sum.getHours()+incr); + break; + case MINUTE: + sum.setMinutes(sum.getMinutes()+incr); + break; + case SECOND: + sum.setSeconds(sum.getSeconds()+incr); + break; + case MILLISECOND: + sum.setMilliseconds(sum.getMilliseconds()+incr); + break; + default: + // Do nothing + break; + } + } + + return sum; // Date +}; + +dojo.date.diff = function(/* Date */ dtA, /* Date */ dtB, /* dojo.date.dateParts */ interv){ +// summary: +// Get the difference in a specific unit of time (e.g., number of months, weeks, +// days, etc.) between two dates. +// +// dtA: +// A Javascript Date object +// +// dtB: +// A Javascript Date object +// +// interv: +// A constant representing the interval, e.g. YEAR, MONTH, DAY. See dojo.date.dateParts. + + // Accept timestamp input + if(typeof dtA == 'number'){dtA = new Date(dtA);} + if(typeof dtB == 'number'){dtB = new Date(dtB);} + var yeaDiff = dtB.getFullYear() - dtA.getFullYear(); + var monDiff = (dtB.getMonth() - dtA.getMonth()) + (yeaDiff * 12); + var msDiff = dtB.getTime() - dtA.getTime(); // Millisecs + var secDiff = msDiff/1000; + var minDiff = secDiff/60; + var houDiff = minDiff/60; + var dayDiff = houDiff/24; + var weeDiff = dayDiff/7; + var delta = 0; // Integer return value + + with(dojo.date.dateParts){ + switch(interv){ + case YEAR: + delta = yeaDiff; + break; + case QUARTER: + var mA = dtA.getMonth(); + var mB = dtB.getMonth(); + // Figure out which quarter the months are in + var qA = Math.floor(mA/3) + 1; + var qB = Math.floor(mB/3) + 1; + // Add quarters for any year difference between the dates + qB += (yeaDiff * 4); + delta = qB - qA; + break; + case MONTH: + delta = monDiff; + break; + case WEEK: + // Truncate instead of rounding + // Don't use Math.floor -- value may be negative + delta = parseInt(weeDiff); + break; + case DAY: + delta = dayDiff; + break; + case WEEKDAY: + var days = Math.round(dayDiff); + var weeks = parseInt(days/7); + var mod = days % 7; + + // Even number of weeks + if (mod == 0) { + days = weeks*5; + } + // Weeks plus spare change (< 7 days) + else { + var adj = 0; + var aDay = dtA.getDay(); + var bDay = dtB.getDay(); + + weeks = parseInt(days/7); + mod = days % 7; + // Mark the date advanced by the number of + // round weeks (may be zero) + var dtMark = new Date(dtA); + dtMark.setDate(dtMark.getDate()+(weeks*7)); + var dayMark = dtMark.getDay(); + // Spare change days -- 6 or less + // ---------- + // Positive diff + if (dayDiff > 0) { + switch (true) { + // Range starts on Sat + case aDay == 6: + adj = -1; + break; + // Range starts on Sun + case aDay == 0: + adj = 0; + break; + // Range ends on Sat + case bDay == 6: + adj = -1; + break; + // Range ends on Sun + case bDay == 0: + adj = -2; + break; + // Range contains weekend + case (dayMark + mod) > 5: + adj = -2; + break; + default: + // Do nothing + break; + } + } + // Negative diff + else if (dayDiff < 0) { + switch (true) { + // Range starts on Sat + case aDay == 6: + adj = 0; + break; + // Range starts on Sun + case aDay == 0: + adj = 1; + break; + // Range ends on Sat + case bDay == 6: + adj = 2; + break; + // Range ends on Sun + case bDay == 0: + adj = 1; + break; + // Range contains weekend + case (dayMark + mod) < 0: + adj = 2; + break; + default: + // Do nothing + break; + } + } + days += adj; + days -= (weeks*2); + } + delta = days; + + break; + case HOUR: + delta = houDiff; + break; + case MINUTE: + delta = minDiff; + break; + case SECOND: + delta = secDiff; + break; + case MILLISECOND: + delta = msDiff; + break; + default: + // Do nothing + break; + } + } + + // Round for fractional values and DST leaps + return Math.round(delta); // Number (integer) +}; + +dojo.provide("dojo.date.supplemental"); + +dojo.date.getFirstDayOfWeek = function(/*String?*/locale){ +// summary: Returns a zero-based index for first day of the week +// description: +// Returns a zero-based index for first day of the week, as used by the local (Gregorian) calendar. +// e.g. Sunday (returns 0), or Monday (returns 1) + + // from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/firstDay + var firstDay = {/*default is 1=Monday*/ + mv:5, + ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,lb:6,ly:6,ma:6,om:6,qa:6,sa:6, + sd:6,so:6,tn:6,ye:6, + as:0,au:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,il:0,is:0,jm:0,jp:0,kg:0,kr:0,la:0, + mh:0,mo:0,mp:0,mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,vi:0,za:0,zw:0, + et:0,mw:0,ng:0,tj:0, + gb:0, + sy:4 + }; + + locale = dojo.hostenv.normalizeLocale(locale); + var country = locale.split("-")[1]; + var dow = firstDay[country]; + return (typeof dow == 'undefined') ? 1 : dow; /*Number*/ +}; + +dojo.date.getWeekend = function(/*String?*/locale){ +// summary: Returns a hash containing the start and end days of the weekend +// description: +// Returns a hash containing the start and end days of the weekend according to local custom using locale, +// or by default in the user's locale. +// e.g. {start:6, end:0} + + // from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/weekend{Start,End} + var weekendStart = {/*default is 6=Saturday*/ + eg:5,il:5,sy:5, + 'in':0, + ae:4,bh:4,dz:4,iq:4,jo:4,kw:4,lb:4,ly:4,ma:4,om:4,qa:4,sa:4,sd:4,tn:4,ye:4 + }; + + var weekendEnd = {/*default is 0=Sunday*/ + ae:5,bh:5,dz:5,iq:5,jo:5,kw:5,lb:5,ly:5,ma:5,om:5,qa:5,sa:5,sd:5,tn:5,ye:5,af:5,ir:5, + eg:6,il:6,sy:6 + }; + + locale = dojo.hostenv.normalizeLocale(locale); + var country = locale.split("-")[1]; + var start = weekendStart[country]; + var end = weekendEnd[country]; + if(typeof start == 'undefined'){start=6;} + if(typeof end == 'undefined'){end=0;} + return {start:start, end:end}; /*Object {start,end}*/ +}; + +dojo.date.isWeekend = function(/*Date?*/dateObj, /*String?*/locale){ +// summary: +// Determines if the date falls on a weekend, according to local custom. + + var weekend = dojo.date.getWeekend(locale); + var day = (dateObj || new Date()).getDay(); + if(weekend.end= weekend.start && day <= weekend.end; // Boolean +}; + +dojo.provide("dojo.i18n.common"); + +dojo.i18n.getLocalization = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){ +// summary: +// Returns an Object containing the localization for a given resource bundle +// in a package, matching the specified locale. +// +// description: +// Returns a hash containing name/value pairs in its prototypesuch that values can be easily overridden. +// Throws an exception if the bundle is not found. +// Bundle must have already been loaded by dojo.requireLocalization() or by a build optimization step. +// +// packageName: package which is associated with this resource +// bundleName: the base filename of the resource bundle (without the ".js" suffix) +// locale: the variant to load (optional). By default, the locale defined by the +// host environment: dojo.locale + + dojo.hostenv.preloadLocalizations(); + locale = dojo.hostenv.normalizeLocale(locale); + + // look for nearest locale match + var elements = locale.split('-'); + var module = [packageName,"nls",bundleName].join('.'); + var bundle = dojo.hostenv.findModule(module, true); + + var localization; + for(var i = elements.length; i > 0; i--){ + var loc = elements.slice(0, i).join('_'); + if(bundle[loc]){ + localization = bundle[loc]; + break; + } + } + if(!localization){ + localization = bundle.ROOT; + } + + // make a singleton prototype so that the caller won't accidentally change the values globally + if(localization){ + var clazz = function(){}; + clazz.prototype = localization; + return new clazz(); // Object + } + + dojo.raise("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale); +}; + +dojo.i18n.isLTR = function(/*String?*/locale){ +// summary: +// Is the language read left-to-right? Most exceptions are for middle eastern languages. +// +// locale: a string representing the locale. By default, the locale defined by the +// host environment: dojo.locale + + var lang = dojo.hostenv.normalizeLocale(locale).split('-')[0]; + var RTL = {ar:true,fa:true,he:true,ur:true,yi:true}; + return !RTL[lang]; // Boolean +}; + +dojo.provide("dojo.date.format"); + + + + + + + + + +// Load the bundles containing localization information for +// names and formats + + + +//NOTE: Everything in this module assumes Gregorian calendars. +// Other calendars will be implemented in separate modules. + +(function(){ +dojo.date.format = function(/*Date*/dateObject, /*Object?*/options){ +// +// summary: +// Format a Date object as a String, using locale-specific settings. +// +// description: +// Create a string from a Date object using a known localized pattern. +// By default, this method formats both date and time from dateObject. +// Formatting patterns are chosen appropriate to the locale. Different +// formatting lengths may be chosen, with "full" used by default. +// Custom patterns may be used or registered with translations using +// the addCustomBundle method. +// Formatting patterns are implemented using the syntax described at +// http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns +// +// dateObject: +// the date and/or time to be formatted. If a time only is formatted, +// the values in the year, month, and day fields are irrelevant. The +// opposite is true when formatting only dates. +// +// options: object {selector: string, formatLength: string, datePattern: string, timePattern: string, locale: string} +// selector- choice of timeOnly,dateOnly (default: date and time) +// formatLength- choice of long, short, medium or full (plus any custom additions). Defaults to 'full' +// datePattern,timePattern- override pattern with this string +// am,pm- override strings for am/pm in times +// locale- override the locale used to determine formatting rules +// + + if(typeof options == "string"){ + dojo.deprecated("dojo.date.format", "To format dates with POSIX-style strings, please use dojo.date.strftime instead", "0.5"); + return dojo.date.strftime(dateObject, options); + } + + // Format a pattern without literals + function formatPattern(dateObject, pattern){ + return pattern.replace(/([a-z])\1*/ig, function(match){ + var s; + var c = match.charAt(0); + var l = match.length; + var pad; + var widthList = ["abbr", "wide", "narrow"]; + switch(c){ + case 'G': + if(l>3){dojo.unimplemented("Era format not implemented");} + s = info.eras[dateObject.getFullYear() < 0 ? 1 : 0]; + break; + case 'y': + s = dateObject.getFullYear(); + switch(l){ + case 1: + break; + case 2: + s = String(s).substr(-2); + break; + default: + pad = true; + } + break; + case 'Q': + case 'q': + s = Math.ceil((dateObject.getMonth()+1)/3); + switch(l){ + case 1: case 2: + pad = true; + break; + case 3: + case 4: + dojo.unimplemented("Quarter format not implemented"); + } + break; + case 'M': + case 'L': + var m = dateObject.getMonth(); + var width; + switch(l){ + case 1: case 2: + s = m+1; pad = true; + break; + case 3: case 4: case 5: + width = widthList[l-3]; + break; + } + if(width){ + var type = (c == "L") ? "standalone" : "format"; + var prop = ["months",type,width].join("-"); + s = info[prop][m]; + } + break; + case 'w': + var firstDay = 0; + s = dojo.date.getWeekOfYear(dateObject, firstDay); pad = true; + break; + case 'd': + s = dateObject.getDate(); pad = true; + break; + case 'D': + s = dojo.date.getDayOfYear(dateObject); pad = true; + break; + case 'E': + case 'e': + case 'c': // REVIEW: don't see this in the spec? + var d = dateObject.getDay(); + var width; + switch(l){ + case 1: case 2: + if(c == 'e'){ + var first = dojo.date.getFirstDayOfWeek(options.locale); + d = (d-first+7)%7; + } + if(c != 'c'){ + s = d+1; pad = true; + break; + } + // else fallthrough... + case 3: case 4: case 5: + width = widthList[l-3]; + break; + } + if(width){ + var type = (c == "c") ? "standalone" : "format"; + var prop = ["days",type,width].join("-"); + s = info[prop][d]; + } + break; + case 'a': + var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm'; + s = info[timePeriod]; + break; + case 'h': + case 'H': + case 'K': + case 'k': + var h = dateObject.getHours(); + // strange choices in the date format make it impossible to write this succinctly + switch (c) { + case 'h': // 1-12 + s = (h % 12) || 12; + break; + case 'H': // 0-23 + s = h; + break; + case 'K': // 0-11 + s = (h % 12); + break; + case 'k': // 1-24 + s = h || 24; + break; + } + pad = true; + break; + case 'm': + s = dateObject.getMinutes(); pad = true; + break; + case 's': + s = dateObject.getSeconds(); pad = true; + break; + case 'S': + s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); + break; + case 'v': // FIXME: don't know what this is. seems to be same as z? + case 'z': + // We only have one timezone to offer; the one from the browser + s = dojo.date.getTimezoneName(dateObject); + if(s){break;} + l=4; + // fallthrough... use GMT if tz not available + case 'Z': + var offset = dateObject.getTimezoneOffset(); + var tz = [ + (offset<=0 ? "+" : "-"), + dojo.string.pad(Math.floor(Math.abs(offset)/60), 2), + dojo.string.pad(Math.abs(offset)% 60, 2) + ]; + if(l==4){ + tz.splice(0, 0, "GMT"); + tz.splice(3, 0, ":"); + } + s = tz.join(""); + break; + case 'Y': + case 'u': + case 'W': + case 'F': + case 'g': + case 'A': + dojo.debug(match+" modifier not yet implemented"); + s = "?"; + break; + default: + dojo.raise("dojo.date.format: invalid pattern char: "+pattern); + } + if(pad){ s = dojo.string.pad(s, l); } + return s; + }); + } + + options = options || {}; + + var locale = dojo.hostenv.normalizeLocale(options.locale); + var formatLength = options.formatLength || 'full'; + var info = dojo.date._getGregorianBundle(locale); + var str = []; + var sauce = dojo.lang.curry(this, formatPattern, dateObject); + if(options.selector != "timeOnly"){ + var datePattern = options.datePattern || info["dateFormat-"+formatLength]; + if(datePattern){str.push(_processPattern(datePattern, sauce));} + } + if(options.selector != "dateOnly"){ + var timePattern = options.timePattern || info["timeFormat-"+formatLength]; + if(timePattern){str.push(_processPattern(timePattern, sauce));} + } + var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time + return result; /*String*/ +}; + +dojo.date.parse = function(/*String*/value, /*Object?*/options){ +// +// summary: +// Convert a properly formatted string to a primitive Date object, +// using locale-specific settings. +// +// description: +// Create a Date object from a string using a known localized pattern. +// By default, this method parses looking for both date and time in the string. +// Formatting patterns are chosen appropriate to the locale. Different +// formatting lengths may be chosen, with "full" used by default. +// Custom patterns may be used or registered with translations using +// the addCustomBundle method. +// Formatting patterns are implemented using the syntax described at +// http://www.unicode.org/reports/tr35/#Date_Format_Patterns +// +// value: +// A string representation of a date +// +// options: object {selector: string, formatLength: string, datePattern: string, timePattern: string, locale: string, strict: boolean} +// selector- choice of timeOnly, dateOnly, dateTime (default: dateOnly) +// formatLength- choice of long, short, medium or full (plus any custom additions). Defaults to 'full' +// datePattern,timePattern- override pattern with this string +// am,pm- override strings for am/pm in times +// locale- override the locale used to determine formatting rules +// strict- strict parsing, off by default +// + + options = options || {}; + var locale = dojo.hostenv.normalizeLocale(options.locale); + var info = dojo.date._getGregorianBundle(locale); + var formatLength = options.formatLength || 'full'; + if(!options.selector){ options.selector = 'dateOnly'; } + var datePattern = options.datePattern || info["dateFormat-" + formatLength]; + var timePattern = options.timePattern || info["timeFormat-" + formatLength]; + + var pattern; + if(options.selector == 'dateOnly'){ + pattern = datePattern; + } + else if(options.selector == 'timeOnly'){ + pattern = timePattern; + }else if(options.selector == 'dateTime'){ + pattern = datePattern + ' ' + timePattern; //TODO: use locale-specific pattern to assemble date + time + }else{ + var msg = "dojo.date.parse: Unknown selector param passed: '" + options.selector + "'."; + msg += " Defaulting to date pattern."; + dojo.debug(msg); + pattern = datePattern; + } + + var groups = []; + var dateREString = _processPattern(pattern, dojo.lang.curry(this, _buildDateTimeRE, groups, info, options)); + var dateRE = new RegExp("^" + dateREString + "$"); + + var match = dateRE.exec(value); + if(!match){ + return null; + } + + var widthList = ['abbr', 'wide', 'narrow']; + //1972 is a leap year. We want to avoid Feb 29 rolling over into Mar 1, + //in the cases where the year is parsed after the month and day. + var result = new Date(1972, 0); + var expected = {}; + for(var i=1; i2) { + if(!options.strict){ + //Tolerate abbreviating period in month part + v = v.replace(/\./g,''); + //Case-insensitive + v = v.toLowerCase(); + } + var months = info['months-format-' + widthList[l-3]].concat(); + for (var j=0; j 15 + } else if(v == am && hours == 12){ + result.setHours(0); //12am -> 0 + } + break; + case 'K': //hour (1-24) + if(v==24){v=0;} + // fallthrough... + case 'h': //hour (1-12) + case 'H': //hour (0-23) + case 'k': //hour (0-11) + //TODO: strict bounds checking, padding + if(v>23){ + dojo.debug("dojo.date.parse: Illegal hours value"); + return null; + } + + //in the 12-hour case, adjusting for am/pm requires the 'a' part + //which for now we will assume always comes after the 'h' part + result.setHours(v); + break; + case 'm': //minutes + result.setMinutes(v); + break; + case 's': //seconds + result.setSeconds(v); + break; + case 'S': //milliseconds + result.setMilliseconds(v); + break; + default: + dojo.unimplemented("dojo.date.parse: unsupported pattern char=" + grp.charAt(0)); + } + } + + //validate parse date fields versus input date fields + if(expected.year && result.getFullYear() != expected.year){ + dojo.debug("Parsed year: '" + result.getFullYear() + "' did not match input year: '" + expected.year + "'."); + return null; + } + if(expected.month && result.getMonth() != expected.month){ + dojo.debug("Parsed month: '" + result.getMonth() + "' did not match input month: '" + expected.month + "'."); + return null; + } + if(expected.date && result.getDate() != expected.date){ + dojo.debug("Parsed day of month: '" + result.getDate() + "' did not match input day of month: '" + expected.date + "'."); + return null; + } + + //TODO: implement a getWeekday() method in order to test + //validity of input strings containing 'EEE' or 'EEEE'... + + return result; /*Date*/ +}; + +function _processPattern(pattern, applyPattern, applyLiteral, applyAll){ + // Process a pattern with literals in it + // Break up on single quotes, treat every other one as a literal, except '' which becomes ' + var identity = function(x){return x;}; + applyPattern = applyPattern || identity; + applyLiteral = applyLiteral || identity; + applyAll = applyAll || identity; + + //split on single quotes (which escape literals in date format strings) + //but preserve escaped single quotes (e.g., o''clock) + var chunks = pattern.match(/(''|[^'])+/g); + var literal = false; + + for(var i=0; i2) ? '\\S+' : '\\d{1,2}'; + break; + case 'd': + s = '\\d{1,2}'; + break; + case 'E': + s = '\\S+'; + break; + case 'h': + case 'H': + case 'K': + case 'k': + s = '\\d{1,2}'; + break; + case 'm': + case 's': + s = '[0-5]\\d'; + break; + case 'S': + s = '\\d{1,3}'; + break; + case 'a': + var am = options.am || info.am || 'AM'; + var pm = options.pm || info.pm || 'PM'; + if(options.strict){ + s = am + '|' + pm; + }else{ + s = am; + s += (am != am.toLowerCase()) ? '|' + am.toLowerCase() : ''; + s += '|'; + s += (pm != pm.toLowerCase()) ? pm + '|' + pm.toLowerCase() : pm; + } + break; + default: + dojo.unimplemented("parse of date format, pattern=" + pattern); + } + + if(groups){ groups.push(match); } + +//FIXME: replace whitespace within final regexp with more flexible whitespace match instead? + //tolerate whitespace + return '\\s*(' + s + ')\\s*'; + }); +} +})(); + +//TODO: try to common strftime and format code somehow? + +dojo.date.strftime = function(/*Date*/dateObject, /*String*/format, /*String?*/locale){ +// +// summary: +// Formats the date object using the specifications of the POSIX strftime function +// +// description: +// see + + // zero pad + var padChar = null; + function _(s, n){ + return dojo.string.pad(s, n || 2, padChar || "0"); + } + + var info = dojo.date._getGregorianBundle(locale); + + function $(property){ + switch (property){ + case "a": // abbreviated weekday name according to the current locale + return dojo.date.getDayShortName(dateObject, locale); + + case "A": // full weekday name according to the current locale + return dojo.date.getDayName(dateObject, locale); + + case "b": + case "h": // abbreviated month name according to the current locale + return dojo.date.getMonthShortName(dateObject, locale); + + case "B": // full month name according to the current locale + return dojo.date.getMonthName(dateObject, locale); + + case "c": // preferred date and time representation for the current + // locale + return dojo.date.format(dateObject, {locale: locale}); + + case "C": // century number (the year divided by 100 and truncated + // to an integer, range 00 to 99) + return _(Math.floor(dateObject.getFullYear()/100)); + + case "d": // day of the month as a decimal number (range 01 to 31) + return _(dateObject.getDate()); + + case "D": // same as %m/%d/%y + return $("m") + "/" + $("d") + "/" + $("y"); + + case "e": // day of the month as a decimal number, a single digit is + // preceded by a space (range ' 1' to '31') + if(padChar == null){ padChar = " "; } + return _(dateObject.getDate()); + + case "f": // month as a decimal number, a single digit is + // preceded by a space (range ' 1' to '12') + if(padChar == null){ padChar = " "; } + return _(dateObject.getMonth()+1); + + case "g": // like %G, but without the century. + break; + + case "G": // The 4-digit year corresponding to the ISO week number + // (see %V). This has the same format and value as %Y, + // except that if the ISO week number belongs to the + // previous or next year, that year is used instead. + dojo.unimplemented("unimplemented modifier 'G'"); + break; + + case "F": // same as %Y-%m-%d + return $("Y") + "-" + $("m") + "-" + $("d"); + + case "H": // hour as a decimal number using a 24-hour clock (range + // 00 to 23) + return _(dateObject.getHours()); + + case "I": // hour as a decimal number using a 12-hour clock (range + // 01 to 12) + return _(dateObject.getHours() % 12 || 12); + + case "j": // day of the year as a decimal number (range 001 to 366) + return _(dojo.date.getDayOfYear(dateObject), 3); + + case "k": // Hour as a decimal number using a 24-hour clock (range + // 0 to 23 (space-padded)) + if (padChar == null) { padChar = " "; } + return _(dateObject.getHours()); + + case "l": // Hour as a decimal number using a 12-hour clock (range + // 1 to 12 (space-padded)) + if (padChar == null) { padChar = " "; } + return _(dateObject.getHours() % 12 || 12); + + case "m": // month as a decimal number (range 01 to 12) + return _(dateObject.getMonth() + 1); + + case "M": // minute as a decimal number + return _(dateObject.getMinutes()); + + case "n": + return "\n"; + + case "p": // either `am' or `pm' according to the given time value, + // or the corresponding strings for the current locale + return info[dateObject.getHours() < 12 ? "am" : "pm"]; + + case "r": // time in a.m. and p.m. notation + return $("I") + ":" + $("M") + ":" + $("S") + " " + $("p"); + + case "R": // time in 24 hour notation + return $("H") + ":" + $("M"); + + case "S": // second as a decimal number + return _(dateObject.getSeconds()); + + case "t": + return "\t"; + + case "T": // current time, equal to %H:%M:%S + return $("H") + ":" + $("M") + ":" + $("S"); + + case "u": // weekday as a decimal number [1,7], with 1 representing + // Monday + return String(dateObject.getDay() || 7); + + case "U": // week number of the current year as a decimal number, + // starting with the first Sunday as the first day of the + // first week + return _(dojo.date.getWeekOfYear(dateObject)); + + case "V": // week number of the year (Monday as the first day of the + // week) as a decimal number [01,53]. If the week containing + // 1 January has four or more days in the new year, then it + // is considered week 1. Otherwise, it is the last week of + // the previous year, and the next week is week 1. + return _(dojo.date.getIsoWeekOfYear(dateObject)); + + case "W": // week number of the current year as a decimal number, + // starting with the first Monday as the first day of the + // first week + return _(dojo.date.getWeekOfYear(dateObject, 1)); + + case "w": // day of the week as a decimal, Sunday being 0 + return String(dateObject.getDay()); + + case "x": // preferred date representation for the current locale + // without the time + return dojo.date.format(dateObject, {selector:'dateOnly', locale:locale}); + + case "X": // preferred time representation for the current locale + // without the date + return dojo.date.format(dateObject, {selector:'timeOnly', locale:locale}); + + case "y": // year as a decimal number without a century (range 00 to + // 99) + return _(dateObject.getFullYear()%100); + + case "Y": // year as a decimal number including the century + return String(dateObject.getFullYear()); + + case "z": // time zone or name or abbreviation + var timezoneOffset = dateObject.getTimezoneOffset(); + return (timezoneOffset > 0 ? "-" : "+") + + _(Math.floor(Math.abs(timezoneOffset)/60)) + ":" + + _(Math.abs(timezoneOffset)%60); + + case "Z": // time zone or name or abbreviation + return dojo.date.getTimezoneName(dateObject); + + case "%": + return "%"; + } + } + + // parse the formatting string and construct the resulting string + var string = ""; + var i = 0; + var index = 0; + var switchCase = null; + while ((index = format.indexOf("%", i)) != -1){ + string += format.substring(i, index++); + + // inspect modifier flag + switch (format.charAt(index++)) { + case "_": // Pad a numeric result string with spaces. + padChar = " "; break; + case "-": // Do not pad a numeric result string. + padChar = ""; break; + case "0": // Pad a numeric result string with zeros. + padChar = "0"; break; + case "^": // Convert characters in result string to uppercase. + switchCase = "upper"; break; + case "*": // Convert characters in result string to lowercase + switchCase = "lower"; break; + case "#": // Swap the case of the result string. + switchCase = "swap"; break; + default: // no modifier flag so decrement the index + padChar = null; index--; break; + } + + // toggle case if a flag is set + var property = $(format.charAt(index++)); + switch (switchCase){ + case "upper": + property = property.toUpperCase(); + break; + case "lower": + property = property.toLowerCase(); + break; + case "swap": // Upper to lower, and versey-vicea + var compareString = property.toLowerCase(); + var swapString = ''; + var j = 0; + var ch = ''; + while (j < property.length){ + ch = property.charAt(j); + swapString += (ch == compareString.charAt(j)) ? + ch.toUpperCase() : ch.toLowerCase(); + j++; + } + property = swapString; + break; + default: + break; + } + switchCase = null; + + string += property; + i = index; + } + string += format.substring(i); + + return string; // String +}; + +(function(){ +var _customFormats = []; +dojo.date.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){ +// +// summary: +// Add a reference to a bundle containing localized custom formats to be +// used by date/time formatting and parsing routines. +// +// description: +// The user may add custom localized formats where the bundle has properties following the +// same naming convention used by dojo for the CLDR data: dateFormat-xxxx / timeFormat-xxxx +// The pattern string should match the format used by the CLDR. +// See dojo.date.format for details. +// The resources must be loaded by dojo.requireLocalization() prior to use + + _customFormats.push({pkg:packageName,name:bundleName}); +}; + +dojo.date._getGregorianBundle = function(/*String*/locale){ + var gregorian = {}; + dojo.lang.forEach(_customFormats, function(desc){ + var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale); + gregorian = dojo.lang.mixin(gregorian, bundle); + }, this); + return gregorian; /*Object*/ +}; +})(); + +dojo.date.addCustomFormats("dojo.i18n.calendar","gregorian"); +dojo.date.addCustomFormats("dojo.i18n.calendar","gregorianExtras"); + +dojo.date.getNames = function(/*String*/item, /*String*/type, /*String?*/use, /*String?*/locale){ +// +// summary: +// Used to get localized strings for day or month names. +// +// item: 'months' || 'days' +// type: 'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English) +// use: 'standAlone' || 'format' (default) +// locale: override locale used to find the names + + var label; + var lookup = dojo.date._getGregorianBundle(locale); + var props = [item, use, type]; + if(use == 'standAlone'){ + label = lookup[props.join('-')]; + } + props[1] = 'format'; + + // return by copy so changes won't be made accidentally to the in-memory model + return (label || lookup[props.join('-')]).concat(); /*Array*/ +}; + +// Convenience methods + +dojo.date.getDayName = function(/*Date*/dateObject, /*String?*/locale){ +// summary: gets the full localized day of the week corresponding to the date object + return dojo.date.getNames('days', 'wide', 'format', locale)[dateObject.getDay()]; /*String*/ +}; + +dojo.date.getDayShortName = function(/*Date*/dateObject, /*String?*/locale){ +// summary: gets the abbreviated localized day of the week corresponding to the date object + return dojo.date.getNames('days', 'abbr', 'format', locale)[dateObject.getDay()]; /*String*/ +}; + +dojo.date.getMonthName = function(/*Date*/dateObject, /*String?*/locale){ +// summary: gets the full localized month name corresponding to the date object + return dojo.date.getNames('months', 'wide', 'format', locale)[dateObject.getMonth()]; /*String*/ +}; + +dojo.date.getMonthShortName = function(/*Date*/dateObject, /*String?*/locale){ +// summary: gets the abbreviated localized month name corresponding to the date object + return dojo.date.getNames('months', 'abbr', 'format', locale)[dateObject.getMonth()]; /*String*/ +}; + +//FIXME: not localized +dojo.date.toRelativeString = function(/*Date*/dateObject){ +// summary: +// Returns an description in English of the date relative to the current date. Note: this is not localized yet. English only. +// +// description: Example returns: +// - "1 minute ago" +// - "4 minutes ago" +// - "Yesterday" +// - "2 days ago" + + var now = new Date(); + var diff = (now - dateObject) / 1000; + var end = " ago"; + var future = false; + if(diff < 0){ + future = true; + end = " from now"; + diff = -diff; + } + + if(diff < 60){ + diff = Math.round(diff); + return diff + " second" + (diff == 1 ? "" : "s") + end; + } + if(diff < 60*60){ + diff = Math.round(diff/60); + return diff + " minute" + (diff == 1 ? "" : "s") + end; + } + if(diff < 60*60*24){ + diff = Math.round(diff/3600); + return diff + " hour" + (diff == 1 ? "" : "s") + end; + } + if(diff < 60*60*24*7){ + diff = Math.round(diff/(3600*24)); + if(diff == 1){ + return future ? "Tomorrow" : "Yesterday"; + }else{ + return diff + " days" + end; + } + } + return dojo.date.format(dateObject); // String +}; + +//FIXME: SQL methods can probably be moved to a different module without i18n deps + +dojo.date.toSql = function(/*Date*/dateObject, /*Boolean?*/noTime){ +// summary: +// Convert a Date to a SQL string +// noTime: whether to ignore the time portion of the Date. Defaults to false. + + return dojo.date.strftime(dateObject, "%F" + !noTime ? " %T" : ""); // String +}; + +dojo.date.fromSql = function(/*String*/sqlDate){ +// summary: +// Convert a SQL date string to a JavaScript Date object + + var parts = sqlDate.split(/[\- :]/g); + while(parts.length < 6){ + parts.push(0); + } + return new Date(parts[0], (parseInt(parts[1],10)-1), parts[2], parts[3], parts[4], parts[5]); // Date +}; + +dojo.provide("dojo.widget.TimePicker"); + + + + + + + + + + + + +dojo.widget.defineWidget( + "dojo.widget.TimePicker", + dojo.widget.HtmlWidget, + function(){ + + /* + summary: + Base class for a stand-alone TimePicker widget + which makes it easy to select a time. + description: + A stand-alone TimePicker widget that makes it easy to select a time. + It is designed to be used on its own, or inside of other widgets + (see dojo.widget.DropdownTimePicker) or other similar combination widgets. + + Times attributes passed in the `RFC 3339` format: + http://www.faqs.org/rfcs/rfc3339.html (2005-06-30T08:05:00-07:00) + so that they are serializable and locale-independent. + + usage: + var timePicker = dojo.widget.createWidget("TimePicker", {}, + dojo.byId("timePickerNode")); + +
+ */ + + // time: Date + // selected time + this.time = ""; + + // useDefaultTime: Boolean + // set following flag to true if a default time should be set + this.useDefaultTime = false; + + // useDefaultMinutes: Boolean + // set the following to true to set default minutes to current time, false to // use zero + this.useDefaultMinutes = false; + + // storedTime: String + // rfc 3339 time + this.storedTime = ""; + + // currentTime: Object + // time currently selected in the UI, stored in hours, minutes, seconds in the format that will be actually displayed + this.currentTime = {}; + + this.classNames = { + // summary: + // stores a list of class names that may be overriden + selectedTime: "selectedItem" + }; + + this.any = "any"; //FIXME: never used? + + // dom node indecies for selected hour, minute, amPm, and "any time option" + this.selectedTime = { + hour: "", + minute: "", + amPm: "", + anyTime: false + }; + + // minutes are ordered as follows: ["12", "6", "1", "7", "2", "8", "3", "9", "4", "10", "5", "11"] + this.hourIndexMap = ["", 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11, 0]; + + // minutes are ordered as follows: ["00", "30", "05", "35", "10", "40", "15", "45", "20", "50", "25", "55"] + this.minuteIndexMap = [0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11]; + }, +{ + isContainer: false, + templateString:"
\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
 ${this.calendar.field-hour}${this.calendar.field-minute} 
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
126
17
28
39
410
511
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
0030
0535
1040
1545
2050
2555
\r\n\t\t\t\t
 \r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
${this.calendar.am}${this.calendar.pm}
\r\n\t\t\t\t
\r\n\t\t\t\t\t
${this.widgetStrings.any}
\r\n\t\t\t\t
 
\r\n
\r\n", + templateCssString:"/*Time Picker */\r\n.timePickerContainer {\r\n\twidth:122px;\r\n\tfont-family:Tahoma, Myriad, Helvetica, Arial, Verdana, sans-serif;\r\n\tfont-size:16px;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead {\r\n\tcolor:#293a4b;\r\n\tfont-size:0.9em;\r\n\tfont-weight:700;\r\n}\r\n\r\n.timeContainer thead td {\r\n\tpadding:0.25em;\r\n\tfont-size:0.80em;\r\n\tborder-bottom:1px solid #6782A8;\r\n}\r\n\r\n.timeCorner {\r\n\twidth:10px;\r\n}\r\n\r\n.cornerTopLeft {\r\n\tbackground: url(\"images/dpCurveTL.png\") top left no-repeat;\r\n}\r\n\r\n.cornerTopRight {\r\n\tbackground: url(\"images/dpCurveTR.png\") top right no-repeat;\r\n}\r\n\r\n.timeLabelContainer {\r\n\tbackground: url(\"images/dpMonthBg.png\") top left repeat-x;\r\n}\r\n\r\n.hours, .minutes, .timeBorder {\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n\r\n}\r\n\r\n.hours td, .minutes td {\r\n\tpadding:0.2em;\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n.minutes {\r\n\tborder-left:1px solid #f5d1db;\r\n}\r\n\r\n.hours {\r\n\tborder-right:1px solid #6782A8;\r\n}\r\n\r\n.hourSelector {\r\n\tborder-right:1px solid #6782A8;\r\n\tpadding:5px;\r\n\tpadding-right:10px;\r\n}\r\n\r\n.minutesSelector {\r\n\tpadding:5px;\r\n\tborder-left:1px solid #f5c7d4;\r\n\ttext-align:center;\r\n}\r\n\r\n.minutesHeading {\r\n\tpadding-left:9px !important;\r\n}\r\n\r\n.timeOptions {\r\n\tbackground-color:#F9C9D7;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft, .timeContainer .cornerBottomRight, .timeContainer .timeOptions {\r\n\tborder-top:1px solid #6782A8;\r\n}\r\n\r\n.timeContainer .cornerBottomLeft {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeContainer .cornerBottomRight {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.timeOptions {\r\n\tcolor:#fff;\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#fff;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.timeOptions .selectedItem {\r\n\tcolor:#fff !important;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.anyTimeContainer {\r\n\ttext-align:center;\r\n\tfont-weight:bold;\r\n\tfont-size:0.7em;\r\n\tpadding:0.1em;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff !important;\r\n}\r\n\r\n.amPmContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.amPmContainer td {\r\n\ttext-align:center;\r\n\tfont-size:0.7em;\r\n\tfont-weight:bold;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n\tcolor:#fff;\r\n}\r\n\r\n\r\n\r\n/*.timePickerContainer {\r\n\tmargin:1.75em 0 0.5em 0;\r\n\twidth:10em;\r\n\tfloat:left;\r\n}\r\n\r\n.timeContainer {\r\n\tborder-collapse:collapse;\r\n\tborder-spacing:0;\r\n}\r\n\r\n.timeContainer thead td{\r\n\tborder-bottom:1px solid #e6e6e6;\r\n\tpadding:0 0.4em 0.2em 0.4em;\r\n}\r\n\r\n.timeContainer td {\r\n\tfont-size:0.9em;\r\n\tpadding:0 0.25em 0 0.25em;\r\n\ttext-align:left;\r\n\tcursor:pointer;cursor:hand;\r\n}\r\n\r\n.timeContainer td.minutesHeading {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\t\r\n}\r\n\r\n.timeContainer .minutes {\r\n\tborder-left:1px solid #e6e6e6;\r\n\tborder-right:1px solid #e6e6e6;\r\n}\r\n\r\n.selectedItem {\r\n\tbackground-color:#3a3a3a;\r\n\tcolor:#ffffff;\r\n}*/\r\n",templateCssPath: dojo.uri.moduleUri("dojo.widget", "templates/TimePicker.css"), + + postMixInProperties: function(localProperties, frag) { + // summary: see dojo.widget.DomWidget + dojo.widget.TimePicker.superclass.postMixInProperties.apply(this, arguments); + this.calendar = dojo.i18n.getLocalization("dojo.i18n.calendar", "gregorian", this.lang); // "am","pm" + this.widgetStrings = dojo.i18n.getLocalization("dojo.widget", "TimePicker", this.lang); // "any" + }, + + fillInTemplate: function(args, frag){ + // summary: see dojo.widget.DomWidget + + // Copy style info from input node to output node + var source = this.getFragNodeRef(frag); + dojo.html.copyStyle(this.domNode, source); + + if(args.value){ + if(args.value instanceof Date){ + this.storedTime = dojo.date.toRfc3339(args.value); + }else{ + this.storedTime = args.value; + } + } + + this.initData(); + this.initUI(); + }, + + initData: function() { + // FIXME: doesn't currently validate the time before trying to set it + // Determine the date/time from stored info, or by default don't + // have a set time + // FIXME: should normalize against whitespace on storedTime... for now + // just a lame hack + if(this.storedTime.indexOf("T")!=-1 && this.storedTime.split("T")[1] && this.storedTime!=" " && this.storedTime.split("T")[1]!="any"){ + this.time = dojo.widget.TimePicker.util.fromRfcDateTime(this.storedTime, this.useDefaultMinutes, this.selectedTime.anyTime); + }else if(this.useDefaultTime){ + this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", this.useDefaultMinutes, this.selectedTime.anyTime); + }else{ + this.selectedTime.anyTime = true; + this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", 0, 1); + } + }, + + initUI: function() { + // set UI to match the currently selected time + if(!this.selectedTime.anyTime && this.time) { + var amPmHour = dojo.widget.TimePicker.util.toAmPmHour(this.time.getHours()); + var hour = amPmHour[0]; + var isAm = amPmHour[1]; + var minute = this.time.getMinutes(); + var minuteIndex = parseInt(minute/5); + this.onSetSelectedHour(this.hourIndexMap[hour]); + this.onSetSelectedMinute(this.minuteIndexMap[minuteIndex]); + this.onSetSelectedAmPm(isAm); + } else { + this.onSetSelectedAnyTime(); + } + }, + + setTime: function(date) { + //summary: set the current date and update the UI + if(date) { + this.selectedTime.anyTime = false; + this.setDateTime(dojo.date.toRfc3339(date)); + } else { + this.selectedTime.anyTime = true; + } + this.initData(); + this.initUI(); + }, + + setDateTime: function(rfcDate) { + this.storedTime = rfcDate; + }, + + onClearSelectedHour: function(evt) { + this.clearSelectedHour(); + }, + + onClearSelectedMinute: function(evt) { + this.clearSelectedMinute(); + }, + + onClearSelectedAmPm: function(evt) { + this.clearSelectedAmPm(); + }, + + onClearSelectedAnyTime: function(evt) { + this.clearSelectedAnyTime(); + if(this.selectedTime.anyTime) { + this.selectedTime.anyTime = false; + this.time = dojo.widget.TimePicker.util.fromRfcDateTime("", this.useDefaultMinutes); + this.initUI(); + } + }, + + clearSelectedHour: function() { + var hourNodes = this.hourContainerNode.getElementsByTagName("td"); + for (var i=0; i12) { + amPmHour = amPmHour - 12; + isAm = false; + } else if (amPmHour == 12) { + isAm = false; + } + return [amPmHour, isAm]; + } + + this.fromAmPmHour = function(amPmHour, isAm) { + //summary: converts a 12-hour-based hour value and an AM/PM flag to a 24-hour-based hour value + var hour = parseInt(amPmHour, 10); + if(isAm && hour == 12) { + hour = 0; + } else if (!isAm && hour<12) { + hour = hour + 12; + } + return hour; + } +} + +dojo.provide("dojo.widget.DropdownTimePicker"); + + + + + + + + + + + +dojo.widget.defineWidget( + "dojo.widget.DropdownTimePicker", + dojo.widget.DropdownContainer, + { + /* + summary: + A form input for entering times with a pop-up dojo.widget.TimePicker to aid in selection + + description: + This is TimePicker in a DropdownContainer, it supports all features of TimeePicker. + + It is possible to customize the user-visible formatting with either the formatLength or + displayFormat attributes. The value sent to the server is typically a locale-independent + value in a hidden field as defined by the name attribute. RFC3339 representation is used + by default, but other options are available with saveFormat. + + usage: + var dtp = dojo.widget.createWidget("DropdownTimePicker", {}, + dojo.byId("DropdownTimePickerNode")); + + + */ + + // iconURL: URL + // path of icon for button to display time picker widget + iconURL: dojo.uri.moduleUri("dojo.widget", "templates/images/timeIcon.gif"), + + // formatLength: String + // Type of formatting used for visual display, appropriate to locale (choice of long, short, medium or full) + // See dojo.date.format for details. + formatLength: "short", + + // displayFormat: String + // A pattern used for the visual display of the formatted date. + // Setting this overrides the default locale-specific settings as well as the formatLength + // attribute. See dojo.date.format for a reference which defines the formatting patterns. + displayFormat: "", + + timeFormat: "", // deprecated, will be removed for 0.5 + +//FIXME: need saveFormat attribute support + // saveFormat: String + // Formatting scheme used when submitting the form element. This formatting is used in a hidden + // field (name) intended for server use, and is therefore typically locale-independent. + // By default, uses rfc3339 style date formatting (rfc) + // Use a pattern string like displayFormat or one of the following: + // rfc|iso|posix|unix + saveFormat: "", + + // value: String|Date + // form value property in rfc3339 format. ex: 12:00 + value: "", + + // name: String + // name of the form element, used to create a hidden field by this name for form element submission. + name: "", + + postMixInProperties: function() { + // summary: see dojo.widget.DomWidget + dojo.widget.DropdownTimePicker.superclass.postMixInProperties.apply(this, arguments); + var messages = dojo.i18n.getLocalization("dojo.widget", "DropdownTimePicker", this.lang); + this.iconAlt = messages.selectTime; + + //FIXME: should this be if/else/else? + if(typeof(this.value)=='string'&&this.value.toLowerCase()=='today'){ + this.value = new Date(); + } + if(this.value && isNaN(this.value)){ + var orig = this.value; + this.value = dojo.date.fromRfc3339(this.value); + if(!this.value){ + var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" }); + var c = orig.split(":"); + for(var i = 0; i < c.length; ++i){ + if(c[i].length == 1) c[i] = "0" + c[i]; + } + orig = c.join(":"); + this.value = dojo.date.fromRfc3339(d + "T" + orig); + dojo.deprecated("dojo.widget.DropdownTimePicker", "time attributes must be passed in Rfc3339 format", "0.5"); + } + } + if(this.value && !isNaN(this.value)){ + this.value = new Date(this.value); + } + }, + + fillInTemplate: function(){ + // summary: see dojo.widget.DomWidget + + dojo.widget.DropdownTimePicker.superclass.fillInTemplate.apply(this, arguments); + + var value = ""; + if(this.value instanceof Date) { + value = this.value; + } else if(this.value) { + var orig = this.value; + var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" }); + var c = orig.split(":"); + for(var i = 0; i < c.length; ++i){ + if(c[i].length == 1) c[i] = "0" + c[i]; + } + orig = c.join(":"); + value = dojo.date.fromRfc3339(d + "T" + orig); + } + + var tpArgs = { widgetContainerId: this.widgetId, lang: this.lang, value: value }; + this.timePicker = dojo.widget.createWidget("TimePicker", tpArgs, this.containerNode, "child"); + + dojo.event.connect(this.timePicker, "onValueChanged", this, "_updateText"); + + if(this.value){ + this._updateText(); + } + this.containerNode.style.zIndex = this.zIndex; + this.containerNode.explodeClassName = "timeContainer"; + this.valueNode.name = this.name; + }, + + getValue: function(){ + // summary: return current time in time-only portion of RFC 3339 format + return this.valueNode.value; /*String*/ + }, + + getTime: function(){ + // summary: return current time as a Date object + return this.timePicker.storedTime; /*Date*/ + }, + + setValue: function(/*Date|String*/rfcDate){ + //summary: set the current time from RFC 3339 formatted string or a date object, synonymous with setTime + this.setTime(rfcDate); + }, + + setTime: function(/*Date|String*/dateObj){ + // summary: set the current time and update the UI + var value = ""; + if(dateObj instanceof Date) { + value = dateObj; + } else if(this.value) { + var orig = this.value; + var d = dojo.date.format(new Date(), { selector: "dateOnly", datePattern: "yyyy-MM-dd" }); + var c = orig.split(":"); + for(var i = 0; i < c.length; ++i){ + if(c[i].length == 1) c[i] = "0" + c[i]; + } + orig = c.join(":"); + value = dojo.date.fromRfc3339(d + "T" + orig); + } + + this.timePicker.setTime(value); + this._syncValueNode(); + }, + + _updateText: function(){ + // summary: updates the field according to the current value (ie, displays the formatted date) + if(this.timePicker.selectedTime.anyTime){ + this.inputNode.value = ""; + }else if(this.timeFormat){ + dojo.deprecated("dojo.widget.DropdownTimePicker", + "Must use displayFormat attribute instead of timeFormat. See dojo.date.format for specification.", "0.5"); + this.inputNode.value = dojo.date.strftime(this.timePicker.time, this.timeFormat, this.lang); + }else{ + this.inputNode.value = dojo.date.format(this.timePicker.time, + {formatLength:this.formatLength, timePattern:this.displayFormat, selector:'timeOnly', locale:this.lang}); + } + this._syncValueNode(); + this.onValueChanged(this.getTime()); + this.hideContainer(); + }, + + onValueChanged: function(/*Date*/dateObj){ + // summary: triggered when this.value is changed + }, + + onInputChange: function(){ + // summary: callback when user manually types a time into the field + if(this.dateFormat){ + dojo.deprecated("dojo.widget.DropdownTimePicker", + "Cannot parse user input. Must use displayFormat attribute instead of dateFormat. See dojo.date.format for specification.", "0.5"); + }else{ + var input = dojo.string.trim(this.inputNode.value); + if(input){ + var inputTime = dojo.date.parse(input, + {formatLength:this.formatLength, timePattern:this.displayFormat, selector:'timeOnly', locale:this.lang}); + if(inputTime){ + this.setTime(inputTime); + } + } else { + this.valueNode.value = input; + } + } + // If the time entered didn't parse, reset to the old time. KISS, for now. + //TODO: usability? should we provide more feedback somehow? an error notice? + // seems redundant to do this if the parse failed, but at least until we have validation, + // this will fix up the display of entries like 01/32/2006 + if(input){ this._updateText(); } + }, + + _syncValueNode: function(){ + var time = this.timePicker.time; + var value; + switch(this.saveFormat.toLowerCase()){ + case "rfc": case "iso": case "": + value = dojo.date.toRfc3339(time, 'timeOnly'); + break; + case "posix": case "unix": + value = Number(time); + break; + default: + value = dojo.date.format(time, {datePattern:this.saveFormat, selector:'timeOnly', locale:this.lang}); + } + this.valueNode.value = value; + }, + + destroy: function(/*Boolean*/finalize){ + this.timePicker.destroy(finalize); + dojo.widget.DropdownTimePicker.superclass.destroy.apply(this, arguments); + } + } +); + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +//If we use "TimePicker" for the name, Dojo get's confused and breaks +//TODO remove this file on next Dojo release + +dojo.provide("struts.widget.StrutsTimePicker"); + + + +dojo.widget.defineWidget( + "struts.widget.StrutsTimePicker", + dojo.widget.DropdownTimePicker, { + widgetType : "StrutsTimePicker", + + inputName: "", + name: "", + + valueNotifyTopics : "", + valueNotifyTopicsArray : null, + + tabIndex : "", + + postCreate: function() { + struts.widget.StrutsTimePicker.superclass.postCreate.apply(this, arguments); + + //set cssClass + if(this.extraArgs["class"]) { + dojo.html.setClass(this.inputNode, this.extraArgs["class"]); + } + + //set cssStyle + if(this.extraArgs.style) { + dojo.html.setStyleText(this.inputNode, this.extraArgs.style); + } + + //value topics + if(!dojo.string.isBlank(this.valueNotifyTopics)) { + this.valueNotifyTopicsArray = this.valueNotifyTopics.split(","); + } + + //tabindex + if(!dojo.string.isBlank(this.tabIndex)) { + this.inputNode.tabIndex = this.tabIndex; + } + }, + + _syncValueNode:function () { + var time = this.timePicker.time; + var value; + switch (this.saveFormat.toLowerCase()) { + case "rfc": + case "iso": + case "": + //originally, Dojo only saves the time part + value = dojo.date.toRfc3339(time); + break; + case "posix": + case "unix": + value = Number(time); + break; + default: + value = dojo.date.format(time, {datePattern:this.saveFormat, selector:"timeOnly", locale:this.lang}); + } + this.valueNode.value = value; + }, + + _updateText : function() { + struts.widget.StrutsTimePicker.superclass._updateText.apply(this, arguments); + if(this.valueNotifyTopicsArray != null) { + for(var i = 0; i < this.valueNotifyTopicsArray.length; i++) { + var topic = this.valueNotifyTopicsArray[i]; + if(!dojo.string.isBlank(topic)) { + try { + dojo.event.topic.publish(topic, this.inputNode.value, this.getValue(), this); + } catch(ex) { + dojo.debug(ex); + } + } + } + } + } +}); + +dojo.provide("dojo.widget.DatePicker"); + + + + + + + + + + +dojo.widget.defineWidget( + "dojo.widget.DatePicker", + dojo.widget.HtmlWidget, + { + + /* + summary: + Base class for a stand-alone DatePicker widget + which makes it easy to select a date, or switch by month and/or year. + description: + A stand-alone DatePicker widget that makes it + easy to select a date, or increment by week, month, and/or year. + It is designed to be used on its own, or inside of other widgets to + (see dojo.widget.DropdownDatePicker) or other similar combination widgets. + + Dates attributes passed in the `RFC 3339` format: + http://www.faqs.org/rfcs/rfc3339.html (2005-06-30T08:05:00-07:00) + so that they are serializable and locale-independent. + + usage: + var datePicker = dojo.widget.createWidget("DatePicker", {}, + dojo.byId("datePickerNode")); + +
+ */ + + //start attributes + + // value: String|Date + // form value property if =='today' will be today's date + value: "", + + // name: String + // name of the form element + name: "", + + // displayWeeks: Integer + // total weeks to display default + displayWeeks: 6, + + // adjustWeeks: Boolean + // if true, weekly size of calendar changes to acomodate the month if false, 42 day format is used + adjustWeeks: false, + + // startDate: String|Date + // first available date in the calendar set + startDate: "1492-10-12", + + // endDate: String|Date + // last available date in the calendar set + endDate: "2941-10-12", + + // weekStartsOn: Integer + // adjusts the first day of the week 0==Sunday..6==Saturday + weekStartsOn: "", + + // staticDisplay: Boolean + // disable all incremental controls, must pick a date in the current display + staticDisplay: false, + + // dayWidth: String + // how to render the names of the days in the header. see dojo.date.getDayNames + dayWidth: 'narrow', + + classNames: { + // summary: + // stores a list of class names that may be overriden + // TODO: this is not good; can't be adjusted via markup, etc. since it's an array + previous: "previousMonth", + disabledPrevious: "previousMonthDisabled", + current: "currentMonth", + disabledCurrent: "currentMonthDisabled", + next: "nextMonth", + disabledNext: "nextMonthDisabled", + currentDate: "currentDate", + selectedDate: "selectedDate" + }, + templateString:"
\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\"↑\"\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t

\r\n\t\t\t\t\t\t\t
\r\n\t\t\t\t
\r\n
\r\n", + templateCssString:".datePickerContainer {\r\n\twidth:164px; /* needed for proper user styling */\r\n}\r\n\r\n.calendarContainer {\r\n/*\tborder:1px solid #566f8f;*/\r\n}\r\n\r\n.calendarBodyContainer {\r\n\twidth:100%; /* needed for the explode effect (explain?) */\r\n\tbackground: #7591bc url(\"images/dpBg.gif\") top left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer thead tr td {\r\n\tcolor:#293a4b;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.25em;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.calendarBodyContainer tbody tr td {\r\n\tcolor:#fff;\r\n\tfont:bold 0.7em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n\tpadding:0.4em;\r\n\tbackground: url(\"images/dpVertLine.gif\") top right repeat-y;\r\n\tcursor:pointer;\r\n\tcursor:hand;\r\n}\r\n\r\n\r\n.monthWrapper {\r\n\tpadding-bottom:2px;\r\n\tbackground: url(\"images/dpHorizLine.gif\") bottom left repeat-x;\r\n}\r\n\r\n.monthContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.monthLabelContainer {\r\n\ttext-align:center;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\tbackground: url(\"images/dpMonthBg.png\") repeat-x top left !important;\r\n\tcolor:#293a4b;\r\n\tpadding:0.25em;\r\n}\r\n\r\n.monthCurve {\r\n\twidth:12px;\r\n}\r\n\r\n.monthCurveTL {\r\n\tbackground: url(\"images/dpCurveTL.png\") no-repeat top left !important;\r\n}\r\n\r\n.monthCurveTR {\r\n\t\tbackground: url(\"images/dpCurveTR.png\") no-repeat top right !important;\r\n}\r\n\r\n\r\n.yearWrapper {\r\n\tbackground: url(\"images/dpHorizLineFoot.gif\") top left repeat-x;\r\n\tpadding-top:2px;\r\n}\r\n\r\n.yearContainer {\r\n\twidth:100%;\r\n}\r\n\r\n.yearContainer td {\r\n\tbackground:url(\"images/dpYearBg.png\") top left repeat-x;\r\n}\r\n\r\n.yearContainer .yearLabel {\r\n\tmargin:0;\r\n\tpadding:0.45em 0 0.45em 0;\r\n\tcolor:#fff;\r\n\tfont:bold 0.75em Helvetica, Arial, Verdana, sans-serif;\r\n\ttext-align:center;\r\n}\r\n\r\n.curveBL {\r\n\tbackground: url(\"images/dpCurveBL.png\") bottom left no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n.curveBR {\r\n\tbackground: url(\"images/dpCurveBR.png\") bottom right no-repeat !important;\r\n\twidth:9px !important;\r\n\tpadding:0;\r\n\tmargin:0;\r\n}\r\n\r\n\r\n.previousMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n\r\n.previousMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important\r\n}\r\n.currentMonth {\r\n}\r\n\r\n.currentMonthDisabled {\r\n\tbackground-color:#bbbbbc !important;\r\n\tcursor:default !important\r\n}\r\n.nextMonth {\r\n\tbackground-color:#6782a8 !important;\r\n}\r\n.nextMonthDisabled {\r\n\tbackground-color:#a4a5a6 !important;\r\n\tcursor:default !important;\r\n}\r\n\r\n.currentDate {\r\n\ttext-decoration:underline;\r\n\tfont-style:italic;\r\n}\r\n\r\n.selectedDate {\r\n\tbackground-color:#fff !important;\r\n\tcolor:#6782a8 !important;\r\n}\r\n\r\n.yearLabel .selectedYear {\r\n\tpadding:0.2em;\r\n\tbackground-color:#9ec3fb !important;\r\n}\r\n\r\n.nextYear, .previousYear {\r\n\tcursor:pointer;cursor:hand;\r\n\tpadding:0;\r\n}\r\n\r\n.nextYear {\r\n\tmargin:0 0 0 0.55em;\r\n}\r\n\r\n.previousYear {\r\n\tmargin:0 0.55em 0 0;\r\n}\r\n\r\n.incrementControl {\r\n\tcursor:pointer;cursor:hand;\r\n\twidth:1em;\r\n}\r\n\r\n.increase {\r\n\tfloat:right;\r\n}\r\n\r\n.decrease {\r\n\tfloat:left;\r\n}\r\n\r\n.lastColumn {\r\n\tbackground-image:none !important;\r\n}\r\n\r\n\r\n",templateCssPath: dojo.uri.moduleUri("dojo.widget", "templates/DatePicker.css"), + + postMixInProperties: function(){ + // summary: see dojo.widget.DomWidget + + dojo.widget.DatePicker.superclass.postMixInProperties.apply(this, arguments); + if(!this.weekStartsOn){ + this.weekStartsOn=dojo.date.getFirstDayOfWeek(this.lang); + } + this.today = new Date(); + this.today.setHours(0,0,0,0); + if(typeof(this.value)=='string'&&this.value.toLowerCase()=='today'){ + this.value = new Date(); + }else if(this.value && (typeof this.value=="string") && (this.value.split("-").length > 2)) { + this.value = dojo.date.fromRfc3339(this.value); + this.value.setHours(0,0,0,0); + } + }, + + fillInTemplate: function(args, frag) { + // summary: see dojo.widget.DomWidget + + dojo.widget.DatePicker.superclass.fillInTemplate.apply(this, arguments); + + // Copy style info from input node to output node + var source = this.getFragNodeRef(frag); + dojo.html.copyStyle(this.domNode, source); + + this.weekTemplate = dojo.dom.removeNode(this.calendarWeekTemplate); + this._preInitUI(this.value ? this.value : this.today, false, true); //init UI with date selected ONLY if user supplies one + + // Insert localized day names in the template + var dayLabels = dojo.lang.unnest(dojo.date.getNames('days', this.dayWidth, 'standAlone', this.lang)); //if we dont use unnest, we risk modifying the dayLabels array inside of dojo.date and screwing up other calendars on the page + if(this.weekStartsOn>0){ + //adjust dayLabels for different first day of week. ie: Monday or Thursday instead of Sunday + for(var i=0;ithis.endDate){ + dateObj = new Date((dateObj days){ + this._preInitUI(this.startDate,true,false); + nextDate = new Date(this.firstDay); + } + this.curMonth = new Date(nextDate); + this.curMonth.setDate(nextDate.getDate()+6); + this.curMonth.setDate(1); + var curClass = (nextDate.getMonth() == this.curMonth.getMonth())?'current':'previous'; + } + if(initUI){ + this._initUI(days); + } + }, + _initUI: function(days) { + dojo.dom.removeChildren(this.calendarDatesContainerNode); + for(var i=0;ithis.endDate){ + incWeek = incMonth = incYear = false; + } + if(decMonth && add(d,DAY,-1)this.endDate){ + incMonth = incYear = false; + } + if(decYear && add(d2,YEAR,-1)this.endDate){ + incYear = false; + } + } + + function enableControl(node, enabled){ + dojo.html.setVisibility(node, enabled ? '' : 'hidden'); + } + enableControl(this.decreaseWeekNode,decWeek); + enableControl(this.increaseWeekNode,incWeek); + enableControl(this.decreaseMonthNode,decMonth); + enableControl(this.increaseMonthNode,incMonth); + enableControl(this.previousYearLabelNode,decYear); + enableControl(this.nextYearLabelNode,incYear); + }, + + _incrementWeek: function(evt) { + var d = new Date(this.firstDay); + switch(evt.target) { + case this.increaseWeekNode.getElementsByTagName("img").item(0): + case this.increaseWeekNode: + var tmpDate = dojo.date.add(d, dojo.date.dateParts.WEEK, 1); + if(tmpDate < this.endDate){ + d = dojo.date.add(d, dojo.date.dateParts.WEEK, 1); + } + break; + case this.decreaseWeekNode.getElementsByTagName("img").item(0): + case this.decreaseWeekNode: + if(d >= this.startDate){ + d = dojo.date.add(d, dojo.date.dateParts.WEEK, -1); + } + break; + } + this._preInitUI(d,true,true); + }, + + _incrementMonth: function(evt) { + var d = new Date(this.curMonth); + var tmpDate = new Date(this.firstDay); + switch(evt.currentTarget) { + case this.increaseMonthNode.getElementsByTagName("img").item(0): + case this.increaseMonthNode: + tmpDate = dojo.date.add(tmpDate, dojo.date.dateParts.DAY, this.displayWeeks*7); + if(tmpDate < this.endDate){ + d = dojo.date.add(d, dojo.date.dateParts.MONTH, 1); + }else{ + var revertToEndDate = true; + } + break; + case this.decreaseMonthNode.getElementsByTagName("img").item(0): + case this.decreaseMonthNode: + if(tmpDate > this.startDate){ + d = dojo.date.add(d, dojo.date.dateParts.MONTH, -1); + }else{ + var revertToStartDate = true; + } + break; + } + if(revertToStartDate){ + d = new Date(this.startDate); + }else if(revertToEndDate){ + d = new Date(this.endDate); + } + this._preInitUI(d,false,true); + }, + + _incrementYear: function(evt) { + var year = this.curMonth.getFullYear(); + var tmpDate = new Date(this.firstDay); + switch(evt.target) { + case this.nextYearLabelNode: + tmpDate = dojo.date.add(tmpDate, dojo.date.dateParts.YEAR, 1); + if(tmpDatethis.startDate){ + year--; + }else{ + var revertToStartDate = true; + } + break; + } + var d; + if(revertToStartDate){ + d = new Date(this.startDate); + }else if(revertToEndDate){ + d = new Date(this.endDate); + }else{ + d = new Date(year, this.curMonth.getMonth(), 1); + } + this._preInitUI(d,false,true); + }, + + onIncrementWeek: function(/*Event*/evt) { + // summary: handler for increment week event + evt.stopPropagation(); + if(!this.staticDisplay){ + this._incrementWeek(evt); + } + }, + + onIncrementMonth: function(/*Event*/evt) { + // summary: handler for increment month event + evt.stopPropagation(); + if(!this.staticDisplay){ + this._incrementMonth(evt); + } + }, + + onIncrementYear: function(/*Event*/evt) { + // summary: handler for increment year event + evt.stopPropagation(); + if(!this.staticDisplay){ + this._incrementYear(evt); + } + }, + + _setMonthLabel: function(monthIndex) { + this.monthLabelNode.innerHTML = dojo.date.getNames('months', 'wide', 'standAlone', this.lang)[monthIndex]; + }, + + _setYearLabels: function(year) { + var y = year - 1; + var that = this; + function f(n){ + that[n+"YearLabelNode"].innerHTML = + dojo.date.format(new Date(y++, 0), {formatLength:'yearOnly', locale:that.lang}); + } + f("previous"); + f("current"); + f("next"); + }, + + _getDateClassName: function(date, monthState) { + var currentClassName = this.classNames[monthState]; + //we use Number comparisons because 2 dateObjects never seem to equal each other otherwise + if ((!this.selectedIsUsed && this.value) && (Number(date) == Number(this.value))) { + currentClassName = this.classNames.selectedDate + " " + currentClassName; + this.selectedIsUsed = true; + } + if((!this.currentIsUsed) && (Number(date) == Number(this.today))) { + currentClassName = currentClassName + " " + this.classNames.currentDate; + this.currentIsUsed = true; + } + return currentClassName; + }, + + onClick: function(/*Event*/evt) { + //summary: the click event handler + dojo.event.browser.stopEvent(evt); + }, + + _handleUiClick: function(/*Event*/evt) { + var eventTarget = evt.target; + if(eventTarget.nodeType != dojo.dom.ELEMENT_NODE){eventTarget = eventTarget.parentNode;} + dojo.event.browser.stopEvent(evt); + this.selectedIsUsed = this.todayIsUsed = false; + if(dojo.html.hasClass(eventTarget, this.classNames["disabledPrevious"])||dojo.html.hasClass(eventTarget, this.classNames["disabledCurrent"])||dojo.html.hasClass(eventTarget, this.classNames["disabledNext"])){ + return; //this date is disabled... ignore it + } + this.clickedNode = eventTarget; + this.setDate(new Date(Number(dojo.html.getAttribute(eventTarget,'djDateValue')))); + }, + + onValueChanged: function(/*Date*/date) { + //summary: the set date event handler + }, + + _isDisabledDate: function(dateObj){ + if(dateObjthis.endDate){ + return true; + } + + return this.isDisabledDate(dateObj, this.lang); + }, + + isDisabledDate: function(/*Date*/dateObj, /*String?*/locale){ + // summary: + // May be overridden to disable certain dates in the calendar e.g. isDisabledDate=dojo.date.isWeekend + + return false; // Boolean + }, + + _initFirstDay: function(/*Date*/dateObj, /*Boolean*/adj){ + //adj: false for first day of month, true for first day of week adjusted by startOfWeek + var d = new Date(dateObj); + if(!adj){d.setDate(1);} + d.setDate(d.getDate()-this._getAdjustedDay(d,this.weekStartsOn)); + d.setHours(0,0,0,0); + return d; // Date + }, + + _getAdjustedDay: function(/*Date*/dateObj){ + //summary: used to adjust date.getDay() values to the new values based on the current first day of the week value + var days = [0,1,2,3,4,5,6]; + if(this.weekStartsOn>0){ + for(var i=0;i