Maternity Care Calendar 2011
Updated to push and pull EDD and LMP measurements to and from Oscar Measurements
MaternityCalender.html
—
HTML,
86Kb
File contents
<html>
<head>
<title>Maternity Care Calendar</title>
<!-- CSS Script that removes textarea and textbox borders when printing ---(put this inbetween <header></header>)----------------->
<style type="text/css" media="print">
.DoNotPrint {
display: none;
}
input.noborder {
border : 0px;
background: transparent;
}
textarea.noborder {
scrollbar-3dlight-color: transparent;
scrollbar-3dlight-color: transparent;
scrollbar-arrow-color: transparent;
scrollbar-base-color: transparent;
scrollbar-darkshadow-color: transparent;
scrollbar-face-color: transparent;
scrollbar-highlight-color: transparent;
scrollbar-shadow-color: transparent;
scrollbar-track-color: transparent;
background: transparent;
overflow: hidden;
border : 0px;
}
</style>
<style type="text/css" >
p, input
{
font-family: arial, sans-serif;
font-size: 10;
}
</style>
<script type="text/javascript">
var calendarLMP, calendarEDDDates, calendarEDDUS, calendarToday, calendarGA, calendarUS1, calendarUS2; /*must be declared in global scope*/
/*put the calendar initializations in the window's onload() method*/
window.onload = function() {
calendarLMP = new Epoch('CalLMP','popup',document.getElementById('LMP'),false);
calendarEDDDates = new Epoch('CalEDDDates','popup',document.getElementById('EDDDates'),false);
calendarEDDUS = new Epoch('CalEDDUS','popup',document.getElementById('EDDUS'),false);
calendarToday = new Epoch('CalToday','popup',document.getElementById('CurrentDate'),false);
calendarGA = new Epoch('CalGA','popup',document.getElementById('GADate'),false);
calendarUS1 = new Epoch('CalUS1','popup',document.getElementById('US1Date'),false);
calendarUS2 = new Epoch('CalUS2','popup',document.getElementById('US2Date'),false);
fillToday();
highlightEDD();
};
</script>
<style type="text/css">
/*!!
Epoch DHTML JavaScript Calendar - Version 2.0.2
English Edition
CSS Style File
(c) 2006-2007 MeanFreePath
Free for NON-COMMERCIAL use - see website for details and updates
http://www.meanfreepath.com/javascript_calendar/index.html
!!*/
table.calendar {
font-family: Helvetica, Arial, sans-serif;
font-size: 0.8em;
border-collapse: collapse;
background-color: white;
border: solid #999999 1px;
background-color: white;
width: 215px;
text-align: center;
/*prevent user from selecting text in Mozilla & Safari - check calendar constructor for IE code)*/
-moz-user-select: none;
/*-khtml-user-select: none;*/
}
table.calendar a {
}
table.calendar a:hover {
}
table.calendar input, table.calendar select {
font-size: 10px;
}
table.calendar td, table.calendar th {
border: 0;
font-size: 10px;
text-align: center;
}
div.mainheading {
margin: 2px;
}
.closeBtn {
/*float: right;
width: 15px;
/*font-size: 1.5em;
height: 13px;
padding: 0 0 3px 0;
margin: 1px 8px 0 0;
border: solid black 1px;*/
}
/*all styles related to the main calendar grid*/
table.cells {
border-collapse: collapse;
border: solid #CCCCCC 1px;
cursor: pointer;
empty-cells: show;
margin: 0 6px 0 6px;
}
/*the day headings*/
table.cells th {
border: solid #CCCCCC 1px;
text-align: left;
font-weight: bold;
color: #0054E3;
width: 22px;
}
table.cells th.wkhead {
border-right: double #CCCCCC 3px;
cursor: default;
width: 22px;
}
/*The date cells*/
table.cells td {
border: solid #CCCCCC 1px;
vertical-align: top;
text-align: left;
font-weight: bold;
height: 20px; /*IE doesn't like ems*/
}
table.cells td.wkhead {
background-color: white;
text-align: center;
border-right: double #CCCCCC 3px;
color: #0054E3;
}
table.cells td.noselect {
background-color: #EEEEEE;
color: #BBBBBB;
text-decoration: line-through;
cursor: default;
}
table.cells td.hlday {
background-color: #99FF99;
}
table.cells td.wkday {
background-color: #DDDDDD;
}
table.cells td.wkend {
background-color: #DDDDDD;
}
table.cells td.curdate {
background-color: #AAAADD;
}
table.cells td.cell_selected {
background-color: #99CCFF;
color: black;
}
table.cells td.notmnth {
background-color: #FFFFFF;
color: #CCCCCC;
}
table.cells td.notallowed {
background-color: white;
color: #EEEEEE;
font-style: italic;
}
table.cells td.hover {
background-color: #999999;
}
table.cells td div {
padding: 1px;
margin: 0;
}
</style>
<script type="text/javascript">
/*!!
Epoch DHTML JavaScript Calendar - Version 2.0.2
English Edition
Primary JavaScript File
(c) 2006-2007 MeanFreePath
Free for NON-COMMERCIAL use - see website for details and updates
http://www.meanfreepath.com/javascript_calendar/index.html
!!*/
/**
* The main Epoch class. All publicly-accessible methods and properties are called from this class
*/
function Epoch(name,mode,targetelement,multiselect) {
var self = this; //workaround due to varying definitions of "this" in variable scopes. see http://www.meanfreepath.com/support/epoch/epoch.html#self for details
//DEFINE PRIVATE METHODS
//-----------------------------------------------------------------------------
/**
* Declares and initializes the calendar variables. All the variables here can be safely changed
* (within reason ;) by the developer
*/
function calConfig() {
self.versionNumber = '2.0.2';
self.displayYearInitial = self.curDate.getFullYear(); //the initial year to display on load
self.displayMonthInitial = self.curDate.getMonth(); //the initial month to display on load (0-11)
self.displayYear = self.displayYearInitial;
self.displayMonth = self.displayMonthInitial;
self.minDate = new Date(2006,0,1);
self.maxDate = new Date(2012,11,31);
self.startDay = 0; // the day the week will 'start' on: 0(Sun) to 6(Sat)
self.showWeeks = true; //whether the week numbers will be shown
self.selCurMonthOnly = true; //allow user to only select dates in the currently displayed month
}
//-----------------------------------------------------------------------------
/**
* All language settings for Epoch are made here.
* Check Date.dateFormat() for the Date object's language settings
*/
function setLang() {
self.daylist = new Array('S','M','T','W','T','F','S','S','M','T','W','T','F','S');
self.months_sh = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
self.monthup_title = 'Go to the next month';
self.monthdn_title = 'Go to the previous month';
self.clearbtn_caption = 'Clear';
self.clearbtn_title = 'Clears any dates selected on the calendar';
self.maxrange_caption = 'This is the maximum range';
self.closebtn_caption = 'Close';
self.closebtn_title = 'Close the calendar';
}
//-----------------------------------------------------------------------------
/**
* Initializes the standard Gregorian Calendar parameters
*/
function setDays() {
self.daynames = new Array();
var j=0;
for(var i=self.startDay;i<self.startDay + 7;i++) {
self.daynames[j++] = self.daylist[i];
}
self.monthDayCount = new Array(31,((self.curDate.getFullYear() - 2000) % 4 ? 28 : 29),31,30,31,30,31,31,30,31,30,31);
}
//-----------------------------------------------------------------------------
/**
* Creates the full DOM implementation of the calendar
*/
function createCalendar() {
var tbody, tr, td;
self.calendar = document.createElement('table');
self.calendar.setAttribute('id',self.name+'_calendar');
setClass(self.calendar,'calendar');
self.calendar.style.display = 'none'; //default to invisible
//to prevent IE from selecting text when clicking on the calendar
addEventHandler(self.calendar,'selectstart', function() {return false;});
addEventHandler(self.calendar,'drag', function() {return false;});
tbody = document.createElement('tbody');
//create the Main Calendar Heading
tr = document.createElement('tr');
td = document.createElement('td');
td.appendChild(createMainHeading());
tr.appendChild(td);
tbody.appendChild(tr);
//create the calendar Day Heading & the calendar Day Cells
tr = document.createElement('tr');
td = document.createElement('td');
self.calendar.celltable = document.createElement('table');
setClass(self.calendar.celltable,'cells');
self.calendar.celltable.appendChild(createDayHeading());
self.calendar.celltable.appendChild(createCalCells());
td.appendChild(self.calendar.celltable);
tr.appendChild(td);
tbody.appendChild(tr);
//create the calendar footer
tr = document.createElement('tr');
td = document.createElement('td');
td.appendChild(createFooter());
tr.appendChild(td);
tbody.appendChild(tr);
//add the tbody element to the main calendar table
self.calendar.appendChild(tbody);
//and add the onmouseover events to the calendar table
addEventHandler(self.calendar,'mouseover',cal_onmouseover);
addEventHandler(self.calendar,'mouseout',cal_onmouseout);
}
//-----------------------------------------------------------------------------
/**
* Creates the primary calendar heading, with months & years
*/
function createMainHeading() {
//create the containing <div> element
var container = document.createElement('div');
setClass(container,'mainheading');
//create the child elements and other variables
self.monthSelect = document.createElement('select');
self.yearSelect = document.createElement('select');
var monthDn = document.createElement('input'), monthUp = document.createElement('input');
var opt, i;
//fill the month select box
for(i=0;i<12;i++) {
opt = document.createElement('option');
opt.setAttribute('value',i);
if(self.displayMonth == i) {
opt.setAttribute('selected','selected');
}
opt.appendChild(document.createTextNode(self.months_sh[i]));
self.monthSelect.appendChild(opt);
}
//and fill the year select box
var yrMax = self.maxDate.getFullYear(), yrMin = self.minDate.getFullYear();
for(i=yrMin;i<=yrMax;i++) {
opt = document.createElement('option');
opt.setAttribute('value',i);
if(self.displayYear == i) {
opt.setAttribute('selected','selected');
}
opt.appendChild(document.createTextNode(i));
self.yearSelect.appendChild(opt);
}
//add the appropriate children for the month buttons
monthUp.setAttribute('type','button');
monthUp.setAttribute('value','>');
monthUp.setAttribute('title',self.monthup_title);
monthDn.setAttribute('type','button');
monthDn.setAttribute('value','<');
monthDn.setAttribute('title',self.monthdn_title);
self.monthSelect.owner = self.yearSelect.owner = monthUp.owner = monthDn.owner = self; //hack to allow us to access self calendar in the events (<fix>??)
//assign the event handlers for the controls
function selectonchange() {
if(self.goToMonth(self.yearSelect.value,self.monthSelect.value)) {
self.displayMonth = self.monthSelect.value;
self.displayYear = self.yearSelect.value;
}
else {
self.monthSelect.value = self.displayMonth;
self.yearSelect.value = self.displayYear;
}
}
addEventHandler(monthUp,'click',function(){self.nextMonth();});
addEventHandler(monthDn,'click',function(){self.prevMonth();});
addEventHandler(self.monthSelect,'change',selectonchange);
addEventHandler(self.yearSelect,'change',selectonchange);
//and finally add the elements to the containing div
container.appendChild(monthDn);
container.appendChild(self.monthSelect);
container.appendChild(self.yearSelect);
container.appendChild(monthUp);
return container;
}
//-----------------------------------------------------------------------------
/**
* Creates the footer of the calendar - goes under the calendar cells
*/
function createFooter() {
var container = document.createElement('div');
var clearSelected = document.createElement('input');
clearSelected.setAttribute('type','button');
clearSelected.setAttribute('value',self.clearbtn_caption);
clearSelected.setAttribute('title',self.clearbtn_title);
clearSelected.owner = self;
addEventHandler(clearSelected,'click',function() {self.resetSelections(false);});
container.appendChild(clearSelected);
if(self.mode == 'popup') {
var closeBtn = document.createElement('input');
closeBtn.setAttribute('type','button');
closeBtn.setAttribute('value',self.closebtn_caption);
closeBtn.setAttribute('title',self.closebtn_title);
addEventHandler(closeBtn,'click',function(){self.hide();});
setClass(closeBtn,'closeBtn');
container.appendChild(closeBtn);
}
return container;
}
//-----------------------------------------------------------------------------
/**
* Creates the heading containing the day names
*/
function createDayHeading() {
//create the table element
self.calHeading = document.createElement('thead');
setClass(self.calHeading,'caldayheading');
var tr = document.createElement('tr'), th;
self.cols = new Array(false,false,false,false,false,false,false);
//if we're showing the week headings, create an empty <td> for filler
if(self.showWeeks) {
th = document.createElement('th');
setClass(th,'wkhead');
tr.appendChild(th);
}
//populate the day titles
for(var dow=0;dow<7;dow++) {
th = document.createElement('th');
th.appendChild(document.createTextNode(self.daynames[dow]));
if(self.selectMultiple) { //if selectMultiple is true, assign the cell a CalHeading Object to handle all events
th.headObj = new CalHeading(self,th,(dow + self.startDay < 7 ? dow + self.startDay : dow + self.startDay - 7));
}
tr.appendChild(th);
}
self.calHeading.appendChild(tr);
return self.calHeading;
}
//-----------------------------------------------------------------------------
/**
* Creates the table containing the calendar day cells
*/
function createCalCells() {
self.rows = new Array(false,false,false,false,false,false);
self.cells = new Array();
var row = -1, totalCells = (self.showWeeks ? 48 : 42);
var beginDate = new Date(self.displayYear,self.displayMonth,1);
var endDate = new Date(self.displayYear,self.displayMonth,self.monthDayCount[self.displayMonth]);
var sdt = new Date(beginDate);
sdt.setDate(sdt.getDate() + (self.startDay - beginDate.getDay()) - (self.startDay - beginDate.getDay() > 0 ? 7 : 0) );
//create the table element to hold the cells
self.calCells = document.createElement('tbody');
var tr,td;
var cellIdx = 0, cell, week, dayval;
for(var i=0;i<totalCells;i++) {
if(self.showWeeks) { //if we are showing the week headings
if(i % 8 == 0) {
row++;
week = sdt.getWeek(self.startDay);
tr = document.createElement('tr');
td = document.createElement('td');
if(self.selectMultiple) { //if selectMultiple is enabled, create the associated weekObj objects
td.weekObj = new WeekHeading(self,td,week,row)
}
else {//otherwise just set the class of the td for consistent look
setClass(td,'wkhead');
}
td.appendChild(document.createTextNode(week));
tr.appendChild(td);
i++;
}
}
else if(i % 7 == 0) { //otherwise, new row every 7 cells
row++;
week = sdt.getWeek(self.startDay);
tr = document.createElement('tr');
}
//create the day cells
dayval = sdt.getDate();
td = document.createElement('td');
td.appendChild(document.createTextNode(dayval));
cell = new CalCell(self,td,sdt,row,week);//,'normal',sdt.getTime() >= self.minDate.getTime() && sdt.getTime() <= self.maxDate.getTime());
self.cells[cellIdx] = cell;
td.cellObj = cell;
tr.appendChild(td);
self.calCells.appendChild(tr);
self.reDraw(cellIdx++); //and paint the cell according to its properties
sdt.setDate(dayval + 1); //increment the date
}
return self.calCells;
}
//-----------------------------------------------------------------------------
/**
* Runs all the operations necessary to change the mode of the calendar
* @param HTMLInputElement targetelement
*/
function setMode(targetelement) {
if(self.mode == 'popup') { //set positioning to absolute for popup
self.calendar.style.position = 'absolute';
}
//if a target element has been set, append the calendar to it
if(targetelement) {
switch(self.mode) {
case 'flat':
self.tgt = targetelement;
self.tgt.appendChild(self.calendar);
self.visible = true;
break;
case 'popup':
self.calendar.style.position = 'absolute';
document.body.appendChild(self.calendar);
self.setTarget(targetelement,false);
break;
}
}
else { //otherwise, add the calendar to the document.body (useful if targetelement will not be defined until after the calendar is initialized)
document.body.appendChild(self.calendar);
self.visible = false;
}
}
//-----------------------------------------------------------------------------
/**
* Removes the calendar table cells from the DOM (does not delete the cell objects associated with them)
*/
function deleteCells() {
self.calendar.celltable.removeChild(self.calendar.celltable.childNodes[1]); //remove the tbody element from the cell table
}
//-----------------------------------------------------------------------------
/**
* Sets the CSS class of the element, W3C & IE
* @param HTMLElement element
* @param string className
*/
function setClass(element,className) {
element.setAttribute('class',className);
element.setAttribute('className',className); //<iehack>
}
/**
* Updates a cell's data, including css class and selection properties
* @param int cellindex
*/
function setCellProperties(cellindex) {
var cell = self.cells[cellindex];
var date;
idx = self.dateInArray(self.dates,cell.date);
if(idx > -1) {
date = self.dates[idx]; //reduce indirection
cell.date.selected = date.selected || false;
cell.date.type = date.type;
cell.date.canSelect = date.canSelect;
cell.setTitle(date.title);
cell.setURL(date.href);
cell.setHTML(date.cellHTML);
}
else {
cell.date.selected = false; //if the cell's date isn't in the dates array, set it's selected value to false
}
//make all cells lying outside the min and max dates un-selectable
if(cell.date.getTime() < self.minDate.getTime() || cell.date.getTime() > self.maxDate.getTime()) {
cell.date.canSelect = false;
}
cell.setClass();
}
//-----------------------------------------------------------------------------
function cal_onmouseover() {
self.mousein = true;
}
//-----------------------------------------------------------------------------
function cal_onmouseout() {
self.mousein = false;
}
//-----------------------------------------------------------------------------
/**
* Updates the calendar's selectedDates pointer array
*/
function updateSelectedDates() {
var idx = 0;
self.selectedDates = new Array();
for(i=0;i<self.dates.length;i++) {
if(self.dates[i].selected) {
self.selectedDates[idx++] = self.dates[i];
}
}
}
//PUBLIC METHODS
//-----------------------------------------------------------------------------
/**
* Find a date in the given array, returning its index if found, -1 if not
* @param array arr
* @param Date searchVal
* @param int startIndex
* @return int
*/
self.dateInArray = function(arr,searchVal,startIndex) {
startIndex = (startIndex != null ? startIndex : 0); //default startIndex to 0, if not set
for(var i=startIndex;i<arr.length;i++) {
if(searchVal.getUeDay() == arr[i].getUeDay()) {
return i;
}
}
return -1;
};
//-----------------------------------------------------------------------------
/**
* Changes the target element of this calendar to another input.
* Many thanks to Jake Olefsky - jake@olefsky.com
* @param HTMLInputElement targetelement
* @param bool focus
*/
self.setTarget = function (targetelement, focus)
{
//if this is a popup calendar
if(self.mode == 'popup') {
//declare the event handlers for the target element
function popupFocus() {
self.show();
}
function popupBlur() {
if(!self.mousein){
self.hide();
}
}
function popupKeyDown() {
self.hide();
}
//unset old target element event handlers (if there is one yet)
if(self.tgt) {
removeEventHandler(self.tgt,'focus',popupFocus);
removeEventHandler(self.tgt,'blur',popupBlur);
removeEventHandler(self.tgt,'keydown',popupKeyDown);
}
//and set the new target element
self.tgt = targetelement;
//create a pointer to the INPUT's date object and init the new data array
var dto = self.tgt.dateObj,pdateArr = new Array;
//if a date is set for the target element
if(dto) {
if(self.tgt.value.length) { //load it into the calendar...
pdateArr[0] = dto;
}
self.goToMonth(dto.getFullYear(),dto.getMonth()); //...and go to the target's month/year
}
self.selectDates(pdateArr,true,true,true);
self.topOffset = self.tgt.offsetHeight; // the vertical distance (in pixels) to display the calendar from the Top of its input element
self.leftOffset = 0; // the horizontal distance (in pixels) to display the calendar from the Left of its input element
self.updatePos(self.tgt);
//and add the event handlers to the new element
addEventHandler(self.tgt,'focus',popupFocus);
addEventHandler(self.tgt,'blur',popupBlur);
addEventHandler(self.tgt,'keydown',popupKeyDown);
if(focus !== false) { //focus the target element immediately, unless otherwise specified
popupFocus();
}
}
else { //if this is a flat or inline calendar
//if the target is already set, remove the calendar's DOM representation from it
if(self.tgt) {
self.tgt.removeChild(self.calendar);
}
//now, set the calendar's target to the new target element, and show the calendar
self.tgt = targetelement;
self.tgt.appendChild(self.calendar);
self.show();
}
};
//-----------------------------------------------------------------------------
/**
* Go to the next month. if the month is December, go to January of the next year
* Returns true if the month will be incremented
* @return bool
*/
self.nextMonth = function () {
var month = self.displayMonth;
var year = self.displayYear;
//increment the month/year values, provided they're within the min/max ranges
if(self.displayMonth < 11) { //i.e. if currently in the year
month++;
}
else if(self.yearSelect.value < self.maxDate.getFullYear()) { //if not, increment the year as well
month = 0;
year++;
}
return self.goToMonth(year,month);
};
//-----------------------------------------------------------------------------
/**
* Go to the previous month - if the month is January, go to December of the previous year.
* Returns true if the month will be decremented
* @return bool
*/
self.prevMonth = function () {
var month = self.displayMonth;
var year = self.displayYear;
//increment the month/year values, provided they're within the min/max ranges
if(self.displayMonth > 0) { //i.e. if currently in the year
month--;
}
else { //if not, decrement the year as well
month = 11;
year--;
}
return self.goToMonth(year,month);
};
//-----------------------------------------------------------------------------
/**
* Sets the calendar to display the requested month/year, returning true if the
* date is within the minimum and maximum allowed dates
* @param int year
* @param int month
* @return bool
*/
self.goToMonth = function (year,month) {
var testdatemin = new Date(year, month, 31);
var testdatemax = new Date(year, month, 1);
if(testdatemin >= self.minDate && testdatemax <= self.maxDate) {
self.monthSelect.value = self.displayMonth = month;
self.yearSelect.value = self.displayYear = year;
//recreate the calendar for the new month
createCalCells();
deleteCells();
self.calendar.celltable.appendChild(self.calCells);
return true;
}
else {
alert(self.maxrange_caption);
return false;
}
};
//-----------------------------------------------------------------------------
/**
* Moves the calendar's position to the target element's location (popup mode only)
*/
self.updatePos = function (target) {
if(self.mode == 'popup') {
self.calendar.style.top = getTop(target) + self.topOffset + 'px';
self.calendar.style.left = getLeft(target) + self.leftOffset + 'px';
}
};
//-----------------------------------------------------------------------------
/**
* Displays the calendar
*/
self.show = function () {
self.updatePos(self.tgt); //update the calendar position, in case the page layout has changed since loading
self.calendar.style.display = 'block'; //'table'; //<iehack> 'table' is the W3C-recommended spec, but IE isn't a fan of those
self.visible = true;
};
//-----------------------------------------------------------------------------
/**
* Hides the calendar
*/
self.hide = function () {
self.calendar.style.display = 'none';
self.visible = false;
};
//-----------------------------------------------------------------------------
/**
* Toggles (shows/hides) the calendar depending on its current state
*/
self.toggle = function () {
self.visible ? self.hide() : self.show();
};
//-----------------------------------------------------------------------------
/**
* Adds the array "dates" to the calendar's dates array, removing duplicate dates,
* and redraws the calendar if redraw is true
* @param array dates
* @param bool redraw
*/
self.addDates = function (dates,redraw) {
var i;
for(i=0;i<dates.length;i++) {
if(self.dateInArray(self.dates,dates[i]) == -1) { //if the date isn't already in the array, add it!
self.dates[self.dates.length] = dates[i];
}
}
//now rebuild the selectedDates pointer array
updateSelectedDates();
if(redraw != false) { //redraw the calendar if "redraw" is false or undefined
self.reDraw();
}
};
//-----------------------------------------------------------------------------
/**
* Removes the dates from the calendar's dates array and redraws the calendar
* if redraw is true
* @param array dates
* @param bool redraw
*/
self.removeDates = function (dates,redraw) {
var idx;
for(var i=0;i<dates.length;i++) {
idx = self.dateInArray(self.dates,dates[i]);
if(idx != -1) { //search for the dates in the dates array, removing them if the dates match
self.dates.splice(idx,1);
}
}
updateSelectedDates();
if(redraw != false) { //redraw the calendar if "redraw" is true or undefined
self.reDraw();
}
};
//-----------------------------------------------------------------------------
/**
* Selects or Deselects an array of dates
* @param Array inpdates
* @param bool selectVal
* @param bool redraw
* @param bool removeothers
*/
self.selectDates = function (inpdates,selectVal,redraw,removeothers) {
var i, idx;
if(removeothers == true) {
for(i=0;i<self.dates.length;i++) {
self.dates[i].selected = false;
}
}
for(i=0;i<inpdates.length;i++) {
idx = self.dateInArray(self.dates,inpdates[i]);
if(selectVal == true) {
inpdates[i].selected = true;
if(idx == -1) { //if the date does not exist in the calendar's dates array, add it
self.dates[self.dates.length] = inpdates[i];
}
else { //if not, just select it
self.dates[idx].selected = true;
}
}
else { //if deselecting...
if(idx > -1) { //if the date is found, deselect and/or remove it from the calendar's dates array
self.dates[idx].selected = inpdates[i].selected = false;
if(self.dates[idx].type == 'normal') { //remove 'normal' dates from the dates array, since they're useless unless selected
self.dates.splice(idx,1);
}
}
}
}
//now rebuild the selectedDates pointer array
updateSelectedDates();
if(redraw != false) { //redraw the calendar if "redraw" is false or undefined
self.reDraw();
}
};
//-----------------------------------------------------------------------------
/**
* Adds the dates in dates as hidden inputs to the form "form". inputname
* is the name of each hidden element. "form" can either be a pointer to the form's
* DOM element or its id string.
* @param mixed form
* @param string inputname
*/
self.sendForm = function(form,inputname) {
var inpname = inputname || 'epochdates', f, inp;
f = (typeof(form) == 'string' ? document.getElementById(form) : form);
if(!f) {
alert('ERROR: Invalid form input');
return false;
}
for(var i=0;i<self.dates.length;i++) {
inp = document.createElement('input');
inp.setAttribute('type','hidden');
inp.setAttribute('name',inpname + '['+i+']');
inp.setAttribute('value',encodeURIComponent(self.dates[i].dateFormat('Y-m-d'))); //default to the ISO date format
f.appendChild(inp);
}
return true;
};
//-----------------------------------------------------------------------------
/**
* Erases the dates array and resets the calendar's selection variables to defaults.
* If retMonth is true, the calendar will return to the initial default month/year
* @param bool retMonth
*/
self.resetSelections = function (retMonth) {
var dateArray = new Array();
var dt = self.dates;
for(var i=0;i<dt.length;i++) {
if(dt[i].selected) {
dateArray[dateArray.length] = dt[i];
}
}
self.selectDates(dateArray,false,false);
self.rows = new Array(false,false,false,false,false,false,false);
self.cols = new Array(false,false,false,false,false,false,false);
if(self.mode == 'popup') { //hide the calendar and clear the input element if in popup mode
self.tgt.value = '';
self.hide();
}
retMonth == true ? self.goToMonth(self.displayYearInitial,self.displayMonthInitial) : self.reDraw();
};
//-----------------------------------------------------------------------------
/**
* Reapplies all the CSS classes for the calendar cells - usually called after changing their state
* If index is specified, it will redraw that cell only.
* @param int index
*/
self.reDraw = function (index) {
self.state = 1;
var len = index ? index + 1 : self.cells.length;
for(var i = index || 0;i<len;i++) {
setCellProperties(i);
}
self.state = 2;
};
//-----------------------------------------------------------------------------
/**
* Returns the index of the cell whose date value matches "date", or -1 if not found
* @param Date date
* @return int
*/
self.getCellIndex = function(date) {
for(var i=0;i<self.cells.length;i++) {
if(self.cells[i].date.getUeDay() == date.getUeDay()) {
return i;
}
}
return -1;
};
//-----------------------------------------------------------------------------
//begin constructor code:
//PUBLIC VARIABLES
self.state = 0;
self.name = name;
self.curDate = new Date();
self.mode = mode;
self.selectMultiple = (multiselect == true); //'false' if not true or not set at all
//the various calendar variables
self.dates = new Array();
self.selectedDates = new Array();
self.calendar;
self.calHeading;
self.calCells;
self.rows;
self.cols;
self.cells = new Array();
//The controls
self.monthSelect;
self.yearSelect;
self.mousein = false;
//Initialize the calendar and its variables{
calConfig();
setLang();
setDays();
createCalendar(); //create the calendar DOM element and its children, and their related objects
targetelement = typeof(targetelement) == 'string' ? document.getElementById(targetelement) : targetelement;
setMode(targetelement);
self.state = 2; //0: initializing, 1: redrawing, 2: finished!
self.visible ? self.show() : self.hide();
}
//-----------------------------------------------------------------------------
/*****************************************************************************/
/**
* Object that contains the methods and properties for the calendar day headings
*/
function CalHeading(owner,tableCell,dayOfWeek) {
//-----------------------------------------------------------------------------
function DayHeadingonclick() {//selects/deselects the days for this object's day of week
//reduce indirection:
var sdates = owner.dates;
var cells = owner.cells;
var dateArray = new Array();
owner.cols[dayOfWeek] = !owner.cols[dayOfWeek];
for(var i=0;i<cells.length;i++) { //cycle through all the cells in the calendar, selecting all cells with the same dayOfWeek as this heading
if(cells[i].dayOfWeek == dayOfWeek && cells[i].date.canSelect && (!owner.selCurMonthOnly || cells[i].date.getMonth() == owner.displayMonth && cells[i].date.getFullYear() == owner.displayYear)) { //if the cell's DoW matches, with other conditions
dateArray[dateArray.length] = cells[i].date;
}
}
owner.selectDates(dateArray,owner.cols[dayOfWeek],true);
}
//-----------------------------------------------------------------------------
var self = this;
self.dayOfWeek = dayOfWeek;
addEventHandler(tableCell,'mouseup',DayHeadingonclick);
}
/*****************************************************************************/
/**
* Object that contains the methods and properties for the calendar week headings
*/
function WeekHeading(owner,tableCell,week,tableRow) {
//-----------------------------------------------------------------------------
function weekHeadingonclick() {
//reduce indirection:
var cells = owner.cells;
var sdates = owner.dates;
var dateArray = new Array();
owner.rows[tableRow] = !owner.rows[tableRow];
for(var i=0;i<cells.length;i++) {
if(cells[i].tableRow == tableRow && cells[i].date.canSelect && (!owner.selCurMonthOnly || cells[i].date.getMonth() == owner.displayMonth && cells[i].date.getFullYear() == owner.displayYear)) { //if the cell's DoW matches, with other conditions)
dateArray[dateArray.length] = cells[i].date;
}
}
owner.selectDates(dateArray,owner.rows[tableRow],true);
}
//-----------------------------------------------------------------------------
var self = this;
self.week = week;
tableCell.setAttribute('class','wkhead');
tableCell.setAttribute('className','wkhead'); //<iehack>
addEventHandler(tableCell,'mouseup',weekHeadingonclick);
}
/*****************************************************************************/
/**
* Object that holds all data & code related to a calendar cell
*/
/**
* The CalCell constructor function
* @param Epoch owner
* @param HTMLTableCellElement tableCell
* @param Date dateObj
* @param int row
* @param int week
*/
function CalCell(owner,tableCell,dateObj,row,week) {
var self = this;
//-----------------------------------------------------------------------------
function calCellonclick() {
if(self.date.canSelect) {
if(owner.selectMultiple == true) { //if we can select multiple cells simultaneously, add the currently selected self's date to the dates array
owner.selectDates(new Array(self.date),!self.date.selected,false);
self.setClass(); //update the current cell's style to reflect the changes - a full redraw isn't necessary
}
else { //if we can only select one date at a time
owner.selectDates(new Array(self.date),true,false,true);
if(owner.mode == 'popup') { //update the target element's value and hide the calendar if in popup mode
owner.tgt.value = self.date.dateFormat(); //use the default date format defined in dateFormat
owner.tgt.dateObj = new Date(self.date); //add a Date object to the target element for later reference
owner.hide();
}
owner.reDraw(); //redraw all the calendar cells
}
}
}
//-----------------------------------------------------------------------------
/**
* Replicate the CSS :hover effect for non-supporting browsers <iehack>
*/
function calCellonmouseover() {
if(self.date.canSelect) {
tableCell.setAttribute('class',self.cellClass + ' hover');
tableCell.setAttribute('className',self.cellClass + ' hover');
}
}
//-----------------------------------------------------------------------------
/**
* Replicate the CSS :hover effect for non-supporting browsers <iehack>
*/
function calCellonmouseout() {
self.setClass();
}
//-----------------------------------------------------------------------------
/**
* Sets the CSS class of the cell based on the specified criteria
*/
self.setClass = function ()
{
if(self.date.canSelect !== false) {
if(self.date.selected) {
self.cellClass = 'cell_selected';
}
else if(owner.displayMonth != self.date.getMonth() ) {
self.cellClass = 'notmnth';
}
else if(self.date.type == 'holiday') {
self.cellClass = 'hlday';
}
else if(self.dayOfWeek > 0 && self.dayOfWeek < 6) {
self.cellClass = 'wkday';
}
else {
self.cellClass = 'wkend';
}
}
else {
self.cellClass = 'noselect';
}
//highlight the current date
if(self.date.getUeDay() == owner.curDate.getUeDay()) {
self.cellClass = self.cellClass + ' curdate';
}
tableCell.setAttribute('class',self.cellClass);
tableCell.setAttribute('className',self.cellClass); //<iehack>
};
//-----------------------------------------------------------------------------
/**
* Sets the cell's hyperlink, if declared
* @param string href
* @param string type ('anchor' or 'js' - default 'anchor')
*/
self.setURL = function(href,type) {
if(href) {
if(type == 'js') { //Make the WHOLE cell be a clickable link
addEventHandler(self.tableCell,'mousedown',function(){window.location.href = href;});
}
else { //make only the date number of the cell a clickable link:
var url = document.createElement('a');
url.setAttribute('href',href);
url.appendChild(document.createTextNode(self.date.getDate()));
self.tableCell.replaceChild(url,self.tableCell.firstChild); //assumes the first child of the cell DOM node is the date text
}
}
};
//-----------------------------------------------------------------------------
/**
* Sets the title (i.e. tooltip) that appears when a user holds their mouse cursor over a cell
* @param string titleStr
*/
self.setTitle = function(titleStr) {
if(titleStr && titleStr.length > 0) {
self.title = titleStr;
self.tableCell.setAttribute('title',titleStr);
}
};
//-----------------------------------------------------------------------------
/**
* Sets the internal html of the cell, using a string containing html markup
* @param string html
*/
self.setHTML = function(html) {
if(html && html.length > 0) {
if(self.tableCell.childNodes[1]) {
self.tableCell.childNodes[1].innerHTML = html;
}
else {
var htmlCont = document.createElement('div');
htmlCont.innerHTML = html;
self.tableCell.appendChild(htmlCont);
}
}
};
//-----------------------------------------------------------------------------
self.cellClass; //the CSS class of the cell
self.tableRow = row;
self.tableCell = tableCell;
self.date = new Date(dateObj);
self.date.canSelect = true; //whether this cell can be selected or not - always true unless set otherwise externally
self.date.type = 'normal'; //i.e. normal date, holiday, etc - always true unless set otherwise externally
self.date.selected = false; //whether the cell is selected (and is therefore stored in the owner's dates array)
self.date.cellHTML = '';
self.dayOfWeek = self.date.getDay();
self.week = week;
//assign the event handlers for the table cell element
addEventHandler(tableCell,'click', calCellonclick);
addEventHandler(tableCell,'mouseover', calCellonmouseover);
addEventHandler(tableCell,'mouseout', calCellonmouseout);
self.setClass();
}
/*****************************************************************************/
Date.prototype.getDayOfYear = function () //returns the day of the year for this date
{
return parseInt((this.getTime() - new Date(this.getFullYear(),0,1).getTime())/86400000 + 1);
};
//-----------------------------------------------------------------------------
/**
* Returns the week number for this date. dowOffset is the day of week the week
* "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
* the week returned is the ISO 8601 week number.
* @param int dowOffset
* @return int
*/
Date.prototype.getWeek = function (dowOffset) {
dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
var newYear = new Date(this.getFullYear(),0,1);
var day = newYear.getDay() - dowOffset; //the day of week the year begins on
day = (day >= 0 ? day : day + 7);
var weeknum, daynum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
//if the year starts before the middle of a week
if(day < 4) {
weeknum = Math.floor((daynum+day-1)/7) + 1;
if(weeknum > 52) {
nYear = new Date(this.getFullYear() + 1,0,1);
nday = nYear.getDay() - dowOffset;
nday = nday >= 0 ? nday : nday + 7;
weeknum = nday < 4 ? 1 : 53; //if the next year starts before the middle of the week, it is week #1 of that year
}
}
else {
weeknum = Math.floor((daynum+day-1)/7);
}
return weeknum;
};
//-----------------------------------------------------------------------------
Date.prototype.getUeDay = function () //returns the number of DAYS since the UNIX Epoch - good for comparing the date portion
{
return parseInt(Math.floor((this.getTime() - this.getTimezoneOffset() * 60000)/86400000)); //must take into account the local timezone
};
//-----------------------------------------------------------------------------
Date.prototype.dateFormat = function(format)
{
if(!format) { // the default date format to use - can be customized to the current locale
format = 'Y-m-d';
}
LZ = function(x) {return(x < 0 || x > 9 ? '' : '0') + x};
var MONTH_NAMES = new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
var result="";
var i_format=0;
var c="";
var token="";
var y=this.getFullYear().toString();
var M=this.getMonth()+1;
var d=this.getDate();
var E=this.getDay();
var H=this.getHours();
var m=this.getMinutes();
var s=this.getSeconds();
value = {
Y: y.toString(),
y: y.substring(2),
n: M,
m: LZ(M),
F: MONTH_NAMES[M-1],
M: MONTH_NAMES[M+11],
j: d,
d: LZ(d),
D: DAY_NAMES[E+7],
l: DAY_NAMES[E],
G: H,
H: LZ(H)
};
if (H==0) {value['g']=12;}
else if (H>12){value['g']=H-12;}
else {value['g']=H;}
value['h']=LZ(value['g']);
if (H > 11) {value['a']='pm'; value['A'] = 'PM';}
else { value['a']='am'; value['A'] = 'AM';}
value['i']=LZ(m);
value['s']=LZ(s);
//construct the result string
while (i_format < format.length) {
c=format.charAt(i_format);
token="";
while ((format.charAt(i_format)==c) && (i_format < format.length)) {
token += format.charAt(i_format++);
}
if (value[token] != null) { result=result + value[token]; }
else { result=result + token; }
}
return result;
};
/*****************************************************************************/
//-----------------------------------------------------------------------------
function addEventHandler(element, type, func) { //unfortunate hack to deal with Internet Explorer's horrible DOM event model <iehack>
if(element.addEventListener) {
element.addEventListener(type,func,false);
}
else if (element.attachEvent) {
element.attachEvent('on'+type,func);
}
}
//-----------------------------------------------------------------------------
function removeEventHandler(element, type, func) { //unfortunate hack to deal with Internet Explorer's horrible DOM event model <iehack>
if(element.removeEventListener) {
element.removeEventListener(type,func,false);
}
else if (element.attachEvent) {
element.detachEvent('on'+type,func);
}
}
//-----------------------------------------------------------------------------
function getTop(element) {//returns the absolute Top value of element, in pixels
var oNode = element;
var iTop = 0;
while(oNode.tagName != 'HTML') {
iTop += oNode.offsetTop || 0;
if(oNode.offsetParent) { //i.e. the parent element is not hidden
oNode = oNode.offsetParent;
}
else {
break;
}
}
return iTop;
}
//-----------------------------------------------------------------------------
function getLeft(element) { //returns the absolute Left value of element, in pixels
var oNode = element;
var iLeft = 0;
while(oNode.tagName != 'HTML') {
iLeft += oNode.offsetLeft || 0;
if(oNode.offsetParent) { //i.e. the parent element is not hidden
oNode = oNode.offsetParent;
}
else {
break;
}
}
return iLeft;
}
//-----------------------------------------------------------------------------
</script>
<script type="text/javascript">
/**
* Version: 1.0 Alpha-1
* Build Date: 13-Nov-2007
* Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
* License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
* Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
*/
Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
if(x.month||x.months){this.addMonths(x.month||x.months);}
if(x.year||x.years){this.addYears(x.year||x.years);}
if(x.day||x.days){this.addDays(x.day||x.days);}
return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
if(!x.second&&x.second!==0){x.second=-1;}
if(!x.minute&&x.minute!==0){x.minute=-1;}
if(!x.hour&&x.hour!==0){x.hour=-1;}
if(!x.day&&x.day!==0){x.day=-1;}
if(!x.month&&x.month!==0){x.month=-1;}
if(!x.year&&x.year!==0){x.year=-1;}
if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
if(x.timezone){this.setTimezone(x.timezone);}
if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
break;}
return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
rx.push(r[0]);s=r[1];}
return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
try{r=(px[i].call(this,s));}catch(e){r=null;}
if(r){return r;}}
throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
rx.push(r[0]);s=r[1];}
return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
s=q[1];}
if(!r){throw new $P.Exception(s);}
if(q){throw new $P.Exception(q[1]);}
if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
if(!last&&q[1].length===0){last=true;}
if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
if(rx[1].length<best[1].length){best=rx;}
if(best[1].length===0){break;}}
if(best[0].length===0){return best;}
if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
best[1]=q[1];}
return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
if(this.now){return new Date();}
var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
if(!this.unit){this.unit="day";}
if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
this[this.unit+"s"]=this.value*orient;}
return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
if(this.month&&!this.day){this.day=1;}
return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
fn=_C[keys]=_.any.apply(null,px);}
return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
</script>
<script type="text/javascript">
var EDD = "";
function fillToday(){
var t = Date.today().toString('yyyy-MM-dd');
document.getElementById('CurrentDate').value = t;
}
function highlightEDD(){
x = document.getElementById('EDDtype').value;
if (x == "LMP"){
document.getElementById('EDDDatesRow').style.background = 'yellow';
document.getElementById('EDDDatesRow').style.outline = ' thin solid black';
document.getElementById('EDDUS1Row').style.background = 'white';
document.getElementById('EDDUS1Row').style.outline = 'thin none black';
document.getElementById('EDDUS2Row').style.background = 'white';
document.getElementById('EDDUS2Row').style.outline = 'thin none black';
} else if (x == "US1"){
document.getElementById('EDDDatesRow').style.background = 'white';
document.getElementById('EDDDatesRow').style.outline = ' thin none black';
document.getElementById('EDDUS1Row').style.background = 'yellow';
document.getElementById('EDDUS1Row').style.outline = 'thin solid black';
document.getElementById('EDDUS2Row').style.background = 'white';
document.getElementById('EDDUS2Row').style.outline = 'thin none black';
} else if (x == "US2"){
document.getElementById('EDDDatesRow').style.background = 'white';
document.getElementById('EDDDatesRow').style.outline = ' thin none black';
document.getElementById('EDDUS1Row').style.background = 'white';
document.getElementById('EDDUS1Row').style.outline = 'thin none black';
document.getElementById('EDDUS2Row').style.background = 'yellow';
document.getElementById('EDDUS2Row').style.outline = 'thin solid black';
}else{
document.getElementById('EDDDatesRow').style.background = 'white';
document.getElementById('EDDDatesRow').style.outline = ' thin none black';
document.getElementById('EDDUS1Row').style.background = 'white';
document.getElementById('EDDUS1Row').style.outline = 'thin none black';
document.getElementById('EDDUS2Row').style.background = 'white';
document.getElementById('EDDUS2Row').style.outline = 'thin none black';
}
}
function calcEDD(){
var d1 = Date.parse(document.getElementById('LMP').value);
if (d1){
var d1EDD = d1.clone().addWeeks(40);
document.getElementById('EDDDates').value = d1EDD.toString('yyyy-MM-dd');
if (!d2 && !d3){
EDD = "LMP";
}
}
var d2 = Date.parse(document.getElementById('US1Date').value);
var d2Trimester = 0;
if (d2){
var US1Week = document.getElementById('US1Week').value;
if (!US1Week){ US1Week = 0};
var US1Day = document.getElementById('US1Day').value;
if (!US1Day) {US1Day = 0};
var d2DaysPassed = (parseInt(US1Week * 7)) + parseInt(US1Day);
if (d2DaysPassed < (14 * 7)){
d2Trimester = 1;
}else if (d2DaysPassed >= (14 * 7)){
d2Trimester = 2;
}
var d2DaysToEDD = 280 - d2DaysPassed;
var d2EDD = d2.clone().add({days:d2DaysToEDD});
document.getElementById('EDDUS1').value = d2EDD.toString('yyyy-MM-dd');
if (!d1 && !d3){
EDD = "US1";
}
if ((d1 && !d3)){
var diff = Math.abs(d1EDD - d2EDD); //in milliseconds
var diffDays = diff/1000/60/60/24; // in days
if (d2Trimester == 1){
if (diffDays > 5){
EDD = "US1";
} else if (diffDays <=5){
EDD = "LMP";
}
}else if (d2Trimester == 2){
if (diffDays > 10){
EDD = "US1";
} else if (diffDays <=10){
EDD = "LMP";
}
}
}
if (d3 && (d2<d3)){
var diff = Math.abs(d1EDD - d2EDD); //in milliseconds
var diffDays = diff/1000/60/60/24; // in days
if (d2Trimester == 1){
if (diffDays > 5){
EDD = "US1";
} else if (diffDays <=5){
EDD = "LMP";
}
}else if (d2Trimester == 2){
if (diffDays > 10){
EDD = "US1";
} else if (diffDays <=10){
EDD = "LMP";
}
}
}
}
var d3 = Date.parse(document.getElementById('US2Date').value);
var d3Trimester = 0;
if (d3){
var US2Week = document.getElementById('US2Week').value;
if (!US2Week){ US2Week = 0};
var US2Day = document.getElementById('US2Day').value;
if (!US2Day) {US2Day = 0};
var d3DaysPassed = (parseInt(US2Week)*7) + parseInt(US2Day);
if (d3DaysPassed < (14 * 7)){
d3Trimester = 1;
}else if (d3DaysPassed >= (14 * 7)){
d3Trimester = 2;
}
var d3DaysToEDD = 280 - d3DaysPassed;
var d3EDD = d3.clone().add({days:d3DaysToEDD});
document.getElementById('EDDUS2').value = d3EDD.toString('yyyy-MM-dd');
if (!d1 && !d2){
EDD = "US2";
}
if (d1 && !d2){
var diff = Math.abs(d1EDD - d3EDD); //in milliseconds
var diffDays = diff/1000/60/60/24; // in days
if (d3Trimester == 1){
if (diffDays > 5){
EDD = "US2";
} else if (diffDays <=5){
EDD = "LMP";
}
}else if (d3Trimester == 2){
if (diffDays > 10){
EDD = "US2";
} else if (diffDays <=10){
EDD = "LMP";
}
}
}
if (d2 && (d3<d2)){
var diff = Math.abs(d1EDD - d3EDD); //in milliseconds
var diffDays = diff/1000/60/60/24; // in days
if (d3Trimester == 1){
if (diffDays > 5){
EDD = "US2";
} else if (diffDays <=5){
EDD = "LMP";
}
}else if (d3Trimester == 2){
if (diffDays > 10){
EDD = "US2";
} else if (diffDays <=10){
EDD = "LMP";
}
}
}
}
if (EDD == "LMP"){
document.getElementById('EDDDate4').value = d1EDD.toString('yyyy-MM-dd');
}
if (EDD == "US1"){
document.getElementById('EDDDate4').value= d2EDD.toString('yyyy-MM-dd');
} if (EDD== "US2"){
document.getElementById('EDDDate4').value= d3EDD.toString('yyyy-MM-dd');
}
if (document.getElementById('LMP').value !== document.getElementById('LMPDate1').value){
document.getElementById('LMPDate2').value = d1.toString('yyyy-MM-dd');
}
if (document.getElementById('LMP').value == document.getElementById('LMPDate1').value){
document.getElementById('LMPDate2').value = "";
}
var d5 = Date.parse(document.getElementById('EDDDate4').value);
if (document.getElementById('EDDDate5').value !== document.getElementById('EDDDate4').value){
document.getElementById('EDDDate6').value = d5.toString('yyyy-MM-dd');
}
if (document.getElementById('EDDDate5').value == document.getElementById('EDDDate4').value){
document.getElementById('EDDDate6').value = "";
}
document.getElementById('EDDtype').value = EDD;
highlightEDD();
fillGA();
}
function fillGA(){
if (EDD == "LMP"){
var d2 = Date.parse(document.getElementById('EDDDates').value); //use EDD by Dates
}else if(EDD == "US1"){
var d2 = Date.parse(document.getElementById('EDDUS1').value); //use EDD by 1st trimester US
}else if(EDD == "US2"){
var d2 = Date.parse(document.getElementById('EDDUS2').value); //use EDD by 2nd trimester US
}
for (w = 0; w <= 42; w++){
var GAWeekLeft = parseInt(40 - w);
var DateAtGA = d2.clone().addWeeks(-GAWeekLeft).toString('ddd, MMM dd, yy');
var GAWeekInput = "Week" + w;
document.getElementById(GAWeekInput).value = DateAtGA;
}
}
</script>
</head>
<body>
<form method="post" action="" name="FormName">
<div style="position: absolute; top: 10px; left: 10px;">
<image src="${oscar_image_path}MaternityCareCalendar.png" width="750px" height="1000px">
</div>
<!-- You can remove ${oscar_image_path} as you develop the form, but make sure you put it back before uploading to OSCAR otherwise the image wouldn't show.
<!-- Also note: the image filename IS CASE SENSITIVE INCLUDING THE EXTENSION. It may work otherwise in Windows, but not in OSCAR because it's based on a Linux platform -->
<div style="position: absolute; top: 20px; left: 60px; width:120px">
<p>Name:<input type="text" name="PatientName" id="PatientName" oscarDB=patient_name class="noborder"></p>
<p>Today's Date(yyyy-mm-dd):<input type="text" name="CurrentDate" id="CurrentDate" class="noborder"></p>
<p>LMP:<input type="text" name="LMP" id="LMP" oscarDB=m$LMP#value class="noborder"></p>
<P>1st ultrasound on
<input type="text" name="US1Date" id="US1Date" class="noborder">:<br>
<input type="text" name="US1Week" id="US1Week" style="width:20px;" value="0" class="noborder">Weeks<input type="text" name="US1Day" id="US1Day" style="width:20px;" value="0" class="noborder">Days</p>
<p>2nd ultrasound on
<input type="text" name="US2Date" id="US2Date" class="noborder">:<br>
<input type="text" name="US2Week" id="US2Week" style="width:20px;" value="0" class="noborder">Weeks<input type="text" name="US2Day" id="US2Day" style="width:20px;" value="0" class="noborder">Days</p>
<p><input type="button" value="Calculate EDD" onClick="calcEDD();" class="DoNotPrint"></p>
<p>The most accurate EDD, as per <a href="http://www.sogc.org/guidelines/documents/gui214CPG0809.pdf" target="_new">SOGC guidelines</a>, is highlighted below.</p>
<table>
<tr id="EDDDatesRow">
<td><p>EDD by LMP:<input type="text" name="EDDDates" id="EDDDates" class="noborder"></p></td>
</tr>
<tr id="EDDUS1Row">
<td><p>EDD by 1st US:<input type="text" name="EDDUS1" id="EDDUS1" class="noborder"></p></td>
</tr>
<tr id="EDDUS2Row">
<td><p>EDD by 2nd US:<input type="text" name="EDDUS2" id="EDDUS2" class="noborder"></p></td>
</tr>
<input type="hidden" name="EDDtype" id="EDDtype">
<!--Measurement LMP-->
<tr id="LMPDateTest1">
<td><input class="nodisplay" type="hidden" name="LMPDate1" id = "LMPDate1" oscarDB=m$LMP#value ></td>
</tr>
<!--Output LMP-->
<tr id="LMPDateTest2">
<td><input class="nodisplay" type="hidden" name="m$LMP#value" id = "LMPDate2"></td>
</tr>
<!--Measurement EDD-->
<tr id="EDDDateTest5">
<td><input class="nodisplay" type="hidden" name="EDDDate5" id = "EDDDate5" oscarDB=m$EDD#value></td>
</tr>
<!--Calculated EDD-->
<tr id="EDDDateTest4">
<td><input class="nodisplay" type="hidden" name="EDDDate4" id = "EDDDate4"></td>
</tr>
<!-- Output EDD-->
<tr id="EDDDateTest6">
<td><input class="nodisplay" type="hidden" name="m$EDD#value" id = "EDDDate6"></td>
</tr>
</table>
</div>
<input name="Week0" id="Week0" type="text" class="noborder" style="position:absolute; top:54px; left:327px; width:100px;" >
<input name="Week1" id="Week1" type="text" class="noborder" style="position:absolute; top:75px; left:327px; width:100px;" >
<input name="Week2" id="Week2" type="text" class="noborder" style="position:absolute; top:96px; left:327px; width:100px;" >
<input name="Week3" id="Week3" type="text" class="noborder" style="position:absolute; top:117px; left:327px; width:100px;">
<input name="Week4" id="Week4" type="text" class="noborder" style="position:absolute; top:138px; left:327px; width:100px;">
<input name="Week5" id="Week5" type="text" class="noborder" style="position:absolute; top:159px; left:327px; width:100px;">
<input name="Week6" id="Week6" type="text" class="noborder" style="position:absolute; top:180px; left:327px; width:100px;">
<input name="Week7" id="Week7" type="text" class="noborder" style="position:absolute; top:201px; left:327px; width:100px;">
<input name="Week8" id="Week8" type="text" class="noborder" style="position:absolute; top:222px; left:327px; width:100px;">
<input name="Week9" id="Week9" type="text" class="noborder" style="position:absolute; top:243px; left:327px; width:100px;">
<input name="Week10" id="Week10" type="text" class="noborder" style="position:absolute; top:264px; left:327px; width:100px;">
<input name="Week11" id="Week11" type="text" class="noborder" style="position:absolute; top:285px; left:327px; width:100px;">
<input name="Week12" id="Week12" type="text" class="noborder" style="position:absolute; top:306px; left:327px; width:100px;">
<input name="Week13" id="Week13" type="text" class="noborder" style="position:absolute; top:327px; left:327px; width:100px;">
<input name="Week14" id="Week14" type="text" class="noborder" style="position:absolute; top:348px; left:327px; width:100px;">
<input name="Week15" id="Week15" type="text" class="noborder" style="position:absolute; top:369px; left:327px; width:100px;">
<input name="Week16" id="Week16" type="text" class="noborder" style="position:absolute; top:390px; left:327px; width:100px;">
<input name="Week17" id="Week17" type="text" class="noborder" style="position:absolute; top:411px; left:327px; width:100px;">
<input name="Week18" id="Week18" type="text" class="noborder" style="position:absolute; top:432px; left:327px; width:100px;">
<input name="Week19" id="Week19" type="text" class="noborder" style="position:absolute; top:453px; left:327px; width:100px;">
<input name="Week20" id="Week20" type="text" class="noborder" style="position:absolute; top:474px; left:327px; width:100px;">
<input name="Week21" id="Week21" type="text" class="noborder" style="position:absolute; top:495px; left:327px; width:100px;">
<input name="Week22" id="Week22" type="text" class="noborder" style="position:absolute; top:516px; left:327px; width:100px;">
<input name="Week23" id="Week23" type="text" class="noborder" style="position:absolute; top:537px; left:327px; width:100px;">
<input name="Week24" id="Week24" type="text" class="noborder" style="position:absolute; top:558px; left:327px; width:100px;">
<input name="Week25" id="Week25" type="text" class="noborder" style="position:absolute; top:579px; left:327px; width:100px;">
<input name="Week26" id="Week26" type="text" class="noborder" style="position:absolute; top:600px; left:327px; width:100px;">
<input name="Week27" id="Week27" type="text" class="noborder" style="position:absolute; top:621px; left:327px; width:100px;">
<input name="Week28" id="Week28" type="text" class="noborder" style="position:absolute; top:642px; left:327px; width:100px;">
<input name="Week29" id="Week29" type="text" class="noborder" style="position:absolute; top:663px; left:327px; width:100px;">
<input name="Week30" id="Week30" type="text" class="noborder" style="position:absolute; top:684px; left:327px; width:100px;">
<input name="Week31" id="Week31" type="text" class="noborder" style="position:absolute; top:705px; left:327px; width:100px;">
<input name="Week32" id="Week32" type="text" class="noborder" style="position:absolute; top:726px; left:327px; width:100px;">
<input name="Week33" id="Week33" type="text" class="noborder" style="position:absolute; top:747px; left:327px; width:100px;">
<input name="Week34" id="Week34" type="text" class="noborder" style="position:absolute; top:768px; left:327px; width:100px;">
<input name="Week35" id="Week35" type="text" class="noborder" style="position:absolute; top:789px; left:327px; width:100px;">
<input name="Week36" id="Week36" type="text" class="noborder" style="position:absolute; top:810px; left:327px; width:100px;">
<input name="Week37" id="Week37" type="text" class="noborder" style="position:absolute; top:832px; left:327px; width:100px;">
<input name="Week38" id="Week38" type="text" class="noborder" style="position:absolute; top:853px; left:327px; width:100px;">
<input name="Week39" id="Week39" type="text" class="noborder" style="position:absolute; top:874px; left:327px; width:100px;">
<input name="Week40" id="Week40" type="text" class="noborder" style="position:absolute; top:895px; left:327px; width:100px;">
<input name="Week41" id="Week41" type="text" class="noborder" style="position:absolute; top:916px; left:327px; width:100px;">
<input name="Week42" id="Week42" type="text" class="noborder" style="position:absolute; top:937px; left:327px; width:100px;">
<!-- The submit/print/reset buttons ------------------------------------------------------------->
<div class="DoNotPrint" style="position:absolute; top:1000px;">
<table>
<tr>
<td>
Subject: <input name="subject" size="40" type="text">
<input value="Submit" name="B1" type="submit">
<input value="Reset" name="B2" type="reset">
<input value="Print" onclick="window.print()" type="button">
<input value="Print and Submit" name="PrintSubmitButton" type="button" onClick="window.print(); document.FormName.submit()">
</td>
</tr>
</table>
</div>
</form>
<!-- ------End of submit/print/reset buttons----------------------------------------------------->
</body>
</html>

