Author: pyaschenko
Date: 2007-11-23 12:32:06 -0500 (Fri, 23 Nov 2007)
New Revision: 4234
Added:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/JQuerySpinBtn.xcss
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/spinbtn_updn.gif
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/JQuerySpinBtn.js
Modified:
trunk/framework/impl/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js
trunk/samples/calendar-sample/src/main/webapp/pages/Calendar.jsp
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/calendar.xcss
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/calendar.js
trunk/ui/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx
Log:
RF-1192
Modified:
trunk/framework/impl/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js
===================================================================
---
trunk/framework/impl/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js 2007-11-23
17:14:48 UTC (rev 4233)
+++
trunk/framework/impl/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js 2007-11-23
17:32:06 UTC (rev 4234)
@@ -31,7 +31,9 @@
getInnerHTML : function(context) {
var html = "";
for (var i = 0; i < this.childs.length; i++)
- html += this.childs[i].getContent(context);
+ {
+ html += this.childs[i].getContent(context);
+ }
return html;
},
// Escape XML symbols - < > & ' ...
@@ -56,6 +58,7 @@
E.prototype.getContent = function(context) {
var html = "<"+this.tag;
var inner = this.getInnerHTML(context);
+ if (inner=='') this.isEmpty = true; else this.isEmpty=false;
for(var i in this.attrs) {
if (!this.attrs.hasOwnProperty(i)) {
continue ;
@@ -64,7 +67,7 @@
var attrValue = this.attrs[i];
if (typeof attrValue == "function")
- attrValue = attrValue(context);
+ attrValue = attrValue.call(this, context);
if (attrValue)
html += "
"+(i=='className'?'class':i)+'="'+this.xmlEscape(attrValue)+'"';
Modified: trunk/samples/calendar-sample/src/main/webapp/pages/Calendar.jsp
===================================================================
--- trunk/samples/calendar-sample/src/main/webapp/pages/Calendar.jsp 2007-11-23 17:14:48
UTC (rev 4233)
+++ trunk/samples/calendar-sample/src/main/webapp/pages/Calendar.jsp 2007-11-23 17:32:06
UTC (rev 4234)
@@ -38,7 +38,7 @@
</h:panelGrid>
<br />
<br />
- <calendar:calendar datePattern=""/>
+ <calendar:calendar datePattern=""
showApplyButton="#{calendarBean.showApplyButton}"
popup="#{calendarBean.popup}"/>
<calendar:calendar cellWidth="5" cellHeight="5"/>
<calendar:calendar cellWidth="40" cellHeight="40"/>
<calendar:calendar
Added:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/JQuerySpinBtn.xcss
===================================================================
---
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/JQuerySpinBtn.xcss
(rev 0)
+++
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/JQuerySpinBtn.xcss 2007-11-23
17:32:06 UTC (rev 4234)
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<f:template
xmlns:f='http:/jsf.exadel.com/template'
+
xmlns:u='http:/jsf.exadel.com/template/util'
+
xmlns="http://www.w3.org/1999/xhtml" >
+ <f:verbatim><![CDATA[
+/*
+ Styles to make ordinary <INPUT type="text"/> look like a
spinbutton/spinbox control.
+ Use with JQuerySpinBtn.js to provide the spin functionality by reacting to mouse etc.
+ (Requires a reference to the JQuery library found at
http://jquery.com/src/latest/)
+ (Hats-off to John Resig for creating the excellent JQuery library. It is fab.)
+
+ This control is achieved with no extra html markup whatsoever and uses unobtrusive
javascript.
+
+ Written by George Adamson, Software Unity (george.jquery(a)softwareunity.com) September
2006.
+ Big improvements added by Mark Gibson, (mgibson(a)designlinks.net) September 2006.
+
+ Do contact me with comments and suggestions but please don't ask for support.
+ As much as I'd love to help with specific problems I have plenty to get on with
already!
+
+ Go ahead and use it in your own projects. This code is provided 'as is'.
+ Sure I've tested in heaps of ways. Its good for me, but you use it at your own
risk.
+ SoftwareUnity and I are certainly not responsible if your computer sets fire to the
sofa,
+ hacks into the pentagon, hijacks a plane or gives you any kind of hassle whatsoever.
+
+ If you'd like your spin-button image in a different place then you'll need to
alter both
+ the CSS below and the javascript isMouseOverUpDn() function to accommodate the new
position.
+ You could even have left and right buttons either side of the textbox.
+*/
+
+INPUT.spin-button {
+ padding-right:20px; /* Padding pevents text from covering the up/dn img. Works
better in Firefox but also causes textbox to widen by 20px. Arrows can go wonky in IE when
text is too long. Perhaps it could be fixed with script that monitored the horiz-scroll
position? */
+ background-repeat:no-repeat; /* Warning: Img may disappear in Firefox if you use
'background-attachment:fixed' ! */
+ background-position:100% 0%;
+}
+
+INPUT.spin-button.up { /* Change button img when mouse is over the UP-arrow */
+ cursor:pointer;
+ background-position:100% -18px; /* 18px matches height of 2 visible buttons */
+}
+INPUT.spin-button.down { /* Change button img when mouse is over the DOWN-arrow */
+ cursor:pointer;
+ background-position:100% -36px; /* 36px matches height of 2x2 visible buttons */
+}
+ ]]>
+ </f:verbatim>
+ <u:selector name="INPUT.spin-button">
+ <u:style name="background-image">
+ <f:resource f:key="/org/richfaces/renderkit/html/css/spinbtn_updn.gif"
/>
+ </u:style>
+ </u:selector>
+
+</f:template>
Modified:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/calendar.xcss
===================================================================
---
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/calendar.xcss 2007-11-23
17:14:48 UTC (rev 4233)
+++
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/calendar.xcss 2007-11-23
17:32:06 UTC (rev 4234)
@@ -75,7 +75,7 @@
.rich-calendar-toolfooter{
- padding : 0px 7px 0px 7px;
+ padding : 0px 4px 0px 4px;
height : 22px;
}
Added:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/spinbtn_updn.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/css/spinbtn_updn.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/JQuerySpinBtn.js
===================================================================
---
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/JQuerySpinBtn.js
(rev 0)
+++
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/JQuerySpinBtn.js 2007-11-23
17:32:06 UTC (rev 4234)
@@ -0,0 +1,210 @@
+/* SpinButton control
+ *
+ * Adds bells and whistles to any ordinary textbox to
+ * make it look and feel like a SpinButton Control.
+ *
+ * Originally written by George Adamson, Software Unity (george.jquery(a)softwareunity.com)
August 2006.
+ * - Added min/max options
+ * - Added step size option
+ * - Added bigStep (page up/down) option
+ *
+ * Modifications made by Mark Gibson, (mgibson(a)designlinks.net) September 2006:
+ * - Converted to jQuery plugin
+ * - Allow limited or unlimited min/max values
+ * - Allow custom class names, and add class to input element
+ * - Removed global vars
+ * - Reset (to original or through config) when invalid value entered
+ * - Repeat whilst holding mouse button down (with initial pause, like keyboard repeat)
+ * - Support mouse wheel in Firefox
+ * - Fix double click in IE
+ * - Refactored some code and renamed some vars
+ *
+ * Tested in IE6, Opera9, Firefox 1.5
+ * v1.0 11 Aug 2006 - George Adamson - First release
+ * v1.1 Aug 2006 - George Adamson - Minor enhancements
+ * v1.2 27 Sep 2006 - Mark Gibson - Major enhancements
+ * v1.3a 28 Sep 2006 - George Adamson - Minor enhancements
+ * rf1.3a 15 Nov 2007 - Pavel Yaschenko - some changes
+
+ Sample usage:
+
+ // Create group of settings to initialise spinbutton(s). (Optional)
+ var myOptions = {
+ min: 0, // Set lower limit.
+ max: 100, // Set upper limit.
+ step: 1, // Set increment size.
+ spinClass: mySpinBtnClass, // CSS class to style the spinbutton. (Class also
specifies url of the up/down button image.)
+ upClass: mySpinUpClass, // CSS class for style when mouse over up button.
+ downClass: mySpinDnClass // CSS class for style when mouse over down button.
+ }
+
+ $(document).ready(function(){
+
+ // Initialise INPUT element(s) as SpinButtons: (passing options if desired)
+ $("#myInputElement").SpinButton(myOptions);
+
+ });
+
+ */
+var sbjQuery = oldJQuery;
+sbjQuery.fn.SpinButton = function(cfg){
+ return this.each(function(){
+
+ // Apply specified options or defaults:
+ // (Ought to refactor this some day to use $.extend() instead)
+ this.spinCfg = {
+ //min: cfg && cfg.min ? Number(cfg.min) : null,
+ //max: cfg && cfg.max ? Number(cfg.max) : null,
+ min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null, // Fixes bug
with min:0
+ max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
+ step: cfg && cfg.step ? Number(cfg.step) : 1,
+ page: cfg && cfg.page ? Number(cfg.page) : 10,
+ upClass: cfg && cfg.upClass ? cfg.upClass : 'up',
+ downClass: cfg && cfg.downClass ? cfg.downClass : 'down',
+ reset: cfg && cfg.reset ? cfg.reset : this.value,
+ delay: cfg && cfg.delay ? Number(cfg.delay) : 500,
+ interval: cfg && cfg.interval ? Number(cfg.interval) : 100,
+ _btn_width: 20,
+ _btn_height: 12,
+ _direction: null,
+ _delay: null,
+ _repeat: null,
+
+ digits: cfg && cfg.digits ? Number(cfg.digits) : 1
+ };
+
+ this.adjustValue = function(i){
+ var v = this.value.toLowerCase();
+ if (v=="am")
+ {
+ this.value="PM";
+ return;
+ }
+ else if (v=="pm") {
+ this.value="AM";
+ return;
+ }
+ v = (isNaN(this.value) ? this.spinCfg.reset : Number(this.value)) + Number(i);
+ if (this.spinCfg.min !== null) v = (v<this.spinCfg.min ? (this.spinCfg.max != null
? this.spinCfg.max : this.spinCfg.min) : v);
+ if (this.spinCfg.max !== null) v = (v>this.spinCfg.max ? (this.spinCfg.min != null
? this.spinCfg.min : this.spinCfg.max) : v);
+
+ var value = String(v);
+ while (value.length<this.spinCfg.digits) value="0"+value;
+
+ this.value = value;
+ };
+
+ sbjQuery(this)
+ .addClass(cfg && cfg.spinClass ? cfg.spinClass : 'spin-button')
+
+ .mousemove(function(e){
+ // Determine which button mouse is over, or not (spin direction):
+ var x = e.pageX || e.x;
+ var y = e.pageY || e.y;
+ var el = e.target || e.srcElement;
+ var direction =
+ (x > coord(el,'offsetLeft') + el.offsetWidth - this.spinCfg._btn_width)
+ ? ((y < coord(el,'offsetTop') + this.spinCfg._btn_height) ? 1 : -1) : 0;
+
+ if (direction !== this.spinCfg._direction) {
+ // Style up/down buttons:
+ switch(direction){
+ case 1: // Up arrow:
+ sbjQuery(this).removeClass(this.spinCfg.downClass).addClass(this.spinCfg.upClass);
+ break;
+ case -1: // Down arrow:
+ sbjQuery(this).removeClass(this.spinCfg.upClass).addClass(this.spinCfg.downClass);
+ break;
+ default: // Mouse is elsewhere in the textbox
+ sbjQuery(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
+ }
+
+ // Set spin direction:
+ this.spinCfg._direction = direction;
+ }
+ })
+
+ .mouseout(function(){
+ // Reset up/down buttons to their normal appearance when mouse moves away:
+ sbjQuery(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
+ this.spinCfg._direction = null;
+ })
+
+ .mousedown(function(e){
+ if (this.spinCfg._direction != 0) {
+ // Respond to click on one of the buttons:
+ var self = this;
+ var adjust = function() {
+ self.adjustValue(self.spinCfg._direction * self.spinCfg.step);
+ };
+
+ adjust();
+
+ // Initial delay before repeating adjustment
+ self.spinCfg._delay = window.setTimeout(function() {
+ adjust();
+ // Repeat adjust at regular intervals
+ self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
+ }, self.spinCfg.delay);
+ }
+ })
+
+ .mouseup(function(e){
+ // Cancel repeating adjustment
+ window.clearInterval(this.spinCfg._repeat);
+ window.clearTimeout(this.spinCfg._delay);
+ })
+
+ .dblclick(function(e) {
+ if (sbjQuery.browser.msie)
+ this.adjustValue(this.spinCfg._direction * this.spinCfg.step);
+ })
+
+ .keydown(function(e){
+ // Respond to up/down arrow keys.
+ switch(e.keyCode){
+ case 38: this.adjustValue(this.spinCfg.step); break; // Up
+ case 40: this.adjustValue(-this.spinCfg.step); break; // Down
+ case 33: this.adjustValue(this.spinCfg.page); break; // PageUp
+ case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
+ }
+ })
+
+ .bind("mousewheel", function(e){
+ // Respond to mouse wheel in IE. (It returns up/dn motion in multiples of 120)
+ if (e.wheelDelta >= 120)
+ this.adjustValue(this.spinCfg.step);
+ else if (e.wheelDelta <= -120)
+ this.adjustValue(-this.spinCfg.step);
+
+ e.preventDefault();
+ })
+
+ .change(function(e){
+ this.adjustValue(0);
+ });
+
+ if (this.addEventListener) {
+ // Respond to mouse wheel in Firefox
+ this.addEventListener('DOMMouseScroll', function(e) {
+ if (e.detail > 0)
+ this.adjustValue(-this.spinCfg.step);
+ else if (e.detail < 0)
+ this.adjustValue(this.spinCfg.step);
+
+ e.preventDefault();
+ }, false);
+ }
+ });
+
+ function coord(el,prop) {
+ var c = el[prop], b = document.body;
+
+ while ((el = el.offsetParent) && (el != b)) {
+ if (!sbjQuery.browser.msie || (el.currentStyle.position != 'relative'))
+ c += el[prop];
+ }
+
+ return c;
+ }
+};
Modified:
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/calendar.js
===================================================================
---
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/calendar.js 2007-11-23
17:14:48 UTC (rev 4233)
+++
trunk/ui/calendar/src/main/resources/org/richfaces/renderkit/html/scripts/calendar.js 2007-11-23
17:32:06 UTC (rev 4234)
@@ -133,8 +133,8 @@
els.position = originalPosition;
els.visibility = originalVisibility;
- element.style.left = ox + 'px';
- element.style.top = oy + 'px';
+ element.style.left = (ox + windowRect.left) + 'px';
+ element.style.top = (oy + windowRect.top) + 'px';
};
Richfaces.Calendar.getOffsetDimensions = function(element) {
@@ -269,10 +269,11 @@
var counter=1;
var y,m,d;
+ var a,h,min;
var shortLabel=false;
pattern = pattern.replace(/([.*+?^<>=!:${}()|[\]\/\\])/g, '\\$1');
- pattern = pattern.replace(/(y+|M+|d+)/g,
+ pattern = pattern.replace(/(y+|M+|d+|a|H{1,2}|h{1,2}|m{2})/g,
function($1) {
switch ($1) {
case 'y' :
@@ -281,6 +282,12 @@
case 'M' : m=counter; counter++; return '(\\d{1,2})';
case 'd' : d=counter; counter++; return '(\\d{1,2})';
case 'MMM': m=counter; counter++; shortLabel=true; return
'('+monthNamesShort.join('|')+')';
+ case 'a' : a=counter; counter++; return '(AM|am|PM|pm)?';
+ case 'HH' :
+ case 'hh' : h=counter; counter++; return '(\\d{2})?';
+ case 'H' :
+ case 'h' : h=counter; counter++; return '(\\d{1,2})?';
+ case 'mm' : min=counter; counter++; return '(\\d{2})?';
}
// y+,M+,d+
var ch = $1.charAt(0);
@@ -297,34 +304,72 @@
var yy = parseInt(match[y],10); if (isNaN(yy)) return null; else if (yy<70)
yy+=2000; else if (yy<100) yy+=1900;
var mm = parseInt(match[m],10); if (isNaN(mm)) mm =
Richfaces.Calendar.getMonthByLabel(match[m], shortLabel ? monthNamesShort : monthNames);
else if (--mm<0 || mm>11) return null;
var dd = parseInt(match[d],10); if (isNaN(dd) || dd<1 || dd>daysInMonth(yy, mm))
return null;
+
+ // time parsing
+ if (min!=undefined && h!=undefined)
+ {
+ var hh,mmin,aa;
+ mmin = parseInt(match[min],10); if (isNaN(mmin) || mmin<0 || mmin>59) return
null;
+ hh = parseInt(match[h],10); if (isNaN(hh)) return null;
+ if (a!=undefined)
+ {
+ aa = match[a].toLowerCase();
+ if ((aa!='am' && aa!='pm') || hh<1 || hh>12) return
null;
+ if (aa=='pm')
+ {
+ if (hh!=12) hh+=11;
+ } else if (hh==12) hh = 0;
+ }
+ else if (hh<0 || hh>23) return null;
+
+ return new Date(yy, mm, dd, hh, mmin, 0);
+ }
+
return new Date(yy, mm, dd);
}
return null;
- }
+ },
+
+ escape : function (str)
+ {
+ return str.replace(/([yMdaHhm])/g,"\\$1");
+ },
+
+ unescape : function (str)
+ {
+ return str.replace(/\\([yMdaHhm])/g,"$1");
+ }
});
Object.extend(Date.prototype, {
format : function(pattern, monthNames, monthNamesShort) {
if (!monthNames) monthNames = Date.getDefaultMonthNames();
if (!monthNamesShort) monthNamesShort = Date.getDefaultMonthNames(true);
- var d = this; var mm; var dd;
- return pattern.replace(/(y+|M+|d+)/g,
- function($1) {
- switch ($1) {
+ var d = this; var mm; var dd; var hh;
+ var result = pattern.replace(/(^|[^\\yMdHhm])(y+|M+|d+|a|H{1,2}|h{1,2}|m{2})/g,
+ function($1,$2,$3) {
+ switch ($3) {
case 'y':
- case 'yy': return str = d.getYear().toString().slice(-2);
- case 'M': return d.getMonth()+1;
- case 'MM': return (mm = d.getMonth()+1)<10 ? '0'+mm :
mm;
- case 'MMM': return monthNamesShort[d.getMonth()];
- case 'd': return d.getDate();
+ case 'yy': return $2+d.getYear().toString().slice(-2);
+ case 'M': return $2+(d.getMonth()+1);
+ case 'MM': return $2+((mm = d.getMonth()+1)<10 ? '0'+mm
: mm);
+ case 'MMM': return $2+monthNamesShort[d.getMonth()];
+ case 'd': return $2+d.getDate();
+ case 'a' : return $2+(d.getHours()<12 ? 'AM' :
'PM');
+ case 'HH' : return $2+((hh = d.getHours())<10 ? '0'+hh :
hh);
+ case 'H' : return $2+d.getHours();
+ case 'hh' : return $2+((hh = d.getHours())==0 ? '12' :
(hh<10 ? '0'+hh : (hh>12 ? hh-12 : hh)));
+ case 'h' : return $2+((hh = d.getHours())==0 ? '12' :
(hh>12 ? hh-12 : hh));
+ case 'mm' : return $2+((min = d.getMinutes())<10 ?
'0'+min : min);
}
// y+,M+,d+
- var ch = $1.charAt(0);
- if (ch=='y') return d.getFullYear();
- if (ch=='M') return monthNames[d.getMonth()];
- if (ch=='d') return (dd = d.getDate())<10 ? '0'+dd : dd;
+ var ch = $3.charAt(0);
+ if (ch=='y') return $2+d.getFullYear();
+ if (ch=='M') return $2+monthNames[d.getMonth()];
+ if (ch=='d') return $2+((dd = d.getDate())<10 ? '0'+dd : dd);
}
);
+ return Date.unescape(result);
}
});
@@ -409,6 +454,7 @@
// firstWeekDay - (0..6) locale-specific constant defining number of the first week
day
// showWeekDaysBar - show WeekDays Bar [default value is true]
// showWeeksBar - show Weeks numbers bar [default value is true]
+ // showApplyButton
// POPUP description
// direction - [top-left, top-right, bottom-left, bottom-right, auto]
@@ -429,13 +475,19 @@
// className - table class
-
this.id = id;
this.params = parameters;
+
+ this.showApplyButton = (!this.params.popup) ? false : this.params.showApplyButton;
+
if (this.params.showWeekDaysBar==undefined) this.params.showWeekDaysBar = true;
if (this.params.showWeeksBar==undefined) this.params.showWeeksBar = true;
- if (!this.params.datePattern) this.params.datePattern = "MMM d, y";
+
+ if (!this.params.datePattern) this.params.datePattern = "MMM d, y h:mm a";
+ // time
+ this.setTimeProperties();
+
// markups initialization
if (!this.params.dayListMarkup)
{
@@ -478,6 +530,7 @@
this.POPUP_BUTTON_ID = this.id+'PopupButton';
this.INPUT_DATE_ID = this.id+'InputDate';
this.IFRAME_ID = this.id+'IFrame';
+ this.TIME_EDITOR_ID = this.id+'TimeEditor';
//this.popupIntervalId=null;
@@ -590,10 +643,143 @@
}
},
+
+ createTimeEditor: function(element)
+ {
+ if (this.timeType==0) return false;
+ var div;
+ var hid = this.id+"Header";
+ var fid = this.id+"Footer";
+ while (element.id!=hid && element.id!=fid && element.parentNode)
element=element.parentNode;
+ {
+ div = document.createElement('div');
+ div.id = this.TIME_EDITOR_ID;
+ div.style.position='absolute';
+ div.style.textAlign='center';
+ div.style.backgroundColor='#f0f0f0';
+ div.style.border='1px solid #808080';
+ div.style.padding='3px';
+ div.style.visibility='hidden';
+ div.innerHTML = this.timePatternHtml+' <span
class="rich-calendar-btn"
onclick="$(\''+this.id+'\').component.hideTimeEditor(true)">[ok]</span>
'+
+ ' <span class="rich-calendar-btn"
onclick="$(\''+this.id+'\').component.hideTimeEditor(false)">[x]</span>';
+ element.appendChild(div);
+
+ var th=$(this.id+'TimeHours');
+ var ts;
+ var tm=$(this.id+'TimeMinutes');
+ if (this.timeType==1)
+ {
+ sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:0,max:23});
+ }
+ else
+ {
+ sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:1,max:12});
+ ts=$(this.id+'TimeSign');
+ sbjQuery(ts).SpinButton({});
+ }
+ sbjQuery(tm).SpinButton({digits:2,min:0,max:59});
+ }
+
+ var h = this.selectedDate.getHours();
+ var m = this.selectedDate.getMinutes();
+ if (this.timeType==2)
+ {
+ var a = (h<12 ? 'AM' : 'PM');
+ ts.value = a;
+ h = (h==0 ? '12' : (h>12 ? h-12 : h));
+ }
+ th.value = (h<10 ? '0'+h : h);
+ tm.value = (m<10 ? '0'+m : m);
+
+ div.style.width = element.clientWidth+'px';
+ div.style.width = (element.clientWidth - (div.offsetWidth -
element.clientWidth))+'px';
+ div.style.top = (div.offsetTop - div.offsetHeight -
element.offsetHeight)+'px';
+ div.style.visibility='';
+
+ return true;
+ },
+
+ setTimeProperties: function() {
+ this.timeType = 0;
+
+ var dateTimePattern = this.params.datePattern;
+ var pattern = [];
+ var re = /(^|[^\\yMdHhm])(y+|M+|d+|a|H{1,2}|h{1,2}|m{2})/g;
+ var r;
+ while (r = re.exec(dateTimePattern))
+ pattern.push({str:r[0],marker:r[2],pref:r[1],idx:r.index});
+
+ var datePattern = "";
+ var timePattern = "";
+
+ var digits,h,hh,m,a;
+ var id = this.id;
+
+ var getString = function (p) {
+ return (i==0 || p.length==0 ? obj.marker :
dateTimePattern.substring(pattern[i-1].str.length+pattern[i-1].idx,
obj.idx+obj.str.length));
+ };
+
+ for (var i=0;i<pattern.length;i++)
+ {
+ var obj = pattern[i];
+ var ch = obj.marker.charAt(0);
+ if (ch=='y'||ch=='M'||ch=='d')
datePattern+=getString(datePattern);
+ else if (ch=='a')
+ {
+ a=true;
+ timePattern+=getString(timePattern);
+ }
+ else if (ch=='H')
+ {
+ h=true;
+ digits=obj.marker.length;
+ timePattern+=getString(timePattern);
+ }
+ else if (ch=='h')
+ {
+ hh=true;
+ digits=obj.marker.length;
+ timePattern+=getString(timePattern);
+ }
+ else if (ch=='m')
+ {
+ m=true;
+ timePattern+=getString(timePattern);
+ }
+
+
+ }
+ this.datePattern = datePattern;
+ this.timePattern = timePattern;
+
+ this.timePatternHtml = timePattern.replace(/(^|[^\\Hhm])(H{1,2}|h{1,2}|m{2}|a)/g,
+ function($1,$2,$3) {
+ switch ($3) {
+ case 'a' : return $2+'<input style="width:22px;
margin: 0px 2px;" id="'+id+'TimeSign"/>';
+ case 'H' :
+ case 'h' : return $2+'<input style="width:22px;
margin: 0px 2px;" id="'+id+'TimeHours"/>';
+ case 'mm' : return $2+'<input style="width:22px;
margin: 0px 2px;" id="'+id+'TimeMinutes"/>';
+ }
+ }
+ );
+
+ if (m && h)
+ {
+ this.timeType = 1;
+ }
+ else if (m && hh && a)
+ {
+ this.timeType = 2;
+ }
+ this.timeHoursDigits = digits;
+ },
+
doCollapse: function() {
if (!this.params.popup || !this.isVisible) return;
+ this.hideTimeEditor();
+
/*this.stopTimer();
this.stopPopupEvents($(this.id));
this.stopPopupEvents($(this.POPUP_ID));*/
@@ -864,7 +1050,7 @@
var date=new Date(this.currentDate);
date.setDate(daydata.day);
- if (this.selectDate(date,true))
+ if (this.selectDate(date,true) && !this.showApplyButton)
{
this.doCollapse();
}
@@ -875,9 +1061,9 @@
else if (this.params.boundaryDatesMode == "select")
{
//var date = new Date(this.currentDate.getFullYear(),
this.currentDate.getMonth()+daydata._month, daydata.day);
- if (this.selectDate(daydata.date))
+ if (this.selectDate(daydata.date) && !this.showApplyButton)
{
- this.doCollapse();
+ this.doCollapse();
}
}
}
@@ -997,7 +1183,7 @@
},
render:function() {
-
+
this.todayDate = new Date();
var currentYear = this.getCurrentYear();
@@ -1070,8 +1256,7 @@
}
// render
- this.renderHeader();
- this.renderFooter();
+ this.renderHF();
this.renderHeaderOptional();
this.renderFooterOptional();
@@ -1216,13 +1401,14 @@
}*/
},
- renderHeader: function()
+
+ renderHF: function()
{
+ if (this.isTimeEditorCreated)
+ {
+ this.isTimeEditorCreated = false;
+ }
this.renderMarkup(this.params.headerMarkup, this.id+"Header",
this.calendarContext);
- },
-
- renderFooter: function()
- {
this.renderMarkup(this.params.footerMarkup, this.id+"Footer",
this.calendarContext);
},
@@ -1361,7 +1547,7 @@
this.selectedDate = newSelectedDate;
if (this.selectedDate!=null)
{
- field.value=this.getSelectedDateString(this.params.datePattern);
+ if (!this.showApplyButton)
field.value=this.getSelectedDateString(this.params.datePattern);
var d = new Date(this.selectedDate);
if (d.getMonth()==this.currentDate.getMonth() &&
d.getFullYear()==this.currentDate.getFullYear())
@@ -1376,9 +1562,7 @@
this.selectedDateCellColor = this.getCellBackgroundColor(e);
Element.addClassName(e, "rich-calendar-select");
- this.renderHeader();
- this.renderFooter();
- }
+ this.renderHF(); }
} else {
// change currentDate and call this.onUpdate();
d.setDate(1);
@@ -1396,15 +1580,13 @@
if (this.selectedDateCellId)
{
this.selectedDateCellId = null;
- this.renderHeader();
- this.renderFooter();
+ this.renderHF();
}
var date = new Date();
if (this.currentDate.getMonth()==date.getMonth() &&
this.currentDate.getFullYear()==date.getFullYear())
{
- this.renderHeader();
- this.renderFooter();
+ this.renderHF();
}
this.today(noUpdate, true);
}
@@ -1425,14 +1607,16 @@
if (this.invokeEvent("dateselect", null, null, null))
{
this.selectedDate = null;
- $(this.INPUT_DATE_ID).value = "";
this.selectedDateCellId = this.clearEffect(this.selectedDateCellId,
this.highlightEffect2, "rich-calendar-select");
- this.renderHeader();
- this.renderFooter();
- this.doCollapse();
- this.invokeEvent("dateselected", null, null, null);
+ this.renderHF();
+ if (!this.showApplyButton)
+ {
+ $(this.INPUT_DATE_ID).value = "";
+ this.doCollapse();
+ this.invokeEvent("dateselected", null, null, null);
+ }
}
},
@@ -1458,44 +1642,108 @@
}
}
}
+ },
+
+ close: function(updateDate)
+ {
+ if (updateDate)
+ {
+ var field = $(this.INPUT_DATE_ID);
+ field.value=this.getSelectedDateString(this.params.datePattern);
+ }
+ this.doCollapse();
+ },
+
+ showTimeEditor: function(element)
+ {
+ if (this.isTimeEditorCreated)
+ {
+ this.hideTimeEditor();
+ return;
+ }
+ if (this.createTimeEditor(element))
+ {
+ this.isTimeEditorCreated = true;
+ }
+ },
+
+ hideTimeEditor: function(updateTime)
+ {
+ if (updateTime && this.selectedDate)
+ {
+ var m = parseInt($(this.id+'TimeMinutes').value,10);
+ this.selectedDate.setMinutes(m);
+ var h=parseInt($(this.id+'TimeHours').value,10);
+ if (this.timeType==2)
+ {
+ if ($(this.id+'TimeSign').value.toLowerCase()=="am")
+ {
+ if (h==12) h = 0;
+ }
+ else
+ {
+ if (h!=12) h+=11;
+ }
+ }
+ this.selectedDate.setHours(h);
+ this.renderHF();
+ }
+
+ if (this.isTimeEditorCreated)
+ {
+ var e = $(this.TIME_EDITOR_ID);
+ e.parentNode.removeChild(e);
+ this.isTimeEditorCreated = false;
+ }
+
+ if (this.params.popup && !this.showApplyButton && updateTime)
this.close(true);
}
-
+
});
CalendarView = {};
-CalendarView.getControl = function(text, functionName) {
+CalendarView.getControl = function(text, functionName, paramsStr) {
var attr = {
- onclick: (functionName ?
"Richfaces.getComponent('calendar',this)."+functionName+"();"
: "")+"return true;",
+ onclick: (functionName ?
"Richfaces.getComponent('calendar',this)."+functionName+"("+(paramsStr
? paramsStr : "")+");" : "")+"return true;",
className: "rich-calendar-btn"
};
return new E('div',attr,[new T(text)]);
};
-CalendarView.getSelectedDateControl = function(text, functionName) {
- var attr = {
- onclick: "Richfaces.getComponent('calendar',this).showSelectedDate();
return true;",
- className: "rich-calendar-btn"
- };
+CalendarView.getSelectedDateControl = function(calendar) {
- var a = [new T(text)];
- if (text)
- {
- a.push(new T(" "));
- a.push(new E('a', {href: '#', onclick:
"Richfaces.getComponent('calendar',this).resetSelectedDate();return
true;"}, [new T('(x)')]));
- }
+ if (!calendar.selectedDate || calendar.showApplyButton) return "";
- return new E('div',attr,a);
+ var text = calendar.selectedDate.format( (calendar.timeType ? calendar.datePattern :
calendar.params.datePattern), calendar.params.monthLabels,
calendar.params.monthLabelsShort);
+
+ var markup = new E('div', {'class': 'rich-calendar-btn',
'style': 'white-space:nowrap', 'onclick':
"Richfaces.getComponent('calendar',this).showSelectedDate(); return
true;"}, [new ET(text)]);
+
+ return markup;
};
+CalendarView.getTimeControl = function(calendar) {
+
+ if (!calendar.selectedDate || !calendar.timeType) return "";
+
+ var text = calendar.selectedDate.format( calendar.timePattern,
calendar.params.monthLabels, calendar.params.monthLabelsShort);
+
+ var markup = new E('div', {'class': 'rich-calendar-btn
rich-calendar-time', 'style': 'white-space:nowrap', 'onclick':
"Richfaces.getComponent('calendar',this).showTimeEditor(this);return
true;"}, [new ET(text)]);
+
+ return markup;
+};
+
CalendarView.nextYearControl = CalendarView.getControl(">>",
"nextYear");
CalendarView.previousYearControl = CalendarView.getControl("<<",
"prevYear");
CalendarView.nextMonthControl = CalendarView.getControl(">",
"nextMonth");
CalendarView.previousMonthControl = CalendarView.getControl("<",
"prevMonth");
CalendarView.currentMonthControl = function (context) { return
context.calendar.getCurrentDate().format("MMMM, yyyy", context.monthLabels,
context.monthLabelsShort);};
CalendarView.todayControl = CalendarView.getControl("Today",
"today");
-CalendarView.selectedDateControl = function (context) { return
CalendarView.getSelectedDateControl(context.calendar.getSelectedDateString(context.calendar.params.datePattern));};
-//CalendarView.resetSelectedDateControl = function (context) { return
(context.calendar.getSelectedDate() ? CalendarView.getControl("x",
"resetSelectedDate") : "");};
+CalendarView.selectedDateControl = function (context) { return
CalendarView.getSelectedDateControl(context.calendar);};
+CalendarView.timeControl = function (context) { return
CalendarView.getTimeControl(context.calendar);};
+CalendarView.closeControl = CalendarView.getControl("x", "close",
"false");
+CalendarView.applyControl = function (context) { return (context.calendar.showApplyButton
? CalendarView.getControl("OK", "close", "true") :
"");};
+CalendarView.cleanControl = function (context) { return (context.calendar.selectedDate ?
CalendarView.getControl("Clean", "resetSelectedDate") :
"");};
CalendarView.header = [
new E('table',{'border': '0', 'cellpadding':
'0', 'cellspacing': '0', 'width': '100%'},
@@ -1523,6 +1771,10 @@
new E('td',{'class': 'rich-calendar-tool'},
[
new ET(function (context) { return Richfaces.evalMacro("nextYearControl",
context)})
+ ]),
+ new E('td',{'class': 'rich-calendar-tool'},
+ [
+ new ET(function (context) { return Richfaces.evalMacro("closeControl",
context)})
])
])
])
@@ -1536,23 +1788,32 @@
[
new E('tr',{},
[
- /*new E('td',{'class': 'rich-calendar-toolfooter'},
+ new E('td',{'class': 'rich-calendar-toolfooter',
'style':function(context){return (this.isEmpty ? 'display:none;' :
'');}},
[
- new ET(function (context) { return
Richfaces.evalMacro("resetSelectedDateControl", context)})
- ]),*/
- new E('td',{'class': 'rich-calendar-toolfooter',
'style': 'white-space:nowrap'},
+ new ET(function (context) { return
Richfaces.evalMacro("selectedDateControl", context)}),
+ ]),
+ new E('td',{'class': 'rich-calendar-toolfooter',
'style':function(context){return (this.isEmpty ? 'display:none;' :
'');}},
[
- new ET(function (context) { return
Richfaces.evalMacro("selectedDateControl", context)})
+ new ET(function (context) { return Richfaces.evalMacro("cleanControl",
context)})
]),
- new E('td',{'class': 'rich-calendar-toolfooter',
'align': 'right'},
+ new E('td',{'class': 'rich-calendar-toolfooter',
'style':function(context){return (this.isEmpty ? 'display:none;' :
'')+'background-color:#ffffff;';}},
[
+ new ET(function (context) { return Richfaces.evalMacro("timeControl",
context)})
+ ]),
+ new E('td',{'width': '100%'}, []),
+ new E('td',{'class': 'rich-calendar-toolfooter',
'style':function(context){return (this.isEmpty ? 'display:none;' :
'');}},
+ [
new ET(function (context) { return Richfaces.evalMacro("todayControl",
context)})
+ ]),
+ new E('td',{'class': 'rich-calendar-toolfooter',
'style':function(context){return (this.isEmpty ? 'display:none;' :
'');}},
+ [
+ new ET(function (context) { return Richfaces.evalMacro("applyControl",
context)})
])
])
])
]
)];
-
+
CalendarView.dayList = [new ET(function (context) { return context.day})];
CalendarView.weekNumber = [new ET(function (context) { return context.weekNumber})];
CalendarView.weekDay = [new ET(function (context) { return context.weekDayLabelShort})];
@@ -1572,7 +1833,10 @@
nextMonthControl: CalendarView.nextMonthControl,
previousMonthControl: CalendarView.previousMonthControl,
currentMonthControl: CalendarView.currentMonthControl,
+ selectedDateControl: CalendarView.selectedDateControl,
+ cleanControl: CalendarView.cleanControl,
+ timeControl: CalendarView.timeControl,
todayControl: CalendarView.todayControl,
- selectedDateControl: CalendarView.selectedDateControl
- //resetSelectedDateControl: CalendarView.resetSelectedDateControl,
+ closeControl: CalendarView.closeControl,
+ applyControl: CalendarView.applyControl
});
\ No newline at end of file
Modified: trunk/ui/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx
===================================================================
--- trunk/ui/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx 2007-11-23
17:14:48 UTC (rev 4233)
+++ trunk/ui/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx 2007-11-23
17:32:06 UTC (rev 4234)
@@ -9,9 +9,9 @@
baseclass="org.richfaces.renderkit.CalendarRendererBase"
component="org.richfaces.component.UICalendar">
<f:clientid var="clientId" />
- <h:scripts>new org.ajax4jsf.javascript.PrototypeScript(),new
org.ajax4jsf.javascript.AjaxScript(),/org/richfaces/renderkit/html/scripts/events.js,/org/richfaces/renderkit/html/scripts/utils.js,/org/richfaces/renderkit/html/scripts/json/json-dom.js,/org/richfaces/renderkit/html/scripts/scriptaculous/effects.js,/org/richfaces/renderkit/html/scripts/calendar.js</h:scripts>
+ <h:scripts>new org.ajax4jsf.javascript.PrototypeScript(),new
org.ajax4jsf.javascript.AjaxScript(),/org/richfaces/renderkit/html/scripts/events.js,/org/richfaces/renderkit/html/scripts/utils.js,/org/richfaces/renderkit/html/scripts/json/json-dom.js,/org/richfaces/renderkit/html/scripts/scriptaculous/effects.js,/org/richfaces/renderkit/html/scripts/jquery/jquery.js,/org/richfaces/renderkit/html/scripts/jquery/jquery.js,/org/richfaces/renderkit/html/scripts/JQuerySpinBtn.js,/org/richfaces/renderkit/html/scripts/calendar.js</h:scripts>
- <h:styles>/org/richfaces/renderkit/html/css/calendar.xcss</h:styles>
+ <h:styles>/org/richfaces/renderkit/html/css/JQuerySpinBtn.xcss,/org/richfaces/renderkit/html/css/calendar.xcss</h:styles>
<f:call name="addPopupToAjaxRendered" />