Link to home
Start Free TrialLog in
Avatar of Melody Scott
Melody ScottFlag for United States of America

asked on

Need new calendar

Hi, experts! I am looking for a calendar, but it needs certain characteristics. The easiest way to explain is to have you go to my site, www dot magickitchen dot com. Please add something to the shopping cart and then enter a zip code and hit update.  You will see [Optional] Alternate expected delivery date: and a box. If you click on the box you can see the calendar we are using.

What we need is a calendar we can program to black out certain days (Basically the days we don't deliver on). So the customer won't be able to select Christmas Day, for instance. Right now they can select it, but the cart goes through some computations and selects the closest choice which we do deliver on. Obviously that's a little confusing for our customers at times.

I spoke to our programmer, and he gave me the specifics we need:

1. JS code not too big
2. Must work with IE 6+, firefox 1.5/2.x and safari
3. Must have an easy way to program what dates are not selectable from the calling api (i.e. not something we program in a static file or in the .js file itself as the holidays dates change from year to year.)
4. Has to be free or cheap to license for a whole server (or really cheap if licence by domain)

Thanks- I have also added the code that we are using now, <script src="/cart/js/cart/calendar.js"></script>
/* --- Swazz Javascript Calendar ---
/* --- v 1.0 3rd November 2006
By Oliver Bryant
http://calendar.swazz.org */
 
/* SCOOB HOWTO:
 Add these lines to your html code where you want an input for a date:
 
  <script src="calendar.js"></script>
   <input type="text" value="" onfocus="this.select();lcs(this)" onclick="event.cancelBubble=true;this.select();lcs(this)">
*/
 
/* --- SCOOB addition:  date format selection ---
   *** Just uncomment either the 'USA' or 'ISO' line below
   *** to override the default European date format
 */
var format='EU';   var separator='/';  // EU:   DD/MM/YYYY (DEFAULT FORMAT)
//  format='USA';  var separator='/';  // USA:  MM/DD/YYYY
  format='ISO';  var separator='-';  // ISO:  YYYY-MM-DD
 
 
function getObj(objID)
{
    if (document.getElementById) {return document.getElementById(objID);}
    else if (document.all) {return document.all[objID];}
    else if (document.layers) {return document.layers[objID];}
}
 
function checkClick(e) {
	e?evt=e:evt=event;
	CSE=evt.target?evt.target:evt.srcElement;
	if (getObj('fc'))
		if (!isChild(CSE,getObj('fc')))
			getObj('fc').style.display='none';
}
 
function isChild(s,d) {
	while(s) {
		if (s==d) 
			return true;
		s=s.parentNode;
	}
	return false;
}
 
function Left(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}
 
function Top(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
	
document.write('<table id="fc" style="position:absolute;border-collapse:collapse;background:#FFFFFF;border:1px solid #ABABAB;display:none" cellpadding=2>');
document.write('<tr><td style="cursor:pointer" onclick="csubm()"><img src="/img/cart/cal_arrowleftmonth.gif"></td><td colspan=5 id="mns" align="center" style="font:bold 13px Arial"></td><td align="right" style="cursor:pointer" onclick="caddm()"><img src="/img/cart/cal_arrowrightmonth.gif"></td></tr>');
document.write('<tr><td align=center style="background:#ABABAB;font:12px Arial">S</td><td align=center style="background:#ABABAB;font:12px Arial">M</td><td align=center style="background:#ABABAB;font:12px Arial">T</td><td align=center style="background:#ABABAB;font:12px Arial">W</td><td align=center style="background:#ABABAB;font:12px Arial">T</td><td align=center style="background:#ABABAB;font:12px Arial">F</td><td align=center style="background:#ABABAB;font:12px Arial">S</td></tr>');
for(var kk=1;kk<=6;kk++) {
	document.write('<tr>');
	for(var tt=1;tt<=7;tt++) {
		num=7 * (kk-1) - (-tt);
		document.write('<td id="v' + num + '" style="width:18px;height:18px">&nbsp;</td>');
	}
	document.write('</tr>');
}
document.write('</table>');
 
document.all?document.attachEvent('onclick',checkClick):document.addEventListener('click',checkClick,false);
 
 
// Calendar script
var now = new Date;
var sccm=now.getMonth();
var sccy=now.getFullYear();
var ccm=now.getMonth();
var ccy=now.getFullYear();
var ccd;                // SCOOB: new code
 
var updobj;
function lcs(ielem) {
	updobj=ielem;
	getObj('fc').style.left=Left(ielem);
	getObj('fc').style.top=Top(ielem)+ielem.offsetHeight;
	getObj('fc').style.display='';
	
	// First check date is valid
	curdt=ielem.value;
//	curdtarr=curdt.split('/');        // SCOOB old code:
	curdtarr=curdt.split(separator);  // SCOOB: new code
	isdt=true;
	for(var k=0;k<curdtarr.length;k++) {
		if (isNaN(curdtarr[k]))
			isdt=false;
	}
	if (isdt&(curdtarr.length==3)) {
 
// SCOOB: New code if/else if/else
	   if (format=='USA') {      // USA foramt:  MM/DD/YYYY
		ccm=curdtarr[0]-1;
	        ccd=curdtarr[1];
		ccy=curdtarr[2];
 
	   }
	   else if (format=='ISO') { // ISO format:  YYYY-MM-DD
		ccy=curdtarr[0];
		ccm=curdtarr[1]-1;
	        ccd=curdtarr[2];
	   }
	   else {                    // DEFAULT behavior:  i.e. European format DD/MM/YYYY
	        ccd=curdtarr[0];
		ccm=curdtarr[1]-1;
		ccy=curdtarr[2];
	   }
 
	   prepcalendar(ccd,ccm,ccy);
	}
	
}
 
function evtTgt(e)
{
	var el;
	if(e.target)el=e.target;
	else if(e.srcElement)el=e.srcElement;
	if(el.nodeType==3)el=el.parentNode; // defeat Safari bug
	return el;
}
function EvtObj(e){if(!e)e=window.event;return e;}
function cs_over(e) {
	evtTgt(EvtObj(e)).style.background='#FFCC66';
}
function cs_out(e) {
	evtTgt(EvtObj(e)).style.background='#C4D3EA';
}
function cs_click(e) {
	updobj.value=calvalarr[evtTgt(EvtObj(e)).id.substring(1,evtTgt(EvtObj(e)).id.length)];
	getObj('fc').style.display='none';
	
}
 
var mn=new Array('JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC');
var mnn=new Array('31','28','31','30','31','30','31','31','30','31','30','31');
var mnl=new Array('31','29','31','30','31','30','31','31','30','31','30','31');
var calvalarr=new Array(42);
 
function f_cps(obj) {
	obj.style.background='#C4D3EA';
	obj.style.font='10px Arial';
	obj.style.color='#333333';
	obj.style.textAlign='center';
	obj.style.textDecoration='none';
	obj.style.border='1px solid #6487AE';
	obj.style.cursor='pointer';
}
 
function f_cpps(obj) {
	obj.style.background='#C4D3EA';
	obj.style.font='10px Arial';
	obj.style.color='#ABABAB';
	obj.style.textAlign='center';
	obj.style.textDecoration='line-through';
	obj.style.border='1px solid #6487AE';
	obj.style.cursor='default';
}
 
function f_hds(obj) {
	obj.style.background='#FFF799';
	obj.style.font='bold 10px Arial';
	obj.style.color='#333333';
	obj.style.textAlign='center';
	obj.style.border='1px solid #6487AE';
	obj.style.cursor='pointer';
}
 
// day selected
function prepcalendar(hd,cm,cy) {
	now=new Date();
	sd=now.getDate();
	td=new Date();
	td.setDate(1);
	td.setFullYear(cy);
	td.setMonth(cm);
	cd=td.getDay();
	getObj('mns').innerHTML=mn[cm]+ ' ' + cy;
	marr=((cy%4)==0)?mnl:mnn;
	for(var d=1;d<=42;d++) {
		f_cps(getObj('v'+parseInt(d)));
		if ((d >= (cd -(-1))) && (d<=cd-(-marr[cm]))) {
			dip=((d-cd < sd)&&(cm==sccm)&&(cy==sccy));
			htd=((hd!='')&&(d-cd==hd));
			if (dip)
				f_cpps(getObj('v'+parseInt(d)));
			else if (htd)
				f_hds(getObj('v'+parseInt(d)));
			else
				f_cps(getObj('v'+parseInt(d)));
 
			getObj('v'+parseInt(d)).onmouseover=(dip)?null:cs_over;
			getObj('v'+parseInt(d)).onmouseout=(dip)?null:cs_out;
			getObj('v'+parseInt(d)).onclick=(dip)?null:cs_click;
			
			getObj('v'+parseInt(d)).innerHTML=d-cd;	
 
 
 
			// SCOOB: New code if/else if/else
			if (format=='USA') {      // USA foramt:  MM/DD/YYYY
			    calvalarr[d]=''+(cm-(-1))+separator+(d-cd)+separator+cy;
			}
			else if (format=='ISO') { // ISO format:  YYYY-MM-DD
			    calvalarr[d]=''+cy+separator+(cm-(-1))+separator+(d-cd);    // SCOOB: new code
			}
			else {                    // DEFAULT behavior:  i.e. European format DD/MM/YYYY
			    calvalarr[d]=''+(d-cd)+separator+(cm-(-1))+separator+cy;
			}
		}
		else {
			getObj('v'+d).innerHTML='&nbsp;';
			getObj('v'+parseInt(d)).onmouseover=null;
			getObj('v'+parseInt(d)).onmouseout=null;
			getObj('v'+parseInt(d)).style.cursor='default';
			}
	}
}
 
prepcalendar('',ccm,ccy);
//getObj('fc'+cc).style.visibility='hidden';
 
function caddm() {
	marr=((ccy%4)==0)?mnl:mnn;
	
	ccm+=1;
	if (ccm>=12) {
		ccm=0;
		ccy++;
	}
	cdayf();
	prepcalendar('',ccm,ccy);
}
 
function csubm() {
	marr=((ccy%4)==0)?mnl:mnn;
	
	ccm-=1;
	if (ccm<0) {
		ccm=11;
		ccy--;
	}
	cdayf();
	prepcalendar('',ccm,ccy);
}
 
function cdayf() {
if ((ccy>sccy)|((ccy==sccy)&&(ccm>=sccm)))
	return;
else {
	ccy=sccy;
	ccm=sccm;
	cfd=scfd;
	}
}

Open in new window

Avatar of HonorGod
HonorGod
Flag of United States of America image

Interesting requirements.
On what kind of server does your site execute?
I presume that you have a database, what kind?
Would it be reasonable to have the "current" holidays identified in the database?
I haven't looked at your calendar.js yet.  From where did it come?  Was it developed by someone there, or picked up off the web?
Avatar of Melody Scott

ASKER

Hi,

I'm going to ask those questions of my developer to be sure I get the right answers. I do know that the calendar we're using comes from the web. Thanks, I'll get back to you as soon as I can!
Hi! I'm back with the response from my programmer:

The questions they ask are implying more integration than they need to be concerned with.
We use perl / mysql.  We have a database with the list of holidays of interest.
We have the ability to write code to create an html page that will have the correct javascript
code to call a calendar script with a list of holidays for the coming 2 months.

Therefore and as stated in my original requirements list, we need a js date picker script that
we can call with a list of blacked out "days of the week" (so you can disable sunday delivery,
regardless of the date) and that you can also feed a list of dates that are to be blacked out
(i.e. not selectable).

The person was probably referring to a javascript that would call back the server interactively
 to fetch the list of blacked out dates for a given month.   If there were to suggest an ajax type
script to do that kind of work, I could write a backend to answer such requests.
Hi! Did those answers help? Do you have any suggestions? Thanks!
sorry, swamped at the present time for my full time job.  I hope to get back to this shortly.
Ok, thanks! Sorry I was a pest....
Here's some Ajax code that I have used to great success.
It creates an xmlHttp object, and uses it to invoke a servlet on the application server to perform a lookup.  In your case, the information that is sent can easily be a date & zip code.

The response from the server can then be the list of available, or unavailable days in the specified month, when can then be used to either create/update a drop down list, or list of radio button entries.

Is this the kind of thing for which you were looking?
<script type='text/javascript'>
  //------------------------------------------------------------------
  // Ajax routines for server request/response
  //------------------------------------------------------------------
  var xmlHttp;
 
  //------------------------------------------------------------------
  // Name: createXMLHttpRequest()
  // Role: Create the XML Request Object used by the Ajax routines
  //------------------------------------------------------------------
  function createXMLHttpRequest() {
    if ( window.ActiveXObject ) {
      xmlHttp = new ActiveXObject( 'Microsoft.XMLHTTP' );
    } else if ( window.XMLHttpRequest ) {
      xmlHttp = new XMLHttpRequest();
    }
  }
      
  //------------------------------------------------------------------
  // Name: getInfo()
  // Role: Issue the request to the Delivery servlet
  //------------------------------------------------------------------
  function getInfo( zip, date ) {
    createXMLHttpRequest();
    var queryString = '/Lookup/Available?Zip=' + zip + '&Date=' + date;
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open( 'GET', queryString, true );
    xmlHttp.send( null );
  }
 
  //------------------------------------------------------------------
  // Name: handleStateChange()
  // Role: Callback routine invoked when XML Request state changes
  // Note: The comment lines can be used to display the state changes
  //       for debug/development purposes
  //------------------------------------------------------------------
  function handleStateChange() {
//  var field = document.getElementById( 'state' );
//  field.value += xmlHttp.readyState + ' ';
    if ( xmlHttp.readyState == 4 ) {
//      field.value += '  RC = ' + xmlHttp.status;
      if ( xmlHttp.status == 200 ) {
         parseResults();
      }
    }
  }
 
  //------------------------------------------------------------------
  // Name: parseResults()
  // Role: Routine used to process results of lookup
  //------------------------------------------------------------------
  function parseResults() {
    var rspDiv = document.getElementById( 'serverResponse' );
    var rspText = document.createTextNode( xmlHttp.responseText );
    rspDiv.innerHTML = rspText.data;
  }
</script>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of HonorGod
HonorGod
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm not sure if it is or not. :) But I will work with it. My programmer had me investigating jquery as well, do you know anything about that? Thanks very much!
Oh, sorry, I just saw the second entry here. Thanks again, I will give it some work. I really appreciate it.
Not at all.  If you need additional help, let me know.
my apologies! I should have given you the points earlier!
Oh, good.  I'm glad to be able to help.
Thanks for the grade, and points.
Good luck, and have a Merry Christmas.