I know this is not a php question. If that bothers you, don't respond. If
not, I sure could use the advice...
I'm using a very abbreviated set of code to show a calendar. The idea is to
simply hide the calendar when it loses focus. I'm displaying the calendar in
a span tag. When that span loses focus, I recurse through its children. If
focus was lost to a child, then I want to keep the calendar visible. I'm
using the element.all to determine children of a given node. The problem is
that changing the months either with the navigation arrows or via the
drop-down, or by changing the year via its drop-down, the menu
disappears...ap parently the navigation links and the select's options are
not seen as a descendant of the primary span tag displaying the calendar.
(Sorry for the text-wrapping...and tia for any thoughts)
Here's a snippet of the html using the calendar:
=============== ======
<input class="value"
name="programEx itDate"
maxlength="255"
style="text-align:left; width:150px;"
type="text"
autocomplete="o ff"
value="<?= $programExitDat e ?>"
onblur="formatD ate(this);"
<img
src="<?= site::$imagesDi rectory ?>calendar.gif "
style="cursor:p ointer;"
title="Click For Calendar"
onclick="getDat e('programExitC alendar', 'programExitDat e');"
<span id="programExit Calendar" style="display: none;
postition:relat ive;"></span>
=============== ======
Here's the javascript being called:
=============== ======
String.prototyp e.repeat = function(l){ var s = '', i = 0; while (i++ <
l){ s += this; } return s; }
String.prototyp e.zf = function(l){ return '0'.repeat(l -
this.length) + this; }
Date.prototype. format = function(f)
{
if (!this.valueOf( )){ return this.toString() ; }
var date = this;
var days = new Array(
'Sunday' ,
'Monday' ,
'Tuesday' ,
'Wednesday' ,
'Thursday' ,
'Friday' ,
'Saturday'
);
var months = new Array(
'January' ,
'February' ,
'March' ,
'April' ,
'May' ,
'June' ,
'July' ,
'August' ,
'September' ,
'October' ,
'November' ,
'December'
);
return f.replace(
/(yyyy|mmmm|mmm| mm|dddd|ddd|dd| hh|nn|ss|a\/p)/gi ,
function($1)
{
switch ($1.toLowerCase ())
{
case 'yyyy' : return date.getFullYea r();
case 'mmmm' : return months[date.getMonth()];
case 'mmm' : return
months[date.getMonth()].substr(0, 3);
case 'mm' : return new String(date.get Month() +
1).zf(2);
case 'dddd' : return days[date.getDay()];
case 'ddd' : return days[date.getDay()].substr(0,
3);
case 'dd' : return new
String(date.get Date()).zf(2);
case 'hh' : return new String((h = date.getHours()
% 12) ? h : 12).zf(2);
case 'nn' : return new
String(date.get Minutes()).zf(2 );
case 'ss' : return new
String(date.get Seconds()).zf(2 );
case 'a/p' : return date.getHours() < 12 ? 'AM' :
'PM';
}
}
);
}
function formatDate(inpu t)
{
if (!input) { return false; }
if (!input.value) { return false; }
if (input.value == ''){ return false; }
var val = new String(input.va lue);
var month = new String('01');
var day = new String('01');
var year = new String('2000');
val = val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$1/$2/$3");
if (!isDate(val))
{
val = input.value;
val = val.replace(/^(\d{4})[^\d]+(\d{1,2})[^\d]+(\d{1,2})$/,
"$2/$3/$1");
}
if (!isDate(val))
{
input.value = '';
return false;
}
month = "0" + val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$1");
day = "0" + val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$2");
year = val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$3");
val = month.substr(mo nth.length - 2, 2) + "/" +
day.substr(day. length - 2, 2) + "/" + year;
input.value = val;
return true;
}
function getDate(parent, target)
{
parent = document.getEle mentById(parent );
target = document.getEle mentById(target );
if (!parent){ return false; }
if (!target){ return false; }
var currentDate = isDate(target.v alue) ? new Date(target.val ue) : new
Date();
target.value = isDate(target.v alue) ? target.value : '';
parent.onblur = function()
{
if (isChild(parent ,
document.active Element)){ return; }
parent.style.di splay = 'none';
parent.innerHTM L = '';
};
showCalendar(pa rent.id, target.name, currentDate.get FullYear(),
currentDate.get Month());
return false;
}
function isChild(parent, element)
{
if (element == parent){ return true; }
var children = parent.all;
for (var child in children)
{
var node = children[child];
if (element == node){ return true; }
if (node.all)
{
if (isChild(node, element)){ return true; }
}
}
return false;
}
function showCalendar(sh owIn, returnTo, year, month, day)
{
showIn = document.getEle mentById(showIn );
returnTo = document.getEle mentById(return To);
if (!showIn){ return false; }
if (!returnTo){ return false; }
showIn.style.po sition = 'absolute';
showIn.style.di splay = '';
if (day)
{
showIn.onblur = null;
showIn.style.di splay = 'none';
showIn.innerHTM L = '';
var date = new Date((month + 1) + '/' + day + '/' + year);
returnTo.value = date.format('mm/dd/yyyy');
returnTo.focus( );
returnTo.select ();
return false;
}
if (showIn.innerHT ML)
{
showIn.innerHTM L = '';
return;
}
var link = null;
var months = new Array(
'January' ,
'February' ,
'March' ,
'April' ,
'May' ,
'June' ,
'July' ,
'August' ,
'September' ,
'October' ,
'November' ,
'December'
);
var thisDate = new Date();
year = year < 2000 ? 2000 : year;
year = year 2037 ? 2037 : year;
thisDate.setYea r(year);
thisDate.setMon th(month);
thisDate.setDat e(1);
var days = 32 - new Date(year, month, 32).getDate();
var nextDate = new Date(year, month, days + 1);
var lastDate = new Date(year, month, 0);
lastDate.setDat e(1);
var today = new Date();
var todayDay = today.getDate() ;
var todayMonth = today.getMonth( );
var todayYear = today.getFullYe ar();
var html = '';
html += '<table style="border:1 px solid steelblue; margin:2px;
padding:2px; width:225px;">\ n';
html += ' <tr>\n';
html += ' <td style="backgrou nd-color:#FF9900; font-family:arial;
font-size:7.25pt; padding-right:5px; padding-top:2px;
text-align:right;">\ n';
html += ' <a\n';
html += ' href=""\n';
html += ' onclick="showCa lendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + lastDate.getFul lYear() + ', ' + lastDate.getMon th()
+ ')"\n';
html += ' title="Previous Month"\n';
html += ' ><img src="/images/arrow.left.gif"
style="border:n one;"></a>\n';
html += ' </td>\n';
html += ' <td colspan="5" style="backgrou nd-color:#FF9900;
padding-top:2px; text-align:center;"> \n';
html += ' <select\n';
html += ' style="font-family:arial; font-size:7.25pt;
text-align:center; width:85px;"\n' ;
html += ' onchange="showC alendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + thisDate.getFul lYear() + ', this.value)"\n' ;
html += ' >\n';
for (month in months)
{
var selected = month == thisDate.getMon th() ? 'selected' : '\n';
html += ' <option value="' + month + '" ' + selected + '>' +
months[month] + '</option>\n';
}
html += ' </select>\n';
html += ' <select\n';
html += ' style="font-family:arial; font-size:7.25pt;
text-align:center; width:50px;"\n' ;
html += ' onchange="showC alendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', this.value, ' + thisDate.getMon th() + ')"\n';
html += ' >\n';
for (year = 2000; year < 2038; year++)
{
var selected = year == thisDate.getFul lYear() ? 'selected' : '\n';
html += ' <option value="' + year + '" ' + selected + '>' + year +
'</option>\n';
}
html += ' </select>\n';
html += ' </td>\n';
html += ' <td style="backgrou nd-color:#FF9900; font-size:7.25pt;
padding-left:5px; padding-top:2px; text-align:left;">\n ';
html += ' <a\n';
html += ' href=""\n';
html += ' onclick="showCa lendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + nextDate.getFul lYear() + ', ' + nextDate.getMon th()
+ ')"\n';
html += ' title="Next Month"\n';
html += ' ><img src="/images/arrow.right.gif "
style="border:n one;"></a>\n';
html += ' </td>\n';
html += ' <tr><td colspan="7" style="backgrou nd-color:#FF9900;
border-bottom:1px solid lavender; height:2px;"></td></tr>\n';
html += ' <tr>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Su n</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Mo n</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Tu e</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">We d</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Th u</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Fr i</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Sa t</td>\n';
html += ' </tr>\n';
html += ' <tr><td colspan="7" style="border-bottom:1px solid lavender;
height:2px;"></td></tr>\n';
html += ' <tr>\n';
month = thisDate.getMon th();
year = thisDate.getFul lYear();
var daysLeft = 0;
var weekDay = thisDate.getDay ();
if (weekDay 0)
{
html += ' <td colspan="' + weekDay + '"
style="backgrou nd-color:lavender; font-size:7.25pt;
width:25px;">&n bsp;</td>\n';
}
for (var day = 1; day <= days; day++)
{
for (; weekDay < 7; weekDay++)
{
if (day days)
{
daysLeft++;
continue;
}
if (!weekDay)
{
html += ' </tr>\n';
html += ' <tr>\n';
}
var border = 'none';
var fontWeight = '100';
if (day == todayDay && month == todayMonth && year == todayYear)
{
border = '1px solid #990000';
fontWeight = '600';
}
html += '<td style="border:' + border + 'font-size:7.25pt;
width:20px;">\n ';
html += ' <a\n';
html += ' href="' + day + '"\n';
html += ' style="font-weight:' + fontWeight + ';
text-decoration:none ;"\n';
html += ' onclick="return showCalendar(\' ' + showIn.id + '\',
\'' + returnTo.name + '\', ' + year + ', ' + month + ', ' + day + ')"\n';
html += ' >' + day + '</a>\n';
html += '</td>\n';
day++
}
day--;
weekDay = 0;
}
if (daysLeft 0)
{
html += ' <td colspan="' + daysLeft + '"
style="backgrou nd-color:lavender; width:25px;">&n bsp;</td>\n';
}
html += ' </tr>\n';
html += '</table>\n';
showIn.innerHTM L = html;
showIn.focus();
return false;
}
=============== ======
not, I sure could use the advice...
I'm using a very abbreviated set of code to show a calendar. The idea is to
simply hide the calendar when it loses focus. I'm displaying the calendar in
a span tag. When that span loses focus, I recurse through its children. If
focus was lost to a child, then I want to keep the calendar visible. I'm
using the element.all to determine children of a given node. The problem is
that changing the months either with the navigation arrows or via the
drop-down, or by changing the year via its drop-down, the menu
disappears...ap parently the navigation links and the select's options are
not seen as a descendant of the primary span tag displaying the calendar.
(Sorry for the text-wrapping...and tia for any thoughts)
Here's a snippet of the html using the calendar:
=============== ======
<input class="value"
name="programEx itDate"
maxlength="255"
style="text-align:left; width:150px;"
type="text"
autocomplete="o ff"
value="<?= $programExitDat e ?>"
onblur="formatD ate(this);"
>
src="<?= site::$imagesDi rectory ?>calendar.gif "
style="cursor:p ointer;"
title="Click For Calendar"
onclick="getDat e('programExitC alendar', 'programExitDat e');"
>
postition:relat ive;"></span>
=============== ======
Here's the javascript being called:
=============== ======
String.prototyp e.repeat = function(l){ var s = '', i = 0; while (i++ <
l){ s += this; } return s; }
String.prototyp e.zf = function(l){ return '0'.repeat(l -
this.length) + this; }
Date.prototype. format = function(f)
{
if (!this.valueOf( )){ return this.toString() ; }
var date = this;
var days = new Array(
'Sunday' ,
'Monday' ,
'Tuesday' ,
'Wednesday' ,
'Thursday' ,
'Friday' ,
'Saturday'
);
var months = new Array(
'January' ,
'February' ,
'March' ,
'April' ,
'May' ,
'June' ,
'July' ,
'August' ,
'September' ,
'October' ,
'November' ,
'December'
);
return f.replace(
/(yyyy|mmmm|mmm| mm|dddd|ddd|dd| hh|nn|ss|a\/p)/gi ,
function($1)
{
switch ($1.toLowerCase ())
{
case 'yyyy' : return date.getFullYea r();
case 'mmmm' : return months[date.getMonth()];
case 'mmm' : return
months[date.getMonth()].substr(0, 3);
case 'mm' : return new String(date.get Month() +
1).zf(2);
case 'dddd' : return days[date.getDay()];
case 'ddd' : return days[date.getDay()].substr(0,
3);
case 'dd' : return new
String(date.get Date()).zf(2);
case 'hh' : return new String((h = date.getHours()
% 12) ? h : 12).zf(2);
case 'nn' : return new
String(date.get Minutes()).zf(2 );
case 'ss' : return new
String(date.get Seconds()).zf(2 );
case 'a/p' : return date.getHours() < 12 ? 'AM' :
'PM';
}
}
);
}
function formatDate(inpu t)
{
if (!input) { return false; }
if (!input.value) { return false; }
if (input.value == ''){ return false; }
var val = new String(input.va lue);
var month = new String('01');
var day = new String('01');
var year = new String('2000');
val = val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$1/$2/$3");
if (!isDate(val))
{
val = input.value;
val = val.replace(/^(\d{4})[^\d]+(\d{1,2})[^\d]+(\d{1,2})$/,
"$2/$3/$1");
}
if (!isDate(val))
{
input.value = '';
return false;
}
month = "0" + val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$1");
day = "0" + val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$2");
year = val.replace(/^(\d{1,2})[^\d]+(\d{1,2})[^\d]+(\d{4})$/,
"$3");
val = month.substr(mo nth.length - 2, 2) + "/" +
day.substr(day. length - 2, 2) + "/" + year;
input.value = val;
return true;
}
function getDate(parent, target)
{
parent = document.getEle mentById(parent );
target = document.getEle mentById(target );
if (!parent){ return false; }
if (!target){ return false; }
var currentDate = isDate(target.v alue) ? new Date(target.val ue) : new
Date();
target.value = isDate(target.v alue) ? target.value : '';
parent.onblur = function()
{
if (isChild(parent ,
document.active Element)){ return; }
parent.style.di splay = 'none';
parent.innerHTM L = '';
};
showCalendar(pa rent.id, target.name, currentDate.get FullYear(),
currentDate.get Month());
return false;
}
function isChild(parent, element)
{
if (element == parent){ return true; }
var children = parent.all;
for (var child in children)
{
var node = children[child];
if (element == node){ return true; }
if (node.all)
{
if (isChild(node, element)){ return true; }
}
}
return false;
}
function showCalendar(sh owIn, returnTo, year, month, day)
{
showIn = document.getEle mentById(showIn );
returnTo = document.getEle mentById(return To);
if (!showIn){ return false; }
if (!returnTo){ return false; }
showIn.style.po sition = 'absolute';
showIn.style.di splay = '';
if (day)
{
showIn.onblur = null;
showIn.style.di splay = 'none';
showIn.innerHTM L = '';
var date = new Date((month + 1) + '/' + day + '/' + year);
returnTo.value = date.format('mm/dd/yyyy');
returnTo.focus( );
returnTo.select ();
return false;
}
if (showIn.innerHT ML)
{
showIn.innerHTM L = '';
return;
}
var link = null;
var months = new Array(
'January' ,
'February' ,
'March' ,
'April' ,
'May' ,
'June' ,
'July' ,
'August' ,
'September' ,
'October' ,
'November' ,
'December'
);
var thisDate = new Date();
year = year < 2000 ? 2000 : year;
year = year 2037 ? 2037 : year;
thisDate.setYea r(year);
thisDate.setMon th(month);
thisDate.setDat e(1);
var days = 32 - new Date(year, month, 32).getDate();
var nextDate = new Date(year, month, days + 1);
var lastDate = new Date(year, month, 0);
lastDate.setDat e(1);
var today = new Date();
var todayDay = today.getDate() ;
var todayMonth = today.getMonth( );
var todayYear = today.getFullYe ar();
var html = '';
html += '<table style="border:1 px solid steelblue; margin:2px;
padding:2px; width:225px;">\ n';
html += ' <tr>\n';
html += ' <td style="backgrou nd-color:#FF9900; font-family:arial;
font-size:7.25pt; padding-right:5px; padding-top:2px;
text-align:right;">\ n';
html += ' <a\n';
html += ' href=""\n';
html += ' onclick="showCa lendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + lastDate.getFul lYear() + ', ' + lastDate.getMon th()
+ ')"\n';
html += ' title="Previous Month"\n';
html += ' ><img src="/images/arrow.left.gif"
style="border:n one;"></a>\n';
html += ' </td>\n';
html += ' <td colspan="5" style="backgrou nd-color:#FF9900;
padding-top:2px; text-align:center;"> \n';
html += ' <select\n';
html += ' style="font-family:arial; font-size:7.25pt;
text-align:center; width:85px;"\n' ;
html += ' onchange="showC alendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + thisDate.getFul lYear() + ', this.value)"\n' ;
html += ' >\n';
for (month in months)
{
var selected = month == thisDate.getMon th() ? 'selected' : '\n';
html += ' <option value="' + month + '" ' + selected + '>' +
months[month] + '</option>\n';
}
html += ' </select>\n';
html += ' <select\n';
html += ' style="font-family:arial; font-size:7.25pt;
text-align:center; width:50px;"\n' ;
html += ' onchange="showC alendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', this.value, ' + thisDate.getMon th() + ')"\n';
html += ' >\n';
for (year = 2000; year < 2038; year++)
{
var selected = year == thisDate.getFul lYear() ? 'selected' : '\n';
html += ' <option value="' + year + '" ' + selected + '>' + year +
'</option>\n';
}
html += ' </select>\n';
html += ' </td>\n';
html += ' <td style="backgrou nd-color:#FF9900; font-size:7.25pt;
padding-left:5px; padding-top:2px; text-align:left;">\n ';
html += ' <a\n';
html += ' href=""\n';
html += ' onclick="showCa lendar(\'' + showIn.id + '\', \'' +
returnTo.name + '\', ' + nextDate.getFul lYear() + ', ' + nextDate.getMon th()
+ ')"\n';
html += ' title="Next Month"\n';
html += ' ><img src="/images/arrow.right.gif "
style="border:n one;"></a>\n';
html += ' </td>\n';
html += ' <tr><td colspan="7" style="backgrou nd-color:#FF9900;
border-bottom:1px solid lavender; height:2px;"></td></tr>\n';
html += ' <tr>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Su n</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Mo n</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Tu e</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">We d</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Th u</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Fr i</td>\n';
html += ' <td style="font-size:7.25pt; font-weight:600;
text-align:center; width:25px;">Sa t</td>\n';
html += ' </tr>\n';
html += ' <tr><td colspan="7" style="border-bottom:1px solid lavender;
height:2px;"></td></tr>\n';
html += ' <tr>\n';
month = thisDate.getMon th();
year = thisDate.getFul lYear();
var daysLeft = 0;
var weekDay = thisDate.getDay ();
if (weekDay 0)
{
html += ' <td colspan="' + weekDay + '"
style="backgrou nd-color:lavender; font-size:7.25pt;
width:25px;">&n bsp;</td>\n';
}
for (var day = 1; day <= days; day++)
{
for (; weekDay < 7; weekDay++)
{
if (day days)
{
daysLeft++;
continue;
}
if (!weekDay)
{
html += ' </tr>\n';
html += ' <tr>\n';
}
var border = 'none';
var fontWeight = '100';
if (day == todayDay && month == todayMonth && year == todayYear)
{
border = '1px solid #990000';
fontWeight = '600';
}
html += '<td style="border:' + border + 'font-size:7.25pt;
width:20px;">\n ';
html += ' <a\n';
html += ' href="' + day + '"\n';
html += ' style="font-weight:' + fontWeight + ';
text-decoration:none ;"\n';
html += ' onclick="return showCalendar(\' ' + showIn.id + '\',
\'' + returnTo.name + '\', ' + year + ', ' + month + ', ' + day + ')"\n';
html += ' >' + day + '</a>\n';
html += '</td>\n';
day++
}
day--;
weekDay = 0;
}
if (daysLeft 0)
{
html += ' <td colspan="' + daysLeft + '"
style="backgrou nd-color:lavender; width:25px;">&n bsp;</td>\n';
}
html += ' </tr>\n';
html += '</table>\n';
showIn.innerHTM L = html;
showIn.focus();
return false;
}
=============== ======
Comment