...

View Full Version : Looking for a good Javascript date picker



vw98034
07-28-2009, 10:38 PM
Can anyone recommend a good Javascript calendar library for selecting a date?

Thanks very much in advance.

Old Pedant
07-29-2009, 01:08 AM
I wrote one. Dunno whether it qualifies as "good" in your eyes. But try it.

http://www.ClearviewDesign.com/Newbie

It's the second one of the demos. No, it's nothing to do with ASP.

NOTE: It appears to have problems positioning the year and month dropdowns in some browsers. I'm looking into that now. Check for updates.

jmrker
07-29-2009, 03:46 AM
Another possibility:


<html>
<head>
<title>Dual Calendar</title>

<style type="text/css">
.cal {
width:240px;
display:none;
border:1px solid black;
/* following 2 lines are optional, depending of type of display */
z-index:10;
position:fixed;
}
.cal th {
border:1px solid #AAAAAA;
color: #000000;
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
background-color: #FFFF00;
cursor:pointer;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
.cal td {
border: 1px solid #AAAAAA;
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
background-color: #FFFF00;
margin: 0px 0px 0px 0px;
padding: 1px 2px 1px 2px;
}
btn {
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
}

</style>


<script language="javascript" type="text/javascript">

function calendar(ids,txt) {
this.Txt = txt;
this.Ids = ids;
this.Cdate = new Date();
this.monthM = this.Cdate.getMonth()+1;
this.dayM = this.Cdate.getDate();
this.yearM = this.Cdate.getFullYear();
this.monthC = this.monthM;
this.dayC = this.dayM;
this.yearC = this.yearM;

this.CalendarRedisplay = function(M,Y) {
if ((M==0) && (Y==0)) {
M = this.monthM;
Y = this.yearM;
} else {
M = this.monthC+M;
Y = this.yearC+Y;
if (M < 1) { M = 12; Y--; }
if (M > 12) { M = 1; Y++; }
}
this.monthC = M;
this.yearC = Y;
document.getElementById(this.Ids).innerHTML = this.displayCalendar(M,Y);
}
this.displayCalendar = function(month, year) {
month = parseInt(month);
year = parseInt(year);
var i = 0;
var days = getDaysInMonth(month,year);
var firstOfMonth = new Date (year, (month-1), 1);
var startingPos = firstOfMonth.getDay();
days += startingPos;

var page = '<table width="100%"><tr><th colspan="7">';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,-1)">|</button> ';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(-1,0)">&lt;</button> ';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,0)">';
page += MonthOfYear[month]+' '+year+'</button>';
page += ' <button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(1,0)">&gt;</button>';
page += ' <button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,1)">|</button>';
page += '</th></tr>';
page += '<tr><th scope="col">Su</th><th scope="col">Mo</th><th scope="col">Tu</th><th scope="col">';
page += 'We</th><th scope="col">Th</th><th scope="col">Fr</th><th scope="col">Sa</th></tr>';

page += '<tr>';
for (i = 0; i < startingPos; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += '<th>&nbsp;</th>';
}
for (i = startingPos; i < days; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += '<th';
page += ' onclick="'+this.Ids+'.update('+(i-startingPos+1)+')">';
page += (i-startingPos+1) + '</th>';
}
for (i=days; i<42; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += "<th>&nbsp;</th>";
}
page += '</tr></table>';
return page;
}

this.display = function() {
this.toggle();
document.getElementById(this.Ids).innerHTML = this.displayCalendar(this.monthC,this.yearC);
}
this.toggle = function() {
var sel = document.getElementById(this.Ids);
if (sel.style.display != 'block') { document.getElementById(this.Ids).style.display = 'block'; }
else { document.getElementById(this.Ids).style.display = 'none'; }
}
this.update = function(info) {
this.dayC = info;
this.toggle();
document.getElementById(this.Txt).value = pad(this.monthC)+'/'+pad(this.dayC)+'/'+this.yearC;
}
}

cal1 = new calendar('cal1','StartDate');
cal2 = new calendar('cal2','StopDate');

