PDA

View Full Version : Newbie needs help!!



SunKiss
09-08-2006, 10:11 PM
I am probably taking on more than a beginner should but I’m working on a reservation form that is 2 phases.

Phase 1 is to calculate reservation details so the guest has a detailed idea of the costs and a total as well as a few other things.

Phase 2 is to transfer the reservation details from one form to another with different field names so it can then be submitted to a shopping cart for secure information gathering.

The current test form can be found at: http://www.sunkissvillas.com/test/zpcal/reservation2.htm

Here is the logic behind the calculation side of the script (center form):

1. Guest selects arrival and departure date (ideally the script would calculate the difference between arrival and departure dates and insert the number of nights in the “nights” field but that would be a plus for the future).
2. Guest enters number of nights.
3. Guest selects season for weekly rate or longer or nightly rate from drop down menu.
4. Rental cost is automatically calculated by (number of nights * rate selection)
5. If stay is less than 7 nights a cleaning fee is automatically added.
6. Guest selects pool heat and pool heat field is automatically calculated (number of nights * 25.00)
7. Discount is determined (if stay is longer than 13 nights discount is automatically calculated by % of rental cost)(14-20 nights = 10%, 21-27 nights = 15%, 28 or more nights = 20%)
8. Total is automatically calculated (running total as costs are added.)
9. Amount due is determine (if arrival date is less than 8 weeks away amount due now = total) (if arrival date is more than 8 weeks away amount due now = (rental cost * .30)(30%)
10. Balance due date is determine (if arrival date is less than 8 weeks away balance due date = “today”) (if arrival date is more than 8 weeks away due date = arrival date – 8 weeks)

I have part of the form working properly and calculating but I have run into a problem with the “if/else” portion of the form and running totals.

I have a script that should work to do the date difference calculations but I haven’t added it in yet.

I would like to get this thing working properly because it would be a great system but I really want to understand the ins and outs of the script and what it is doing and why it is doing it and also if there is a better way to do it.

Any and all help would be greatly appreciated.
Mark

Twey
09-08-2006, 10:51 PM
Doing this in Javascript is not a good idea. Javascript is controlled by the user, and can be bypassed if the user so wishes. You should do this server-side, with a server-side language such as PHP, ASP, Java, or Python.

SunKiss
09-09-2006, 02:09 AM
Hi Twey,
Thanks for the feedback. Ultimately I don't care how it gets scripted, just as long as its maintains functionality and easy of use. I do have one question, I understand about users possibly making changes and then submitting but can't that be avoided for the most part by making fields "read only"?

I'd be happy to do it in PHP but that will take a little more help. I'm willing! Just show me how to convert the code or give me the equivalents. I still want to understand this regardless of what language it's in. Lead on if you have the time.
Mark

Twey
09-09-2006, 11:36 AM
I do have one question, I understand about users possibly making changes and then submitting but can't that be avoided for the most part by making fields "read only"?No. Don't be fooled by what seems to be possible. The user can submit any data, and make it appear to come from any form control. This includes <select> elements, readonly elements, radio buttons, and all those other things that you thought were safe. Javascript is in the same boat: it's client-side, so the user has total control over it. The user can effectively disable parts of it, modify it while it's running, or just completely ignore it.
I'd be happy to do it in PHP but that will take a little more help. I'm willing! Just show me how to convert the code or give me the equivalents.Do you know PHP, and does your server have it installed and enabled?

SunKiss
09-09-2006, 12:37 PM
Hi Twey,
Thanks for the insite.

I know some PHP but I'm new to that also. I use a php form handler on my site now and have followed the flow through the code and understand about as much as I do in JS. It works well so yes PHP is installed and enabled on my server.

It's unfortunate because I just got more of the form working properly. Besides the date calculations the only thing that I haven't been able to get working right is the discount calculation. Works nice otherwise.
Mark

SunKiss
09-09-2006, 01:53 PM
Hey Twey,
I still want to do this script in PHP but in the mean time can you tell me why the "discount" part of the script isn't working. I'm doing an "onFocus" in the discount field for the discount function. Originally I had the cleaning calculation and discount function together in one script but coulnd't get it to work that way either so I split it into 2 scripts, one for cleaning - which has always worked, and the other for discounts which has never worked. I renamed the discount function and changed the onFocus for that field to match but it still doesn't work. Here is the scripts the way they are now:


<SCRIPT language=JavaScript>

function Calculate()
{
// calculate total

if (charges.duration1.value < 7)
charges.cleaning.value = 110.01;

else
charges.cleaning.value = 0.00;

//charges.total.value = parseFloat(charges.rentalcost.value)
//+ parseFloat(charges.pheat.value) + (charges.cleaning.value) + (charges.SecurityDep.value) - (charges.discount.value) + (charges.tax.value);

}
</SCRIPT>
<SCRIPT language=JavaScript>
function Calc()
{
// calculate discount amount

if (charges.duration1.value > 27)
charges.discount.value = charges.rentalcost.value * .2;

else if (charges.duration1.value > 20 && < 28)
charges.discount.value = charges.rentalcost.value *.15;

else if (charges.duration1.value > 13 && < 21)
charges.discount.value = charges.rentalcost.value *.10;

else (charges.duration1.value > 6 && < 14)
charges.discount.value = charges.discount.value + 0.00;

//charges.discount.value = parseFloat(charges.discount.value)
//+ parseFloat(charges.pheat.value)
//+ parseFloat(charges.cleaning.value)
//+ parseFloat(charges.SecurityDep.value)
//- parseFloat(charges.discount.value)
//+ parseFloat(charges.tax.value);
}
</SCRIPT>

Here is the input field code:


<input onFocus=Calculate(); name="cleaning" type="text" class="inputnum" id="cleaning" size="5" maxlength="5" readonly />


<input onFocus="Calc();" name="discount" type="text" class="inputnum" id="discount" size="7" maxlength="7" readonly />

What part of this don't I understand? The "parseFloat" I commented out because I didn't need it.
Mark

Twey
09-09-2006, 04:12 PM
The object "charges" is never defined.

SunKiss
09-09-2006, 06:55 PM
OK, but why does the first script (cleaning script) work and the discount part doesn't? I didn't do anything different for the first part over the second (I didn't define it either.) How do I define it?
Mark

Twey
09-09-2006, 07:47 PM
Instead of "charges.cleaning.value", for example, you probably mean "document.forms['charges'].elements['cleaning'].value", I'd guess.

SunKiss
09-09-2006, 09:37 PM
Still doesn't work. I've tried every variation for field definition I can think of. At least 50 configuration, including putting the scripts together, etc. With the following scripts the cleaning fee still works but the discoutn does not.


<SCRIPT language=JavaScript>

function Calculate()
{form1 = document.forms['charges'].elements['cleaning'].value
// calculate total

if (document.forms.charges.duration1.value < 7)
document.forms.charges.cleaning.value = 110.01;

else
document.forms.charges.cleaning.value = 0.00;

//charges.total.value = parseFloat(charges.rentalcost.value)
//+ parseFloat(charges.pheat.value) + (charges.cleaning.value) + (charges.SecurityDep.value) - (charges.discount.value) + (charges.tax.value);

}
</SCRIPT>
<SCRIPT language=JavaScript>
function Calc()
{form1 = document.forms['charges'].elements['discount'].value
// calculate discount amount

if (document.forms.charges.duration1.value > 27)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value * .2;

else (document.forms.charges.duration1.value > 20 && < 28)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value *.15;

else (document.forms.charges.duration1.value > 13 && < 21)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value *.10;

else (document.forms.charges.duration1.value > 6 && < 14)
document.forms.charges.discount.value = document.forms.charges.discount.value + 0.00;

//charges.discount.value = parseFloat(charges.discount.value)
//+ parseFloat(charges.pheat.value)
//+ parseFloat(charges.cleaning.value)
//+ parseFloat(charges.SecurityDep.value)
//- parseFloat(charges.discount.value)
//+ parseFloat(charges.tax.value);
}
</SCRIPT>

Any more thoughts?
Thanks,
Mark

SunKiss
09-10-2006, 07:47 PM
This script produces an "error on page" and I can't figure out why.


<SCRIPT language=JavaScript>
function Calc()
{form1 = document.forms['charges'].elements['discount'].value
// calculate discount amount document.forms['charges'].elements['cleaning'].value

if (document.forms.charges.duration1.value > 27)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value * .2;

else (document.forms.charges.duration1.value > 20 && < 28)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value *.15;

else (document.forms.charges.duration1.value > 13 && < 21)
document.forms.charges.discount.value = document.forms.charges.rentalcost.value *.10;

else (document.forms.charges.duration1.value > 6 && < 14)
document.forms.charges.discount.value = document.forms.charges.discount.value + 0.00;

//charges.discount.value = parseFloat(charges.discount.value)
//+ parseFloat(charges.pheat.value)
//+ parseFloat(charges.cleaning.value)
//+ parseFloat(charges.SecurityDep.value)
//- parseFloat(charges.discount.value)
//+ parseFloat(charges.tax.value);
}
</SCRIPT>

It's references from:


<input onFocus="Calc();" name="discount" type="text" class="inputnum" id="discount" size="7" maxlength="7" readonly />

Can anyone help me see what I'm not seeing? I've separated it out from the "cleaning charge" script and ran it by itself but it doesn't work. The cleaning script works fine every time. What have i missed?

Twey
09-10-2006, 09:14 PM
<SCRIPT language=JavaScript>The type attribute has superseded the language attribute.

if (document.forms.charges.duration1.value > 27)Form elements should be accessed using the form.elements collection: there's no guarantee that they'll be available as properties of the form.

else (document.forms.charges.duration1.value > 20 && < 28)Conditions require if.

<input onFocus="Calc();" name="discount" type="text" class="inputnum" id="discount" size="7" maxlength="7" readonly />Your HTML uses an XHTML-style self-closing tag ending (/>), but it isn't valid XHTML. If you don't know what you're doing (and usually even if you do), stick with HTML.

That's some generally ugly and inflexible code :-\ You'd be much better off using a loop rather than all those if/else pairs.
<script type="text/javascript">
var discountBoundaries = [
[13, 0.1],
[20, 0.15],
[27, 0.2]
];

function calculateDiscount(frm) {
var f = frm.elements;

for(
var i = 0;
i < discountBoundaries.length &&
discountBoundaries[i + 1][0] < f['duration1'].value;
++i
) {}
f['discount'].value =
parseFloat(f['rentalcost'].value) *
discountBoundaries[i][1];
}
</script>

<!-- ... -->

<input
onfocus="calculateDiscount(this.form);"
name="discount"
type="text"
class="inputnum"
id="discount"
size="7"
maxlength="7"
readonly="readonly"
>

SunKiss
09-11-2006, 12:10 AM
Hi Twey,
Thanks for the script help. I had to add 2 more boundaries to get it to do everything I wanted but it works great. I will be spending some time trying to follow the process through this script so I can understand it. I guess I need to get some more advanced books on JS.

I still confused about why the "if else" code didn't work and what xhtml has to do with it. What makes it even more confusing is why the first if else script for cleaning worked fine.

Anyway, thanks again for your help.
Mark

Twey
09-11-2006, 12:57 AM
The third problem I pointed out is the most serious, and the cause of your error. Every condition requires an if statement. For example,
// Valid
if(1 == 1) {
doSomething();
} else {
doSomethingElse();
}

// Valid
if(1 == 1) {
doSomething();
} else if(2 == 2) {
doSomethingElse();
}

// Invalid
if(1 == 1) {
doSomething();
} else (2 == 2) {
doSomethingElse();
}

SunKiss
09-11-2006, 01:16 PM
Hi Twey,
Thanks for the guidance. I have to go back over what I did but I could have sworn at least one of variations of code I tried, not the one I posted, had all the "else if" requirements in it as well as the field definitions you provided and it still didn't work. That's what stumpted me.

If what you say is true and I just missed something incredibly simple I would be curious to see if it works. I think I will go back over the old code and try it again just to see if would work.

I agree with you about the code being ugly. Your code is much more elegant than what I did.

Another question. Another part of this form project is for date control. I have the following script that determine the difference between 2 dates and inserts the result into a field. The script currently uses a button to calculate the difference but I'm trying to change that to an "onFocus" event without a button but have been unable to get it to do it. It seems like a simple operation and probably is but thus far the solution has eluded me.
Mark


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">
<!-- Original: Ronnie T. Moore -->
<!-- Web Site: The JavaScript Source -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin
function isValidDate(dateStr) {
// Date validation function courtesty of
// Sandeep V. Tamhankar (stamhankar@hotmail.com) -->

// Checks for the following valid date formats:
// MM/DD/YY MM/DD/YYYY MM-DD-YY MM-DD-YYYY

var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/; // requires 4 digit year

var matchArray = dateStr.match(datePat); // is the format ok?
if (matchArray == null) {
alert(dateStr + " Date is not in a valid format.")
return false;
}
month = matchArray[1]; // parse date into variables
day = matchArray[3];
year = matchArray[4];
if (month < 1 || month > 12) { // check month range
alert("Month must be between 1 and 12.");
return false;
}
if (day < 1 || day > 31) {
alert("Day must be between 1 and 31.");
return false;
}
if ((month==4 || month==6 || month==9 || month==11) && day==31) {
alert("Month "+month+" doesn't have 31 days!")
return false;
}
if (month == 2) { // check for february 29th
var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
if (day>29 || (day==29 && !isleap)) {
alert("February " + year + " doesn't have " + day + " days!");
return false;
}
}
return true;
}

function isValidTime(timeStr) {
// Time validation function courtesty of
// Sandeep V. Tamhankar (stamhankar@hotmail.com) -->

// Checks if time is in HH:MM:SS AM/PM format.
// The seconds and AM/PM are optional.

var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;

var matchArray = timeStr.match(timePat);
if (matchArray == null) {
alert("Time is not in a valid format.");
return false;
}
hour = matchArray[1];
minute = matchArray[2];
second = matchArray[4];
ampm = matchArray[6];

if (second=="") { second = null; }
if (ampm=="") { ampm = null }

if (hour < 0 || hour > 23) {
alert("Hour must be between 1 and 12. (or 0 and 23 for military time)");
return false;
}
if (hour <= 12 && ampm == null) {
if (confirm("Please indicate which time format you are using. OK = Standard Time, CANCEL = Military Time")) {
alert("You must specify AM or PM.");
return false;
}
}
if (hour > 12 && ampm != null) {
alert("You can't specify AM or PM for military time.");
return false;
}
if (minute < 0 || minute > 59) {
alert ("Minute must be between 0 and 59.");
return false;
}
if (second != null && (second < 0 || second > 59)) {
alert ("Second must be between 0 and 59.");
return false;
}
return true;
}

function dateDiff(dateform) {
date1 = new Date();
date2 = new Date();
diff = new Date();

if (isValidDate(dateform.firstdate.value) && isValidTime(dateform.firsttime.value)) { // Validates first date
date1temp = new Date(dateform.firstdate.value + " " + dateform.firsttime.value);
date1.setTime(date1temp.getTime());
}
else return false; // otherwise exits

if (isValidDate(dateform.seconddate.value) && isValidTime(dateform.secondtime.value)) { // Validates second date
date2temp = new Date(dateform.seconddate.value + " " + dateform.secondtime.value);
date2.setTime(date2temp.getTime());
}
else return false; // otherwise exits

// sets difference date to difference of first date and second date

diff.setTime(Math.abs(date1.getTime() - date2.getTime()));

timediff = diff.getTime();

weeks = Math.floor(timediff / (1000 * 60 * 60 * 24 * 7));
timediff -= weeks * (1000 * 60 * 60 * 24 * 7);

days = Math.floor(timediff / (1000 * 60 * 60 * 24));
timediff -= days * (1000 * 60 * 60 * 24);

hours = Math.floor(timediff / (1000 * 60 * 60));
timediff -= hours * (1000 * 60 * 60);

mins = Math.floor(timediff / (1000 * 60));
timediff -= mins * (1000 * 60);

secs = Math.floor(timediff / 1000);
timediff -= secs * 1000;

dateform.difference.value = (weeks * 7) + days ;

return false; // form should never submit, returns false
}
// End -->
</script>
</head>

<body>
<center>
<form onSubmit="return dateDiff(this);">
<table>
<tr><td>
<pre>
First Date: Date: <input type=text name=firstdate value="" size=10 maxlength=10> (MM/DD/YYYY format)
<input type="hidden" name=firsttime value="00:00am">

Second Date: Date: <input type=text name=seconddate value="" size=10 maxlength=10> (MM/DD/YYYY format)
<input type="hidden" name=secondtime value="00:00am"> <center><input type=submit value="Calculate Difference!">

Date Difference:<br>
<input type=text name=difference value="" size=3>
</center>
</pre>
</td></tr>
</table>
</form>
</center>

<p><center>
<font face="arial, helvetica" size="-2">Free JavaScripts provided<br>
by <a href="http://javascriptsource.com">The JavaScript Source</a></font>
</center><p>

<!-- Script Size: 5.13 KB -->
</body>
</html>

Twey
09-11-2006, 04:49 PM
<input type=text name=difference value="" onfocus="dateDiff(this.form);" size=3>... and remove the onsubmit handler, obviously.

SunKiss
09-12-2006, 02:38 PM
Hi Twey,
Sweeeeeet. It works great. Thanks a million for the help. It's not PHP but it is just what the doctor ordered.

I've uploaded the latest version of the page and form and you can view it at:
http://www.sunkissvillas.com/test/zpcal/reservation2.htm

Do you have any suggestions on how to use or modify the date difference script to get the difference between the current date and a date in the future (arrival date) and put the result in a hidden field so it could be compared for another field value?
Thanks,
Mark

SunKiss
09-13-2006, 04:51 PM
OK Twey,
The form looks really good except that now I need to convert the arrival date format for comparison between today's date. I have the following script for determining the number of days between today and arrival date (date8A) but I think there is a problem with the way this script's format is when comparing to (date8a). Field format for (date8a) is mm/dd/yyyy.

Original code:

<SCRIPT LANGUAGE="JavaScript">
<!--

var SECOND = 1000; // the number of milliseconds in a second
var MINUTE = SECOND * 60; // the number of milliseconds in a minute
var HOUR = MINUTE * 60; // the number of milliseconds in an hour
var DAY = HOUR * 24; // the number of milliseconds in a day
var WEEK = DAY * 7; // the number of milliseconds in a week

function daysBetween(mo, dy, yr) {
var nDate = new Date(); // current date (local)
var nTime = nDate.getTime(); // current time (UTC)
var dTime = Date.UTC(yr, mo - 1, dy); // specified time (UTC)
var bTime = Math.abs(nTime - dTime) // time difference
return Math.round(bTime / DAY);
}

document.write("Days until 2020: " + daysBetween(1, 1, 2020));

// -->
</SCRIPT>

Modified code:

<SCRIPT LANGUAGE="JavaScript">
<!--

var SECOND = 1000; // the number of milliseconds in a second
var MINUTE = SECOND * 60; // the number of milliseconds in a minute
var HOUR = MINUTE * 60; // the number of milliseconds in an hour
var DAY = HOUR * 24; // the number of milliseconds in a day
var WEEK = DAY * 7; // the number of milliseconds in a week

function daysBetween(mo, dy, yr) {
var nDate = new Date(); // current date (local)
var nTime = nDate.getTime(); // current time (UTC)
var dTime = Date.UTC(yr, mo - 1, dy); // specified time (UTC)
var bTime = Math.abs(nTime - dTime) // time difference
return Math.round(bTime / DAY);
}

document.forms.charges.dntemp=(+ daysBetween(date8a));

function CalcDueNow(charges)

{form1 = document.forms['charges'].elements['duenow'].value

if (document.forms.charges.dntemp.value < 56)
document.forms.charges.duenow.value = document.forms.charges.total.value;

else (document.forms.charges.dntemp.value > 55)
document.forms.charges.duenow.value = document.forms.charges.rentalcost.value * .3
document.forms.charges.balancedue.value = document.forms.charges.total.value - document.forms.charges.duenow.value;
}


// -->
</SCRIPT>

I need to determine the difference between (date8a) and today and put the result either in a var or hidden field to compare the number of days which will fill fields "due now" and "balance due" based on the number of days in the var or hidden field. I've played around with this quite a bit and I've pretty much determined the problem is with the date format on one side or the other.
Thanks,
Mark