In this lab, you will implement client-side scripts to process a form and display feedback on a page.
The starter project is a version of the pacific trails resort case study with a new page called pricing. The pricing page is supposed to give the site visitor a quote for a stay at pacific trails resort. In this lab, you will only work on the behavior of the pricing page.
The pricing page consist of a form with two < input> elements of type number, two < input> elements of type checkbox, and the "Calculate Cost" button, which is implemented by a < div> element: see image.
If you open the file pricing.html in VS Code, you will find several < div> elements with class display-none that are not displayed on the page because their class display-none is styled to set the CSS property display to none .
In this lab, you add all code to the JavaScript file js/pricing.js . Do not make any changes to the stylesheet or to the HTML files.
1. Define a function that checks whether the input field for the number of guests contains a positive value, i.e. a value greater than 0:
a. Retrieve the value of the input field for the number of guests. For example:
let numGuests = document.getElementById('num-guests').value;
b. If the input field is empty or contains a non-positive value, i.e. a value less than or equal to 0, remove the class display-none from the < div> element with id guests-error and return false.
Note that the variable numGuests as defined above is of type string. To obtain the number represented by the string apply the method Number.parseInt(numGuests) . To remove the class from the < div> element retrieve first the < div> element:
let guestsError = document.getElementById('guests-error');
Then remove the class:
guestsError.classList.remove('display-none');
c. If the input field contains a positive value, add the class display-none to the < div>element with id guests-error and return true.
You can add the class display-none to the element represented by variable guestsError as follows:
guestsError.classList.add('display-none');
2. Register the function as event handler with the < input> element with id num-guests for the focusout event. I suggest placing the instrucon(s) to register any event listeners at the top of the JavaScript file. Note that these instructions are not wrapped in any function or method.
3. Test the script:
a. Enter a value <= 0 in the input field for the number of guests and then move the cursor out of the input field. The error message should be displayed below the input field.
b. Enter a a positive value in the input field and move the cursor out of the input field. The error message should disappear.
Analogously to Part 1, validate the input field for the number of nights. Note that a valid input value must be greater than 1. Test that the error message is displayed for an invalid value as soon as the input field for the number of nights looses focus. Test that the error message disappears if the value is corrected and the input field looses focus.
1. Implement a function that calculates and displays the cost for the entered user input:
a. Check if the input for the number of guests and nights is valid. Use the validaon funcons implemented for Part 1 and 2. The return value of these functions will indicate whether the input is valid.
b. If one or both fields are invalid, add the class display-none to the < div> element with id price-result and terminate the function.
c. If both fields are valid,
i. calculate the cost before taxes: The cost is $50 per person per night. If breakfast is included, $10 is added per person and per night. If dinner is included, $20 is added per person per night.
ii. calculate the taxes and fees: The taxes and fees are 21% of the cost.
iii. calculate the total: The total is the sum of the cost and the taxes & fees. (See also the examples in the images below.)
iv. Set the inner HTML of the suitable < td> elements in the HTML table in file pricing.html to the cost, the taxes, and the total, respectively.
v. Remove the class display-none from the < div> element with id price-result
2. If the above function is getting too large, say more than 40 lines, refactor the function
3. Register the function as event handler with the Calculate-Cost button, i.e. register the function with the < div> element with id price-button , for the click event.
4. Test the script:
a. Enter valid values, click the Calculate Cost button, and check that the correct quote that is displayed. (See also the examples in the images below.)
b. Enter different valid values, click the Calculate Cost button, and check that the quote is correctly updated.
c. Enter an invalid value, click the Calculate Cost button, and check that no quote is displayed.
5. If you have not yet done so, format the displayed cost values as shown in the four examples on the next page.
Figure: see image.
activities.html
< !DOCTYPE html>
< html lang="en">
< head>
< title>Pacific Trails Resort :: Activities< /title>
< meta charset="utf-8">
< meta name="description"
content="Pacific Trails Resort offers you glamping in spacious and well-appointed private Yurts. All luxury campsites have an ocean view. Enjoy the zen and natural beauty of Big Sur at Pacific Trails Resort.">
< link rel="stylesheet" href="pacific.css">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< /head>
< body>
< div id="wrapper">
< header>
< h1>Pacific Trails Resort< /h1>
< /header>
< nav>
< ul>
< li>< a href="index.html">Home< /a>< /li>
< li>< a href="yurts.html">Yurts< /a>< /li>
< li>< a href="activities.html">Activities< /a>< /li>
< li>< a href="pricing.html">Pricing< /a>< /li>
< /ul>
< /nav>
< div id="trailhero">
< /div>
< main>
< h2>Activities at Pacific Trails< /h2>
< h3>Hiking< /h3>
< p>< span class="resort">Pacific Trails Resort< /span> has 5 miles of hiking trails and is adjacent to a state park.
Go it alone or join one of our guided hikes.< /p>
< h3>Kayaking< /h3>
< p>Ocean kayaks are available for guest use.< /p>
< h3>Bird Watching< /h3>
< p>While anytime is a good time for bird watching at Pacific Trails, we offer guided birdwatching trips at sunrise
several times a week.< /p>
< /main>
< footer>
Copyright © 2018 Pacific Trails Resort< br>
< a href="mailto:yourfirstname@yourlastname.com">yourfirstname@yourlastname.com< /a>
< /footer>
< /div>
< /body>
< /html>
index.html
< !DOCTYPE html>
< html lang="en">
< head>
< title>Pacific Trails Resort< /title>
< meta charset="utf-8">
< meta name="description"
content="Pacific Trails Resort offers you glamping in spacious and well-appointed private Yurts. All luxury campsites have an ocean view. Enjoy the zen and natural beauty of Big Sur at Pacific Trails Resort.">
< link rel="stylesheet" href="pacific.css">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< /head>
< body>
< div id="wrapper">
< header>
< h1>Pacific Trails Resort< /h1>
< /header>
< nav>
< ul>
< li>< a href="index.html">Home< /a>< /li>
< li>< a href="yurts.html">Yurts< /a>< /li>
< li>< a href="activities.html">Activities< /a>< /li>
< li>< a href="pricing.html">Pricing< /a>< /li>
< /ul>
< /nav>
< div id="homehero">
< /div>
< main>
< h2>Enjoy Nature in Luxury< /h2>
< video controls="controls" width="320" height="240">
< source src="videos/pacific.m4v" type="video/mp4">
< source src="videos/pacific.ogv" type="video/ogg">
< embed type="application/x-shockwave-flash" src="videos/pacific.swf" width="320" height="240"
title="Pacific Trail Resort">
< /video>
< p>< span class="resort">Pacific Trails Resort< /span> offers a special lodging experience on the California North
Coast with panoramic views of the Pacific Ocean. Your stay at Pacific Trails Resort includes a sumptuously
appointed private yurt and a cooked-to-order breakfast each morning.< /p>
< ul>
< li>Unwind in the heated outdoor pool and whirlpool< /li>
< li>Explore the coast on your own or join our guided tours< /li>
< li>Relax in our lodge while enjoying complimentary appetizers and beverages< /li>
< li>Savor nightly fine dining with an ocean view< /li>
< /ul>
< div>
< span class="resort">Pacific Trails Resort< /span>< br>
12456 Pacific Trails Road< br>
Zephyr, CA 95555< br>< br>
< a id="mobile" href="tel:888-555-5555">888-555-5555< /a>< span id="desktop">888-555-5555< /span>< br>< br>
< /div>
< /main>
< footer>
Copyright © 2018 Pacific Trails Resort< br>
< a href="mailto:yourfirstname@yourlastname.com">yourfirstname@yourlastname.com< /a>
< /footer>
< /div>
< /body>
< /html>
pricing.html
< !DOCTYPE html>
< html lang="en">
< head>
< title>Pacific Trails Resort :: Pricing< /title>
< meta charset="utf-8">
< meta name="description"
content="Pacific Trails Resort offers you glamping in spacious and well-appointed private Yurts. All luxury campsites have an ocean view. Enjoy the zen and natural beauty of Big Sur at Pacific Trails Resort.">
< link rel="stylesheet" href="pacific.css">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< /head>
< body>
< div id="wrapper">
< header>
< h1>Pacific Trails Resort< /h1>
< /header>
< nav>
< ul>
< li>< a href="index.html">Home< /a>< /li>
< li>< a href="yurts.html">Yurts< /a>< /li>
< li>< a href="activities.html">Activities< /a>< /li>
< li>< a href="pricing.html">Pricing< /a>< /li>
< /ul>
< /nav>
< main>
< h2>Pricing< /h2>
< div id="price-result" class="display-none">
< table class="pricing">
< tr>
< td>Total before tax:< /td> < td id="price-value" class="price">< /td>
< /tr>
< tr>
< td>Taxes and fees:< /td> < td id="taxes-value" class="price">< /td>
< /tr>
< tr>
< td>Total:< /td> < td id="total-value" class="price">< /td>
< /tr>
< /table>
< /div>
< form>
< label for="num-guests">Number guests:< /label>
< input type="number" id="num-guests" name="num-guests">
< div class="error display-none" id="guests-error">Enter a valid number > 0.< /div>
< label for="num-nights">Number nights (at least 2 nights):< /label>
< input type="number" id="num-nights" name="num-nights">
< div class="error display-none" id="nights-error">Enter a valid number > 1.< /div>
< label for="breakfast">Breakfast:< /label>
< input type="checkbox" id="breakfast" name="breakfast" value="breakfast">
< label for="dinner">Dinner:< /label>
< input type="checkbox" id="dinner" name="dinner">
< div id="price-button">Calculate Cost< /div>
< /form>
< /main>
< footer>
Copyright © 2018 Pacific Trails Resort< br>
< a href="mailto:yourfirstname@yourlastname.com">yourfirstname@yourlastname.com< /a>
< /footer>
< /div>
< script src="./js/pricing.js">< /script>
< /body>
< /html>
yurts.html
< !DOCTYPE html>
< html lang="en">
< head>
< title>Pacific Trails Resort :: Yurts< /title>
< meta charset="utf-8">
< meta name="description"
content="Pacific Trails Resort offers you glamping in spacious and well-appointed private Yurts. All luxury campsites have an ocean view. Enjoy the zen and natural beauty of Big Sur at Pacific Trails Resort.">
< link rel="stylesheet" href="pacific.css">
< meta name="viewport" content="width=device-width, initial-scale=1.0">
< /head>
< body>
< div id="wrapper">
< header>
< h1>Pacific Trails Resort< /h1>
< /header>
< nav>
< ul>
< li>< a href="index.html">Home< /a>< /li>
< li>< a href="yurts.html">Yurts< /a>< /li>
< li>< a href="activities.html">Activities< /a>< /li>
< li>< a href="pricing.html">Pricing< /a>< /li>
< /ul>
< /nav>
< div id="yurthero">
< /div>
< main>
< h2>The Yurts at Pacific Trails< /h2>
< dl>
< dt>< strong>What is a yurt?< /strong>< /dt>
< dd>Our luxury yurts are permanent structures four feet off the ground. Each yurt has
canvas walls, a wooden floor, and a roof dome that can be opened.< /dd>
< dt>< strong>How are the yurts furnished?< /strong>< /dt>
< dd>Each yurt is furnished with a queen-size bed with down quilt and gas-fired stove.
Your luxury camping experience includes electricity and a sink with hot and
cold running water. Shower and restroom facilities are located in the lodge.< /dd>
< dt>< strong>What should I bring?< /strong>< /dt>
< dd>Most guests pack comfortable walking shoes and plan to dress for changing weather with light layers of
clothing. It's also helpful to bring a flashlight and a sense of adventure!< /dd>
< /dl>
< h3>Yurt Packages< /h3>
< p>A variety of luxury yurt packages are available. Choose a package below and contact us to begin your
reservation. We’re happy to build a custom package just for you!< /p>
< table class="yurts">
< tr>
< th>Package Name< /th>
< th>Description< /th>
< th>Nights< /th>
< th>Cost per Person< /th>
< /tr>
< tr>
< td>Weekend Escape< /td>
< td class="text">Two breakfasts, a trail map, a picnic snack< /td>
< td>2< /td>
< td>$450< /td>
< /tr>
< tr>
< td>Zen Retreat< /td>
< td class="text">Four breakfasts, a trail map, a pass for daily yoga< /td>
< td>4< /td>
< td>$600< /td>
< /tr>
< tr>
< td>Kayak Away< /td>
< td class="text">Two breakfasts, two hours of kayak rental daily, a trail map< /td>
< td>2< /td>
< td>$500< /td>
< /tr>
< /table>
< /main>
< footer>
Copyright © 2018 Pacific Trails Resort< br>
< a href="mailto:yourfirstname@yourlastname.com">yourfirstname@yourlastname.com< /a>
< /footer>
< /div>
< /body>
< /html>
pacific.css
* {
box-sizing: border-box;
}
header,
nav,
main,
footer {
display: block;
}
body {
background-color: #3399CC;
color: #666666;
font-family: Verdana, Arial, sans-serif;
background-image: linear-gradient(to bottom, #3399CC, #C2E0F0, #3399CC);
}
header {
background-color: #000033;
color: #FFFFFF;
font-family: Georgia, serif;
}
h1 {
line-height: 200%;
background-image: url(images/sunset.jpg);
background-repeat: no-repeat;
background-position: right;
padding-left: 1em;
height: 72px;
margin-bottom: 0;
}
nav {
font-weight: bold;
padding: 0;
float: left;
width: 160px;
}
nav ul {
list-style-type: none;
padding-left: 1em;
}
nav a {
text-decoration: none;
}
nav a:link {
color: #FFFFFF;
}
nav a:visited {
color: #C2E0F0;
}
nav a:hover {
color: #CCCCCC;
}
h2 {
color: #3399CC;
font-family: Georgia, serif;
}
h3 {
color: #000033;
}
dt {
color: #000033;
font-weight: bold;
}
.resort {
color: #000033;
font-size: 1.2em;
}
footer {
font-size: .70em;
font-style: italic;
text-align: center;
padding: 1em;
background-color: #FFFFFF;
margin-left: 170px;
}
main {
padding-left: 2em;
padding-right: 2em;
padding-bottom: 1px;
padding-top: 1em;
background-color: #FFFFFF;
margin-left: 170px;
display: block;
}
#homehero {
height: 300px;
background-image: url(images/coast.jpg);
background-size: 100% 100%;
background-repeat: no-repeat;
margin-left: 170px;
}
#yurthero {
height: 300px;
background-image: url(images/yurt.jpg);
background-size: 100% 100%;
background-repeat: no-repeat;
margin-left: 170px;
}
#trailhero {
height: 300px;
background-image: url(images/trail.jpg);
background-size: 100% 100%;
background-repeat: no-repeat;
margin-left: 170px;
}
#wrapper {
width: 80%;
margin-left: auto;
margin-right: auto;
background-color: #000033;
min-width: 700px;
max-width: 1024px;
box-shadow: 3px 3px 3px #000033;
}
#mobile {
display: none;
}
#desktop {
display: inline;
}
table.yurts {
margin-left: auto;
margin-right: auto;
border: 1px solid #3399CC;
width: 90%;
border-collapse: collapse;
}
table.yurts td,
table.yurts th {
padding: 5px;
border: 1px solid #3399CC;
}
table.yurts td {
text-align: center;
}
table.yurts .text {
text-align: left;
}
table.yurts tr:nth-of-type(even) {
background-color: #F5FAFC;
}
table.pricing {
margin-left: auto;
margin-right: auto;
border-collapse: collapse;
width: 80%;
}
table.pricing .price {
text-align: right;
}
table.pricing tr:last-child {
border-top: thin solid;
}
video,
embed {
float: right;
margin: 2em;
}
.leftfloat {
float: left;
margin: 1em;
}
.clear {
clear: both;
}
.display-none {
display: none;
}
#price-result {
border: solid;
padding: 1em;
width: 50%;
}
form {
width: 50%;
}
input[type=number] {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
input[type=checkbox] {
margin-top: 12pt;
margin-right: 25pt;
margin-left: 0;
text-align: left;
width: auto;
}
label {
padding: 12px 12px 12px 0;
display: inline-block;
}
.error {
color: red;
}
#price-button {
width: 100%;
font-size: 1em;
color: #666666;
background-color: #EEEEEE;
padding: 12px 20px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
margin-bottom: 20px;
text-align: center;
}
@media only screen and (max-width: 1024px) {
body {
margin: 0;
padding: 0;
background-image: none;
}
#wrapper {
width: auto;
min-width: 0;
margin: 0;
box-shadow: none;
}
h1 {
margin: 0;
}
nav {
float: none;
width: auto;
padding: 0.1em 1em;
background-color: #124373;
}
nav li {
display: inline-block;
}
nav a {
padding-right: 2em;
}
main {
padding: 1em;
margin-left: 0;
font-size: 90%;
}
footer {
margin: 0;
}
#homehero,
#yurthero,
#trailhero {
margin-left: 0;
}
}
@media only all and (max-width: 768px) {
h1 {
height: 100%;
font-size: 1.5em;
padding-left: 0.3em;
}
nav {
padding: 0;
}
nav a {
display: block;
padding: 0.2em;
font-size: 1.1em;
border-bottom: 1px solid #330000;
}
nav ul {
padding: 0;
margin: 0;
}
nav li {
display: block;
margin: 0;
padding: 0;
}
main {
padding: 0.1em 0.6em 0.1em 0.4em
}
#homehero,
#yurthero,
#trailhero {
display: none;
}
form {
width: 100%;
}
#price-result {
padding: 1em;
width: 100%;
}
}