var MonthOfYear = ['','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var DaysInMonth = ['',31,28,31,30,31,30,31,31,30,31,30,31];
function getDaysInMonth(month,year) {
var days = DaysInMonth[month];
if ((month == 2) && isLeapYear(year)) { days=29; }
return days;
}
function isLeapYear (Year) {
if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) { return (true); }
else { return (false); }
}
function pad(value) {
return value=(value < 10)?'0'+value:value;
}

</script>
</head>
<body><!-- onload='cal1.update(cal1.update(0))' -->

<input type="text" id="StartDate">
<img src="cal.gif" onclick="cal1.display()">
<div id="cal1" class="cal"></div>

<br>

<input type="text" id="StopDate">
<img src="cal.gif" onclick="cal2.display()">
<div id="cal2" class="cal"></div>
<br>

</body>
</html>


Script is set-up for two calendars, but is fairly easy to remove one.
You can play with the CSS to change colors, size, positions, etc.

Good Luck!
:)

vw98034
07-29-2009, 06:34 AM
I wrote one. Dunno whether it qualifies as "good" in your eyes. But try it.

http://www.ClearviewDesign.com/Newbie

It's the second one of the demos. No, it's nothing to do with ASP.

NOTE: It appears to have problems positioning the year and month dropdowns in some browsers. I'm looking into that now. Check for updates.

My eyes might not work well at this time of a day. I don't know what you want me to see on the page. I can't find what I am looking for, a Javascript code and a demo.

Old Pedant
07-29-2009, 06:46 AM
Click on "Demos" on that page and then click on the second demo in the list.

But w.t.h.:
http://www.clearviewdesign.com/Newbie/Demos/poponCalendarDemo.shtml
http://www.clearviewdesign.com/Newbie/Demos/poponCalendarDemo.shtml

and I did fix the minor bugs it had in XHTML traditional. Seems to work fine in MSIE/FF/Chrome.

vw98034
07-29-2009, 06:53 AM
Another possibility:


<html>
<head>
<title>Dual Calendar</title>

<style type="text/css">
.cal {
width:240px;
display:none;
border:1px solid black;
/* following 2 lines are optional, depending of type of display */
z-index:10;
position:fixed;
}
.cal th {
border:1px solid #AAAAAA;
color: #000000;
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
background-color: #FFFF00;
cursor:pointer;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
.cal td {
border: 1px solid #AAAAAA;
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
background-color: #FFFF00;
margin: 0px 0px 0px 0px;
padding: 1px 2px 1px 2px;
}
btn {
font: 70% Verdana, Geneva, Arial, Helvetica, sans-serif;
}

</style>


<script language="javascript" type="text/javascript">

function calendar(ids,txt) {
this.Txt = txt;
this.Ids = ids;
this.Cdate = new Date();
this.monthM = this.Cdate.getMonth()+1;
this.dayM = this.Cdate.getDate();
this.yearM = this.Cdate.getFullYear();
this.monthC = this.monthM;
this.dayC = this.dayM;
this.yearC = this.yearM;

this.CalendarRedisplay = function(M,Y) {
if ((M==0) && (Y==0)) {
M = this.monthM;
Y = this.yearM;
} else {
M = this.monthC+M;
Y = this.yearC+Y;
if (M < 1) { M = 12; Y--; }
if (M > 12) { M = 1; Y++; }
}
this.monthC = M;
this.yearC = Y;
document.getElementById(this.Ids).innerHTML = this.displayCalendar(M,Y);
}
this.displayCalendar = function(month, year) {
month = parseInt(month);
year = parseInt(year);
var i = 0;
var days = getDaysInMonth(month,year);
var firstOfMonth = new Date (year, (month-1), 1);
var startingPos = firstOfMonth.getDay();
days += startingPos;

var page = '<table width="100%"><tr><th colspan="7">';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,-1)">|</button> ';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(-1,0)">&lt;</button> ';
page += '<button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,0)">';
page += MonthOfYear[month]+' '+year+'</button>';
page += ' <button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(1,0)">&gt;</button>';
page += ' <button class="btn" onClick="'+this.Ids+'.CalendarRedisplay(0,1)">|</button>';
page += '</th></tr>';
page += '<tr><th scope="col">Su</th><th scope="col">Mo</th><th scope="col">Tu</th><th scope="col">';
page += 'We</th><th scope="col">Th</th><th scope="col">Fr</th><th scope="col">Sa</th></tr>';

page += '<tr>';
for (i = 0; i < startingPos; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += '<th>&nbsp;</th>';
}
for (i = startingPos; i < days; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += '<th';
page += ' onclick="'+this.Ids+'.update('+(i-startingPos+1)+')">';
page += (i-startingPos+1) + '</th>';
}
for (i=days; i<42; i++) {
if ( i%7 == 0 ) page += "</tr><tr>";
page += "<th>&nbsp;</th>";
}
page += '</tr></table>';
return page;
}

this.display = function() {
this.toggle();
document.getElementById(this.Ids).innerHTML = this.displayCalendar(this.monthC,this.yearC);
}
this.toggle = function() {
var sel = document.getElementById(this.Ids);
if (sel.style.display != 'block') { document.getElementById(this.Ids).style.display = 'block'; }
else { document.getElementById(this.Ids).style.display = 'none'; }
}
this.update = function(info) {
this.dayC = info;
this.toggle();
document.getElementById(this.Txt).value = pad(this.monthC)+'/'+pad(this.dayC)+'/'+this.yearC;
}
}

