The Lawn Paynes website is a proposal page for a friend who is looking to expand his small lawn care and landscaping business by showing which services he provides, examples of his work using a slideshow, and a contact page to allow customers to reach out to him. The site can be viewed at https://ryansallee.github.io.
displayMessage()
file: spring.js Page: Lawn Paynes Home Page
- This function's purpose is to insert a message into the
#alert
div on this project's home page that is dependent upon the date listed on the computer detected by JavaScript with theDate.now()
method saved into thetodayDate
variable in Unix Time as a date object. As well, two dates are saved as date objects inbeginSpringDate
(03/20/2018), the beginning of spring, andbeginSummerDate
(06/21/2018), the beginning of summer, that will determine the messages displayed. If the date is before the beginning of spring, the message stored inbeforeSpringMessage
will display in the#alert
div set to an orange background. However, if the date is after the beginning of spring but before the beginning of summer, the message stored in thebeforeSummerMessage
will display in the#alert
div set to a red background. - Testing Notes:
To test the
displayMessage()
conditions for when it is before spring, please change the date on your computer to a date before 3/20/18, navigate away from the domain, and then return back to the page. You should be able to see the message "Spring is coming! Call us now to get your Lawn Paynes solved! with a orange background. If the date on the computer is set to a date between 03/20/2018 and 06/21/2018, you should see the message "Spring is here! Call us now before your Lawn Paynes are out of control!" with a red background. If the date is set past 06/21/2018, there will be no message.
nameValidate()
,emailValidate()
,phoneValidate()
,commentValidate()
file: lawn_form.js Page: Contact
- All four of these functions are called when the click event on the submit button (
submitButton
) occurs. These four functions validate their inputs to ensure the input fields for name, email, phone number, or comments is not blank by using the.val()
method. As well theemailValidate()
andphoneValidate()
validate their respective inputs against regex values for email and phone that are stored inemailFormat
andphoneFormat
by using the.test()
method against their respective inputs. If the inputs are blank or do not match a valid email or phone number format, each function sets their respective variables (doNotSubmitName
,doNotSubmitEmail
,doNotSubmitPhone
,doNotSubmitEmail
), to true, and a message is inserted in a div below each respective input advising information is needed or invalid. If any of the four variablesdoNotSubmitName
,doNotSubmitEmail
,doNotSubmitPhone
, ordoNotSubmitEmail
are true, an error is thrown and will be shown in the console and the code for the click event will not execute any further to the$.ajax
function. - Testing Notes: To test the validations, please leave any combination of the inputs on the Contact page blank, enter a phone number in an invalid North American phone number format, or an email in an invalid format such as just a single letter or an email without a domain. If any of these invalid inputs are submitted, messages advising input is needed or invalid will display below their respective inputs.
$.ajax
file: lawn_form.js Page: Contact
- The jQuery
$.ajax
function is executed if the validationsnameValidate()
,emailValidate()
,phoneValidate()
,commentValidate()
are successful (doNotSubmitName
,doNotSubmitEmail
,doNotSubmitPhone
,doNotSubmitEmail
are all false) after the click event on the submit button(submitButton
). The AJAX request is configured as a POST request, with the serialized data from the inputs in the form (formData
), and sends the request to a URL that returns a response with a CORS (Cross-Origin Resource Sharing) header that bypasses the same-origin policy. If a successful response is sent, a function is called to fade out the form using the.fadeOut()
jQuery method and an anonymous function is called to fade the form back in using.fadeIn()
and displaysuccessMessage
in the form. If the response is an error, the.errorAlert
class is selected anderrorMessage
displays in this div above the Name input. - Testing Notes: To test the form, please place valid input in the input fields and submit the form. The form will fade out over 1 second, and the message contained in
successMessage
will fade in over 1 second. To test the error message, load the page, disconnect from your web connection, and then submit the form. Since there will be no request, an error will be returned for the request anderrorMessage
will display in the div above the Name input.
slideShow(n)
,showButtons()
,slideMove(n)
,stop()
,resume()
file: lawn_slide_show.js Page: Our Work
- These 5 functions establish an automatic slide show with Previous(<), Pause, Next(>), and Resume buttons to allow a user to have control over the slideshow. As well, conditions are used to ensure the slideshow and its buttons only display on tablet-sized viewports and larger (>=640px).
slideShow(n)
is executed upon page load since the<script>
tags are placed at the end of the HTML file of Our Work.slideShow(n)
advances the slides automatically every 3 seconds as it is called every 3 seconds byslideInterval
.slideShow(n)
will only execute on tablet-sized viewports and larger(>=640px) by using a condition making sure that the detected viewport (viewPortWidth
) is equal to or greater than 640px(targetWidth
). After evaluating the condition on the viewport, parameter n is defined with a condition asslideShow(n)
is called byslideInterval
with n undefined and incrementsslideNumber
by 1 with the increment operator; this will be index number of the slide to be displayed inslides
. As well, conditions are used to make sure that n does not exceed the final index (3) or the first index (0) ofslides
as this would create an error. Next, a for loop is used to hide the current slide by setting its display to none displayed asi
will always be one behind the value ofslideNumber
. The next slide will display by setting the index ofslides
determined by the value ofslideNumber
.showButtons()
uses conditions to display the control buttons for the slideshow by using a condition to make sure that the control buttons (pauseButton
,resumeButton
,nextButton
, &previousButton
) display when the detected viewport (viewPortWidth
) is equal to or greater than 640px(targetWidth
) and JavaScript is active as thebutton
selector in our_workstyle.css hides all<button>
tags by setting the display to none.slideMove(n)
sets theslideNumber
by adding the parameter n toslideNumber
and passing this as an argument toslideShow(n)
to advance or move back the slide whenslideShow(n)
is called byslideMove(n)
. The slide displayed is advanced by 1 slide whenslideMove(n)
is called when a click event onnextButton
(> Button) occurs as it passes 1 as an argument forslideMove(n)
, and the slides are moved back by 1 on the click event onpreviousButton
(< Button) as -1 is passed as an argument forslideMove(n)
.stop()
ceases the movement of the of the slideshow sinceslideInterval
is cleared byclearInterval
, and thuslyslideShow(n)
is no longer called every 3 seconds.stop()
is called by a click event onpauseButton
or on a click event onnextButton
orpreviousButton
(afterslideMove(n)
is called to go the next slide or the preceding slide).stop()
can only called while the slideshow is playing (whenshowPlaying
is true: on page load or after a click event onresumeButton
, the Resume Button) since it setsshowPlaying
to false and only executes whenshowPlaying
is true so clicks onnextButton
andpreviousButton
do not callstop()
again if the slideshow has not been resumed.resume()
restarts the slideshow when there is a click event onresumeButton
and the show is paused (whenever there has been a click event onnextButton
,previousButton
, orpauseButton
-all of the control buttons but the Resume Button- that setsshowPlaying
to false) and setsshowPlaying
to true so thatstop()
can be called whenever there is a click event onnextButton
,previousButton
, orpauseButton
.
- Testing Notes: To test that the controls are displayed only when JavaScript is enabled on screens larger than 640px, please disable JavaScript in your browser and refresh the page. Just above the header, there should be no control buttons visible at the end of
.slide-container
.
.slide-container
file: our_workstyle.css Page: Our Work
- The purpose of this this custom class is to set a flex container for the images displayed on small screens to stack them upon one another as well as set a limiting container the images in the slideshow on larger screens (>=640px). For all screens, this container gives depth to the page with a box-shadow style and decreases the blockiness of the container with a border-radius style of 25px in addition to providing some contrast by using a shade of blue, but with the gradient-direction reversed from the direction of the body. On smaller screens, the container almost fills the page with a 97.5% width to give it some breathing room, but ensure that the container is not small on mobile devices. For larger screens, the width is decreased so that the
.slides
container that contains slideshow images are not overly large, and padding is applied to allow the.slides
container to breathe since the img selector for tablet sized screens fills the whole.slides
container with a 100% max-width and max-height. Furthermore, the width is significantly decreased on desktops and laptops (>=1025px)to ensure that the container does not extend below the user's viewport.
.contactForm
file: contact.css Page: Contact
- To set up a flex container for the contact form so that all of the inputs are stacked upon one another, I created this custom CSS class. This class as well provides contrast to the background color of the body with a white background-color style. Like the
.slide-container
class, depth is given to the page with a box-shadow style. As well, the base style gives it a 97.5% width for the container on small screens for maximum visibility with some breathing room of the background, since the base styles are mobile-first. Furthermore, the width decreases on the breakpoints for tablets (>=640px) and laptop and desktop screens (>=1025px) where the width is equivalent to the.main-header
class to make sure that the edge of the.contactForm
is aligned to the navigation and title in the header for a clean look. As well,.contactForm
gives a top margin +10px of the height of the header due to the header's use of fixed positioning for a stickyheader. For balance, a bottom margin of 10px is applied as well.
.slides
files: our_workstyle.css & our_work_no_script.css Page: Our Work
- This custom selector contains each of the images as well as their captions. For the slideshow that runs on devices with a viewport greater than or equal to 640px, the
.slides
selector uses the nth-of-type selector to hide the second.slides
container and every.slides
container thereafter as nth-of-type is set to 1n+2. If JavaScript is disabled by a visitor, the our_work_no_script.css file embedded in<noscript>
tags reverses.slides
containers 2-4 being set to none by setting them back to block. - Testing Notes: Please disable JavaScript on a device with a viewport greater than or equal to 640px such as a tablet or laptop, and all of the images that play on the auto-slide show will appear stacked upon one another.
<noscript><p>...
file: contact.html Page: Contact
- This tag contains a message to advise a visitor that the form will not function when JavaScript is disabled. The previous
<p>
tag and its message is hidden by the CSS selectorp:nth-child(2)
in contact_no_script.css. Please disable JavaScript and then reload the page to test that the message in the<p>
tag that is nested in<noscript>
displays rather than the previous<p>
tag.