KevinM1 Posted October 13, 2006 Share Posted October 13, 2006 I've been trying to help out someone on another message board with tweaking a calendar script they have. The script allows for appointments to be made by passing values into an array within the code itself (not the way I would've done it, but that's neither here nor there). Originally, any appointments made would turn the days selected red to highlight the span of time they would take. Since the user is a firefighter, he wants the ability to have different colors available for different watch shifts. I figured that the easiest way to adapt the existing script to that would be to add another element to the array as a flag, then have a series of switch statements that would see what flag (if any) were set and highlight those dates with the correct color. Unfortunately, the code is only displaying the first appointment and nothing else. I think the problem is in checkDate's for-loop, but I can't see it. I originally thought that the switchs' break statements were ending the loop, but I don't think that's it.Below is all of the code...it's long. I don't like that all of the JavaScript is in the head rather than included as an external file. I also don't like how the calendar is created, but since I can't get the basic functionality of the script to work correctly I don't want to re-invent that part of the wheel just yet. The comments on every checkDate line were to help me match brackets. Well, anyway, here's the code:EDIT: I think I have to put it in a separate post because of its length. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 13, 2006 Author Share Posted October 13, 2006 The forum doesn't seem to like the code, so I'll just link to where I posted it on the other message board:[url=http://www.ozzu.com/ftopic69734.html]http://www.ozzu.com/ftopic69734.html[/url]I can't link directly to my message, but it's the last one in that thread. Quote Link to comment Share on other sites More sharing options...
fenway Posted October 13, 2006 Share Posted October 13, 2006 You'll have to post just the relevant code snippets. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 13, 2006 Author Share Posted October 13, 2006 Unfortunately, since I'm not 100% sure where my problem lies, I'll have to post all of the script so you can see how each of the functions are called. CheckDate is the most important function, and the one that I modified (the switch blocks). The only other thing I modified was the apps 2-d array. I merely added a flag as the last element for each array.[code]var months = ["January","February","March","April","May","June","July","August","Se ptember","October","November","December"];var daycounts = [31,28,31,30,31,30,31,31,30,31,30,31]; //for leap years, remember to set february to 29 days//2002 firstdays = [1,4,4,0,2,5,0,3,6,1,4,6];var firstdays = [0,3,3,6,1,4,6,2,5,0,3,5];//2004 firstdays = [3,6,7,3,5,1,3,6,2,4,0,2];// This is where you put in the appointments. follow pattern [fromday,frommonth,today,tomonth,message, flag]var apps = [[1,1,2,1,"Red Watch Days", "Holiday"],[12,6,12,6,"my birthday", "Holiday"],[28,8,2,9,"Trip to Paris", "Holiday"],[22,11,22,11,"Party with colleagues", "Holiday"],[20,12,30,12,"Christmas with family", "Holiday"],[12, 10, 14, 10, "Watch 1 Test", "Watch1"],[15, 10, 17, 10, "Watch 2 Test", "Watch2"],[18, 10, 20, 10, "Watch 3 Test", "Watch3"]];function CheckDate(month,dayno){ //begin function var retval = new String(dayno); var m = month + 1; for(var app = 0; app < apps.length; app++){ //begin for-loop if(m == apps[app][1] ){ //first month (if 1) if(apps[app][3] - apps[app][1] > 0){ //if 2 if(dayno >= apps[app][0]){ //if 3 switch (apps[app][5].toLowerCase()){ //switch case "holiday": retval = "<div class='hol' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch1": retval = "<div class='watch1' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch2": retval = "<div class='watch2' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch3": retval = "<div class='watch3' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; default: retval = "<div class='error' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; } //end switch } //end if 3 else { //else 1 if(dayno >= apps[app][0] && dayno <= apps[app][2]){ //if 3 switch (apps[app][5].toLowerCase()){ //switch case "holiday": retval = "<div class='hol' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch1": retval = "<div class='watch1' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch2": retval = "<div class='watch2' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch3": retval = "<div class='watch3' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; default: retval = "<div class='error' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; } //end switch } //end if 3 } //end else 1 } // end if 2 else if(m == apps[app][3]){ // second month (else if 1) if(dayno <= apps[app][2]){ //if 2 switch (apps[app][5].toLowerCase()){ //switch case "holiday": retval = "<div class='hol' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch1": retval = "<div class='watch1' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch2": retval = "<div class='watch2' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch3": retval = "<div class='watch3' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; default: retval = "<div class='error' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; } //end switch } //end if 2 } //end else if 1 else if( m > apps[app][1] && m < apps[app][3] ){ //else if 1 switch (apps[app][5].toLowerCase()){ //switch case "holiday": retval = "<div class='hol' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch1": retval = "<div class='watch1' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch2": retval = "<div class='watch2' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; case "watch3": retval = "<div class='watch3' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; default: retval = "<div class='error' title='" + apps[app][4] + "'>" + dayno + "</div>"; break; } //end switch } //end else if 1 } //end if 1 return retval; } //end for-loop}function PrintMonth(month){ var done = false; var day = 0; document.write("<table class='inner'><caption><b>" + months[month] + "</b></caption><thead>"); document.write("<th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>F r i</th><th>Sat</th><th>Sun</th></thead>"); while(!done){ document.write("<tr>"); PrintWeek(month,day, firstdays[month], daycounts[month]); document.write("</tr>"); day = day + 7; if( day > daycounts[month] + firstdays[month]){ done = true; } } //end of while-loop document.write("</tbody></table><p>");} //end of functionfunction PrintWeek(monthno,start,min,max){ var d; var desc; for(var j = 0; j < 7; j++){ document.write("<td>"); d = start + j; if(d >= min && d < max + min){ desc = CheckDate(monthno,d - min + 1); document.write(desc); } document.write("</td>"); } //end of for-loop} //end of function[/code]EDIT: Nope, fixing the first toLowerCase() call didn't help. Quote Link to comment Share on other sites More sharing options...
fenway Posted October 13, 2006 Share Posted October 13, 2006 And what calls are you issuing to write out the page itself? Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 13, 2006 Author Share Posted October 13, 2006 [quote author=fenway link=topic=111389.msg451617#msg451617 date=1160768107]And what calls are you issuing to write out the page itself?[/quote]Every time I try posting HTML within the code brackets I get an error, so I can't rewrite the code. But I can describe it! :)The page's layout is a table, four rows, three columns. In every table cell, they used a script element to call PrintMonth(x), where x is the index of the array (0 = January, 1 = February, etc). Nothing else is within those cells.Sloppy, and definitely not the way I'd do it. Once I get the calendars to print the set appointments correctly, I'll try to convince the guy I'm helping to let me change how all of that is handled. Quote Link to comment Share on other sites More sharing options...
fenway Posted October 13, 2006 Share Posted October 13, 2006 I think I understand, but I really need to see that page... can you put it up somewhere? Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 14, 2006 Author Share Posted October 14, 2006 [quote author=fenway link=topic=111389.msg451710#msg451710 date=1160779550]I think I understand, but I really need to see that page... can you put it up somewhere?[/quote]I put it up at http://www.nightslyr.com/calendar.html -- all of the code is in that file. Quote Link to comment Share on other sites More sharing options...
fenway Posted October 14, 2006 Share Posted October 14, 2006 Your return statement for CheckDate() is inside the for loop, so it only runs once... move it one line down, and it'll work. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 15, 2006 Author Share Posted October 15, 2006 [quote author=fenway link=topic=111389.msg451898#msg451898 date=1160848089]Your return statement for CheckDate() is inside the for loop, so it only runs once... move it one line down, and it'll work.[/quote]Thanks, that helped a lot! :)Unfortunately, now I have a logic problem. None of the appointments are displaying correctly. For instance, the second appointment is just supposed to highlight June 12 in red. Instead, it highlights from June 1 to June 12. The others show the same kind of thing -- highlighting the entire month in the appropriate color until the value stored in the today variable. I'm not exactly sure where the problem lies. I'm having a hard time following the for-loop and the myriad if-statements it has. I thought the problem lied where if-3 and else-1 are in the loop, as both check to see if dayno >= apps[app][0], but commenting it out didn't help. Any ideas? Quote Link to comment Share on other sites More sharing options...
fenway Posted October 15, 2006 Share Posted October 15, 2006 Well, to be honest, I have no idea why you have that if/else/switch logic... it's quite confusing. As for your problem, my guess would be that a variable isn't being reset. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 15, 2006 Author Share Posted October 15, 2006 [quote author=fenway link=topic=111389.msg452173#msg452173 date=1160935282]Well, to be honest, I have no idea why you have that if/else/switch logic... it's quite confusing. As for your problem, my guess would be that a variable isn't being reset.[/quote]Well, like I said before, the vast majority of the script was written before I got to it. All I did was try to append the switch statements as I was told that the rest worked fine. Unfortunately, I found that to not be the case (my previous message).I'm now trying to re-write the script from scratch. I've written a basic test script to see if I can print out at least one month correctly. I figure I can modify that to print all months correctly once it works right. Unfortunately, nothing is being printed to the screen so far, and I'm not sure why. My code (which is in an external .js file) is:[code]var W3CDOM = (document.createElement && document.getElementsByTagName);var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];var firstDays = [1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6];function init(){ if(!W3CDOM) return; printJanuary();}function printJanuary(){ document.write("<table><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thur</th><th>Fri</th><th>Sat</th><tr>"); var start = firstDays[0]; var offset = 0; while(offset < start){ document.write("<td></td>"); offset++; } for(var i = 1; i < numDays[0]; i++){ if((i % 7) < 1){ document.write("<td>" + i + "</td>"); } else{ document.write("</tr><tr><td>" + i + "</td>"); } } document.write("</tr></table>");}window.onload = init;[/code]I have other scripts that use the same basic setup. I've never had a problem with this kind of initialization function being used in the window's onload event handler before, so I'm pretty sure that's not where the problem lies. The XHTML is basically empty. There's no structure other than the body. Any ideas?EDIT: I know I have a logic problem with the algorithm (the i % 7 bit), but I wouldn't think that would prevent anything from being printed. Quote Link to comment Share on other sites More sharing options...
fenway Posted October 15, 2006 Share Posted October 15, 2006 Well, first, I would only execute a single document.write() call.. I don't know why you're not seeing anything. You should alert the string that you're building as you go along. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 16, 2006 Author Share Posted October 16, 2006 Hey, fenway, thanks for your help and patience. I know it must get frustrating dealing with newbs like me, so I just wanted to let you know that I really do appreciate it. :)I managed to get the calendars to print, but I seem to have a logic problem. In my testing, my months beginning on any day but Sunday all printed fine. But the months that start on a Sunday (April and I believe July) kept being printed as though they started on a Monday, and I'm not 100% sure why. I have a while-loop (which you'll see below) that prints off the blank days at the beginning of each month, if there are any. It appears that whenever a month starts on a Sunday, that while-loop still fires one time. I've tried different conditionals in there (start != 1 && pos < start, pos < (start - 1)), but none have worked so far. Any ideas?[code]var W3CDOM = (document.createElement && document.getElementsByTagName);var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];var firstDays = [2, 5, 5, 1, 3, 6, 1, 4, 7, 2, 5, 7]; //1 = Sunday, 2 = Monday, etc.function init(){ if(!W3CDOM) return; printMonth();}function printMonth(){ bod = document.getElementById('bod'); //My body element has an id of bod var output = '<table><br /><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th><br /><tr style="text-align: right;"><br />'; var start = firstDays[6]; var pos = 1; while(pos < start){ output += '<td></td>'; pos++; } for(var i = 1; i <= numDays[6]; i++){ if ((pos / 6) <= 1){ output += '<td>' + i + '</td>'; pos++; } else{ output += '</tr><br /><tr style="text-align: right;"><td>' + i + '</td>'; pos = 1; } } output += '</tr><br /></table>'; bod.innerHTML = output;}window.onload = init;[/code] Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 16, 2006 Author Share Posted October 16, 2006 Never mind. I figured it out. Apparently, I'm an idiot. :lol: Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 18, 2006 Author Share Posted October 18, 2006 I figured I'd use this thread to pose my next question as I'm still writing my calendar/appointments script and I don't want to pollute the board with another new thread.With my current setup (XHTML at http://www.nightslyr.com/calendar/calendar3.html), I have the calendars' structure coded directly in the markup. I give each month's table an id (the month name), and I give each cell of the first week of every month an id based on position (1 = Sunday, 2 = Monday, etc) so I can start outputting my dates at the right spot.What I'm wondering is this: Say I want to print February, which I believe started on a Thursday this year. I put the number 1 inside the cell February5 (first Thursday of February). Is there an easy way for me to print dates 2-28, in this instance, without having to give every cell in my calendars an id, thereby not having to use document.getElementById for every single date?Thanks. :) Quote Link to comment Share on other sites More sharing options...
fenway Posted October 19, 2006 Share Posted October 19, 2006 I don't see why you can't do this on the fly. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 20, 2006 Author Share Posted October 20, 2006 Actually, I found an even better way to do it -- getElementsByTagName. Just start the loop at the proper start day of that array, and iterate through it until the end of the month. For some reason, I always forget about that method until I need to use it.My script seems to be working properly now. I just need to tweak some CSS for the legend/key to look good.Again, thanks for your patience and help! :) Quote Link to comment Share on other sites More sharing options...
obsidian Posted October 20, 2006 Share Posted October 20, 2006 ok, nightslyr, i've got a question for you: why are you completely redrawing the calendar for every month? IMHO, you'd be better off to draw up all your calendars using PHP and then use javascript to simply show the proper month based on what the user supplies. that way, you can simpy have a show/hide function where you pass it the ID of the div or table that contains the calendar you want to show.is this an option, or could you just explain why you're writing the whole thing up to be written by javascript each month?also, your link above comes up with a 404 error :( Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted October 20, 2006 Author Share Posted October 20, 2006 [quote author=obsidian link=topic=111389.msg454937#msg454937 date=1161351276]ok, nightslyr, i've got a question for you: why are you completely redrawing the calendar for every month? IMHO, you'd be better off to draw up all your calendars using PHP and then use javascript to simply show the proper month based on what the user supplies. that way, you can simpy have a show/hide function where you pass it the ID of the div or table that contains the calendar you want to show.is this an option, or could you just explain why you're writing the whole thing up to be written by javascript each month?also, your link above comes up with a 404 error :([/quote]Ah, well, like I originally said, I was doing this to help someone on another message board and to get more experience using JavaScript myself. If I was doing something like this for myself, PHP would be the only way I'd do it. I'd have a form that would allow users to input their appointments, rather than to code them directly into the script (which is what the JS script relies on now, which is horrible). I'd also give it the option to either print out one month (like you suggested) or the entire year at once.Since the person I was helping had made the original in JS and only wanted to have something that would properly print out different classes of appointments (he's a firefighter, so knowing when each watch is on duty seemed to be his biggest concern), and since I wasn't sure whether or not they have access to a db to store the appointments, I figured I might as well just rewrite it in the same language. I did PM him with the suggestions I wrote above, though. There's really no reason for him to be doing it the hard way if they have access to a db. And now that I have it working in JS, transferring it over shouldn't be much of a problem if they do decide to go that route. The logic should basically remain the same.The 404 error stems from me renaming my html file. I tend to save drafts as I go in case I need something from a previous version, so the one I last linked to was the third draft. The new, working link is http://www.nightslyr.com/calendar/calendar.html. Most of the appointments on there were tests to ensure that they printed correctly over multiple months and that the proper color for multiple appointments on the same day printed when needed. The appointment info itself is displayed when the mouse is hovering over an appointment day...the cell's title property does that, rather than an event handler.It's not pretty, but it's functional. Quote Link to comment Share on other sites More sharing options...
obsidian Posted October 20, 2006 Share Posted October 20, 2006 definitely answers my question ;) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.