cal1 = new calendar('cal1','StartDate');
cal2 = new calendar('cal2','StopDate');

var MonthOfYear = ['','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var DaysInMonth = ['',31,28,31,30,31,30,31,31,30,31,30,31];
function getDaysInMonth(month,year) {
var days = DaysInMonth[month];
if ((month == 2) && isLeapYear(year)) { days=29; }
return days;
}
function isLeapYear (Year) {
if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) { return (true); }
else { return (false); }
}
function pad(value) {
return value=(value < 10)?'0'+value:value;
}

</script>
</head>
<body><!-- onload='cal1.update(cal1.update(0))' -->

<input type="text" id="StartDate">
<img src="cal.gif" onclick="cal1.display()">
<div id="cal1" class="cal"></div>

<br>

<input type="text" id="StopDate">
<img src="cal.gif" onclick="cal2.display()">
<div id="cal2" class="cal"></div>
<br>

</body>
</html>


Script is set-up for two calendars, but is fairly easy to remove one.
You can play with the CSS to change colors, size, positions, etc.

Good Luck!
:)

I have tested your code. It is quite good:thumbsup: I have a suggestion on the UI. It would be better if the date colour will be changed when mouse-over. I haven't studied your code yet and I don't know how easy to make this enhancement. Again, I haven't studied your code. I don't know whether it can be configured so that only the current and future date can be picked and the second date can't later than the first date.

Thanks!

Philip M
07-29-2009, 08:09 AM
Script to check that a date is in the future:-


<script type = "text/javascript">

function checkFutureDate() {
var end_year = 2009;
var end_month = 6; // months are 0-11
var end_day = 13;

var now = new Date().getTime();
var d = new Date();
d.setFullYear(end_year, end_month, end_day); // YYYY,MM(0-11),DD
var selectedDate = d.getTime(); // today or after
if (selectedDate <= now) { // valid after today's date
//if (selectedDate < now) { // valid on today's date or after
alert ("Date must be (on or) after today's date!");
return false;
}
alert ("Date is valid");
return true;
}

checkFutureDate();

</script>

It would help if you indicate whether the dates to be selected are a few days or many days/months/years apart. This will populate a select box with the next ten days, and could easily be modified to say 31 days.


<body onload = "populate()">

<form name= "myform">
<select name = "datelist">
<option value = "d0"></option>
<option value = "d1"></option>
<option value = "d2"></option>
<option value = "d3"></option>
<option value = "d4"></option>
<option value = "d5"></option>
<option value = "d6"></option>
<option value = "d7"></option>
<option value = "d8"></option>
<option value = "d9"></option>
</select>

</form>

<script type = "text/javascript">

