Reputation: 3
I am building an order form with validation and computational functionality. In the folder there are two files; 1) index.html and 2) app.js. Both the .html and .js file are in the same folder. I cannot, for the life of me, successfully link the .js file to the .html file! I have read through countless posts here, and the only piece of advice I found was to link the .html file to a jquery library (which I did). I have also tested the .js file to see if it is linking properly by typing a test message at the top of the .js file. The result; no linkage! Here is the code:
For the .html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Order Form</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js'></script>
<link rel="stylesheet" href="style.css">
<script src="modernizr.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<form name="order" method="post" action="/submit">
<h1>Order Form</h1>
<fieldset>
<legend>Contact Details</legend>
<ul>
<li>
<label class="required">
<div>Full Name</div>
<input name="name" required autofocus>
</label>
</li>
<li>
<label class="required">
<div>Email Address</div>
<input type="email" name="email" required>
</label>
</li>
<li>
<label>
<div>Postal Address</div>
<input name="address1" placeholder="Address Line 1">
</label>
<div> </div>
<input name="address2" placeholder="Address Line 2">
<div> </div>
<input name="city" class="city" placeholder="Town/City">
<input name="state" class="state" placeholder="State">
<input name="zip" class="zip" placeholder="Zip Code">
<div> </div>
<select name="country">
<option value="0">Country</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
</select>
</li>
<li>
<label>
<div>Home Phone No.</div>
<input type="tel" name="homephone">
</label>
</li>
<li>
<label>
<div>Cell Phone No.</div>
<input type="tel" name="cellphone">
</label>
</li>
<li>
<label>
<div>Skype Name</div>
<input name="skype">
</label>
</li>
<li>
<label>
<div>Twitter</div>
<span class="twitter_prefix">@</span>
<input name="twitter" class="twitter">
</label>
</li>
</ul>
</fieldset>
<fieldset>
<legend>Login Details</legend>
<ul>
<li>
<label class="required">
<div>Password</div>
<input type="password" name="password" required>
</label>
</li>
<li>
<label class="required">
<div>Confirm Password</div>
<input type="password" name="confirm_password" required>
</label>
</li>
</ul>
</fieldset>
<fieldset>
<legend>Order Details</legend>
<table>
<thead>
<tr>
<th>Product Code</th><th>Description</th><th>Qty</th><th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
COMP001
<input type="hidden" name="product_code" value="COMP001">
</td>
<td>The Ultimate Smartphone</td>
<td>
<input type="number" data-price="399.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>399.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
<tr>
<td>
COMP002
<input type="hidden" name="product_code" value="COMP002">
</td>
<td>The Ultimate Tablet</td>
<td>
<input type="number" data-price="499.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>499.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
<tr>
<td>
COMP003
<input type="hidden" name="product_code" value="COMP003">
</td>
<td>The Ultimate Netbook</td>
<td>
<input type="number" data-price="299.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>299.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">Order Total</td>
<td>
<output name="order_total" id="order_total">$0.00</output>
</td>
</tr>
</tfoot>
</table>
</fieldset>
<fieldset>
<legend>Payment Details</legend>
<ul>
<li>
<label class="required">
<div>Name on Card</div>
<input name="card_name" required>
</label>
</li>
<li>
<label class="required">
<div>Credit Card No.</div>
<input name="card_number" pattern="[0-9]{13,16}"
maxlength="16" required title="13-16 digits, no spaces">
</label>
</li>
<li>
<label class="required">
<div>Expiry Date</div>
<input type="month" name="card_expirty" maxlength="7"
placeholder="yyyy-mm" required value="2015-06">
</label>
</li>
<li>
<label class="required">
<div>CVV2 No.</div>
<input name="card_cvv2" class="cvv" maxlength="3" pattern="[0-9]{3}"
required title="exactly 3 digits">
<span>(Three digit code at back of card)</span>
</label>
</li>
</ul>
</fieldset>
<div class="buttons">
<input type="submit" value="Submit Order">
<input type="submit" id="saveOrder" value="Save Order" formnovalidate formaction="/save">
</div>
</form>
For the .js file:
(function() {
var init=function() {
var orderForm=document.forms.order,
saveBtn=document.getElementById('saveOrder'),
saveBtnClicked=false;
var saveForm=function() {
if(!('formAction' in document.createElement('input'))) {
var formAction=saveBtn.getAttribute('formaction');
orderForm.setAttribute('action', formAction);
}
saveBtnClicked=true;
};
saveBtn.addEventListener('click', saveForm, false);
};
var qtyFields=orderForm.quantity,
totalFields=document.getElementsByClassName('item_total'),
orderTotalField=document.getElementById('order_total');
var formatMoney=function(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
var calculateTotals=function() {
var 1=0,
ln=qtyFields.length,
itemQty=0,
itemPrice=0.00,
itemTotal=0.00,
itemTotalMoney='$0.00',
orderTotal=0.00,
orderTotalMoney='$0.00';
for(; i<ln; i++) {
if(!!qtyFields[i].valueAsNumber) {
itemQty=qtyFields[i].valueAsNumber || 0;
} else {
itemQty=parseFloat(qtyFields[i].value) || 0;
}
if(!!qtyFields[i].dataset) {
itemPrice=parseFloat(qtyFields[i].dataset.price);
} else {
itemPrice=parseFloat(qtyFields[i].getAttribute('data-price'));
}
itemTotal=itemQty*itemPrice;
itemTotalMoney='$'+formatMoney(itemTotal.toFixed(2));
orderTotal+=itemTotal;
orderTotalMoney='$'+formatMoney(orderTotal.toFixed(2));
if(!!totalFields[i].value) {
totalFields[i].value=itemTotalMoney;
orderTotalField.value=orderTotalMoney;
} else {
totalFields[i].innerHTML=itemTotalMoney;
orderTotalField.innerHTML=orderTotalMoney;
}
}
};
CalculateTotals();
var qtyListeners=function() {
var i=0,
ln=qtyFields.length;
for(; i<ln; i++) {
qtyFields[i].addEventListener('input', calculateTotals, false);
qtyFields[i].addEventListener('keyup', calculateTotals, false);
}
};
qtyListeners();
var doCustomValidity=function(field, msg) {
if('setCustomValidity' in field) {
field.setCustomValidity(msg);
} else {
field.validationMessage=msg;
}
};
var validateForm=function() {
doCustomValidity(orderForm.name, '');
doCustomValidity(orderForm.password, '');
doCustomValidity(orderForm.confirm_password, '');
doCustomValidity(orderForm.card_name, '');
if(orderForm.name.value.length < 4) {
doCustomValidity(
orderForm.name, 'Full Name must be at least 4 characters long'
);
}
if(orderForm.password.value.length < 8) {
doCustomValidity(
orderForm.password,
'Password must be at least 8 characters long'
);
}
if(orderForm.password.value !=orderForm.confirm_password.value) {
doCustomValidity(
orderForm.confirm_password,
'Confirm Password must match Password'
);
}
if(orderForm.card_name.value.length < 4) {
doCustomValidity(
orderForm.card_name,
'Name on Card must be at least 4 characters long'
);
}
};
orderForm.addEventListener('input', validateForm, false);
orderForm.addEventListener('keyup', validateForm, false);
window.addEventListener('load', init, false);
})();
Any and all input/advise will be much appreciated. Thanks in advance!
Here is the updated (corrected) code:
index.html: (didn't change anything with this file; just took out the modernizr.js link and the .css link)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Order Form</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js'></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<form name="order" method="post" action="/submit">
<h1>Order Form</h1>
<fieldset>
<legend>Contact Details</legend>
<ul>
<li>
<label class="required">
<div>Full Name</div>
<input name="name" required autofocus>
</label>
</li>
<li>
<label class="required">
<div>Email Address</div>
<input type="email" name="email" required>
</label>
</li>
<li>
<label>
<div>Postal Address</div>
<input name="address1" placeholder="Address Line 1">
</label>
<div> </div>
<input name="address2" placeholder="Address Line 2">
<div> </div>
<input name="city" class="city" placeholder="Town/City">
<input name="state" class="state" placeholder="State">
<input name="zip" class="zip" placeholder="Zip Code">
<div> </div>
<select name="country">
<option value="0">Country</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
</select>
</li>
<li>
<label>
<div>Home Phone No.</div>
<input type="tel" name="homephone">
</label>
</li>
<li>
<label>
<div>Cell Phone No.</div>
<input type="tel" name="cellphone">
</label>
</li>
<li>
<label>
<div>Skype Name</div>
<input name="skype">
</label>
</li>
<li>
<label>
<div>Twitter</div>
<span class="twitter_prefix">@</span>
<input name="twitter" class="twitter">
</label>
</li>
</ul>
</fieldset>
<fieldset>
<legend>Login Details</legend>
<ul>
<li>
<label class="required">
<div>Password</div>
<input type="password" name="password" required>
</label>
</li>
<li>
<label class="required">
<div>Confirm Password</div>
<input type="password" name="confirm_password" required>
</label>
</li>
</ul>
</fieldset>
<fieldset>
<legend>Order Details</legend>
<table>
<thead>
<tr>
<th>Product Code</th><th>Description</th><th>Qty</th><th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
COMP001
<input type="hidden" name="product_code" value="COMP001">
</td>
<td>The Ultimate Smartphone</td>
<td>
<input type="number" data-price="399.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>399.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
<tr>
<td>
COMP002
<input type="hidden" name="product_code" value="COMP002">
</td>
<td>The Ultimate Tablet</td>
<td>
<input type="number" data-price="499.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>499.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
<tr>
<td>
COMP003
<input type="hidden" name="product_code" value="COMP003">
</td>
<td>The Ultimate Netbook</td>
<td>
<input type="number" data-price="299.99" name="quantity" value="0"
min="0" max="99" maxlength="2">
</td>
<td>299.99</td>
<td>
<output name="item_total" class="item_total">$0.00</output>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">Order Total</td>
<td>
<output name="order_total" id="order_total">$0.00</output>
</td>
</tr>
</tfoot>
</table>
</fieldset>
<fieldset>
<legend>Payment Details</legend>
<ul>
<li>
<label class="required">
<div>Name on Card</div>
<input name="card_name" required>
</label>
</li>
<li>
<label class="required">
<div>Credit Card No.</div>
<input name="card_number" pattern="[0-9]{13,16}"
maxlength="16" required title="13-16 digits, no spaces">
</label>
</li>
<li>
<label class="required">
<div>Expiry Date</div>
<input type="month" name="card_expirty" maxlength="7"
placeholder="yyyy-mm" required value="2015-06">
</label>
</li>
<li>
<label class="required">
<div>CVV2 No.</div>
<input name="card_cvv2" class="cvv" maxlength="3" pattern="[0-9]{3}"
required title="exactly 3 digits">
<span>(Three digit code at back of card)</span>
</label>
</li>
</ul>
</fieldset>
<div class="buttons">
<input type="submit" value="Submit Order">
<input type="submit" id="saveOrder" value="Save Order" formnovalidate formaction="/save">
</div>
</form>
...and the app.js file:
(function() {
var init=function() {
var orderForm=document.forms.order,
saveBtn=document.getElementById('saveOrder'),
saveBtnClicked=false;
var saveForm=function() {
if(!('formAction' in document.createElement('input'))) {
var formAction=saveBtn.getAttribute('formAction');
orderForm.setAttribute('action', formAction);
}
saveBtnClicked=true;
};
saveBtn.addEventListener('click', saveForm, false);
var qtyFields=orderForm.quantity,
totalFields=document.getElementsByClassName('item_total'),
orderTotalField=document.getElementById('order_total');
var formatMoney=function(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
var calculateTotals=function() {
var i=0,
ln=qtyFields.length,
itemQty=0,
itemPrice=0.00,
itemTotal=0.00,
itemTotalMoney='$0.00',
orderTotal=0.00,
orderTotalMoney='$0.00';
for(; i<ln; i++) {
if(!!qtyFields[i].valueAsNumber) {
itemQty=qtyFields[i].valueAsNumber || 0;
} else {
itemQty=parseFloat(qtyFields[i].value) || 0;
}
if(!!qtyFields[i].dataset) {
itemPrice=parseFloat(qtyFields[i].dataset.price);
} else {
itemPrice=parseFloat(qtyFields[i].getAttribute('data-price'));
}
itemTotal=itemQty*itemPrice;
itemTotalMoney='$'+formatMoney(itemTotal.toFixed(2));
orderTotal+=itemTotal;
orderTotalMoney='$'+formatMoney(orderTotal.toFixed(2));
if(!!totalFields[i].value) {
totalFields[i].value=itemTotalMoney;
orderTotalField.value=orderTotalMoney;
} else {
totalFields[i].innerHTML=itemTotalMoney;
orderTotalField.innerHTML=orderTotalMoney;
}
}
};
CalculateTotals();
var qtyListeners=function() {
var i=0,
ln=qtyFields.length;
for(; i<ln; i++) {
qtyFields[i].addEventListener('input', calculateTotals, false);
qtyFields[i].addEventListener('keyup', calculateTotals, false);
}
};
qtyListeners();
var doCustomValidity=function(field, msg) {
if('setCustomValidity' in field) {
field.setCustomValidity(msg);
} else {
field.validationMessage=msg;
}
};
var validateForm=function() {
doCustomValidity(orderForm.name, '');
doCustomValidity(orderForm.password, '');
doCustomValidity(orderForm.confirm_password, '');
doCustomValidity(orderForm.card_name, '');
if(orderForm.name.value.length < 4) {
doCustomValidity(
orderForm.name, 'Full Name must be at least 4 characters long'
);
}
if(orderForm.password.value.length < 8) {
doCustomValidity(
orderForm.password,
'Password must be at least 8 characters long'
);
}
if(orderForm.password.value !=orderForm.confirm_password.value) {
doCustomValidity(
orderForm.confirm_password,
'Confirm Password must match Password'
);
}
if(orderForm.card_name.value.length < 4) {
doCustomValidity(
orderForm.card_name,
'Name on Card must be at least 4 characters long'
);
}
};
orderForm.addEventListener('input', validateForm, false);
orderForm.addEventListener('keyup', validateForm, false);
window.addEventListener('load', init, false);
};
})();
There are no longer any errors that arise when I use chrome debugger**
As always, thanks in advance!!
Upvotes: 0
Views: 417
Reputation: 4004
I'm seeing an error message (script tag IS working): Uncaught SyntaxError: Unexpected number on line 27 of app.js
In this part:
var calculateTotals=function() {
var 1=0,
ln=qtyFields.length,
itemQty=0,
itemPrice=0.00,
itemTotal=0.00,
itemTotalMoney='$0.00',
orderTotal=0.00,
orderTotalMoney='$0.00';
This would be in reference to using the number "1" as a variable name in "var 1=0,"
After solving that, the next issue was an "orderForm is not defined" error on line 18. Looks like a scope issue to me where the variable is defined within a method, and other methods are trying to access it but it's out of scope.
In general from what I can tell, it doesn't look like your issue is what you think it is, it looks like you need to debug your javascript.
Most modern web browsers have debugging tools built in for that. Here's a guide to using Chrome for that. https://developer.chrome.com/devtools/docs/javascript-debugging
Upvotes: 1