function populate() {
var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
var days = ["Sun","Mon","Tues","Wed","Thur","Fri","Sat"];
for (var i =0; i<10; i++) {
var nd = new Date();
nd.setMonth(nd.getMonth());
nd.setDate(nd.getDate() + i);
var mn = nd.getMonth();
var dy = nd.getDate();
var yy = nd.getFullYear();
var day = nd.getDay();

var d = days[day] + ", " + months[mn] + " " + dy + ", " + yy;
document.myform.datelist.options[i].text = d;
}
}

</script>

vw98034
07-29-2009, 10:51 PM
Click on "Demos" on that page and then click on the second demo in the list.

But w.t.h.:
http://www.clearviewdesign.com/Newbie/Demos/poponCalendarDemo.shtml
http://www.clearviewdesign.com/Newbie/Demos/poponCalendarDemo.shtml

and I did fix the minor bugs it had in XHTML traditional. Seems to work fine in MSIE/FF/Chrome.

Get it and looks good:thumbsup:

vw98034
07-29-2009, 11:00 PM
Script to check that a date is in the future:-


<script type = "text/javascript">

function checkFutureDate() {
var end_year = 2009;
var end_month = 6; // months are 0-11
var end_day = 13;

var now = new Date().getTime();
var d = new Date();
d.setFullYear(end_year, end_month, end_day); // YYYY,MM(0-11),DD
var selectedDate = d.getTime(); // today or after
if (selectedDate <= now) { // valid after today's date
//if (selectedDate < now) { // valid on today's date or after
alert ("Date must be (on or) after today's date!");
return false;
}
alert ("Date is valid");
return true;
}

checkFutureDate();

</script>

It would help if you indicate whether the dates to be selected are a few days or many days/months/years apart. This will populate a select box with the next ten days, and could easily be modified to say 31 days.


<body onload = "populate()">

<form name= "myform">
<select name = "datelist">
<option value = "d0"></option>
<option value = "d1"></option>
<option value = "d2"></option>
<option value = "d3"></option>
<option value = "d4"></option>
<option value = "d5"></option>
<option value = "d6"></option>
<option value = "d7"></option>
<option value = "d8"></option>
<option value = "d9"></option>
</select>

</form>

<script type = "text/javascript">

function populate() {
var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
var days = ["Sun","Mon","Tues","Wed","Thur","Fri","Sat"];
for (var i =0; i<10; i++) {
var nd = new Date();
nd.setMonth(nd.getMonth());
nd.setDate(nd.getDate() + i);
var mn = nd.getMonth();
var dy = nd.getDate();
var yy = nd.getFullYear();
var day = nd.getDay();

var d = days[day] + ", " + months[mn] + " " + dy + ", " + yy;
document.myform.datelist.options[i].text = d;
}
}

</script>

What I need from Javascript is to not allow a past date selected, but not for data validation. A Javascript date picker I have used before can be configured to meet this requirement. Since it is weak on UI and positioning, I would like to try another version for my current task.

Old Pedant
07-30-2009, 12:06 AM
What does "not for data validation" mean???

A date picker pretty much automatically does "data validation", since the user *CAN'T* pick a bad date. So maybe your comment doesn't matter. But I don't understand what it's supposed to mean.

Altering most date pickers to not allow dates in the past is pretty easy, but with my particular picker it would be a tiny bit tougher. Because I allow the user a <select> for both the month and year, I'd have to disallow a prior month unless a future year had already been chosen. But that might be annoying to the person who wanted to click on (say) "January" and then "2012". He/she would be forced to pick the "2012" first, else he'd never see "January" as an option.

How far in the future do you want to allow the dates to go??? If never more than one or two years, I'd obviate all this by making the <select> choose both month and year at the same time.

jmrker
07-30-2009, 12:35 AM
I have tested your code. It is quite good:thumbsup: I have a suggestion on the UI. It would be better if the date colour will be changed when mouse-over. I haven't studied your code yet and I don't know how easy to make this enhancement. Again, I haven't studied your code. I don't know whether it can be configured so that only the current and future date can be picked and the second date can't later than the first date.

Thanks!

I'm not sure I understand the last sentence.

1. You want the first date to be today or later. TRUE?
2. You want the second date to be always be equal to or later than the first date. TRUE?

3. But you say the second date can't be later than the first date.
What does that mean? Must only be the first date, but not later?
If true then why have two calendars then?

What are the real specifications?



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum