Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 19 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,106 +2,40 @@



### Description
* In this Skill-based Assessment, you will be creating a small website and you get to pick what is the website about. The main purpose of this SBA is to test your skills in implementing a clean HTML structure that follows the methodologies of visual design, and styling your site so that it is user-friendly.
### General Description & Navigation

* You have the entire day for this SBA. Make sure to check in with your instructor for approval of your idea. Your work will be graded based on the below technical requirements. Also, creativity always works in your favor.
* GitHub Pages link: https://ghassannasr.github.io/sba.javascript_3-page-website/

* Since this is your first time creating a 3 page website, keep it simple. Keeping it simple is very important. It ensures that you can complete this project within the given time and also gives you a better idea of what can you get done in the given time if you were to do it again with more requirements.
* For this assignment I implemented a 3-page mini website as a celebration of parks in Charleston, SC, and parks in general.

* Once you got your idea, think in the user’s perspective when creating the website.  You like your users to have a good experience when interacting with your site. This gives you a better chance of users trusting your site and coming back for more. For this SBA, don’t worry too much about the content. There are many places you can get free content to display on your site. Concentrate more on the web site's structure and grid system.
* I wanted the look and feel of the pages to reflect the vibrance of spring in Charleston ... beautiful blue skies and the colors of cherry and almond blossoms.

* The entry page is simple. It has a fully-responsive navbar and content, including a little footer. I spent some time experimenting with ways of laying out text on the blue sky, trying to immitate the feel of clouds.

* Some resources for free content:
* Photos: `https://www.pexels.com/search/template/`
* Text: `https://www.lipsum.com/`
* GIFs: `https://www.motionelements.com/stock-image-10116013-business-and-startup-4k`
* There are two navigation links at the top that link to other pages: 1) A "Register" link to a page for signing up for a newsletter, and 2) a link in the dropdown to the "Parks" page that provides an interface to an API endpoint at the National Park Service here: https://www.nps.gov/subjects/developer/api-documentation.htm#/visitorcenters/getVisitorCenters . The other links are provided but not implemented.

* Useful API sites:
* https://rapidapi.com/ (Links to an external site.)
* https://any-api.com/ (Links to an external site.)
* https://github.com/toddmotto/public-apis#public-apis- (Links to an external site.)
* https://apilist.fun/
* The nav bar at the top has identical html on every page of the website. I therefore produce the nav bar html in a utility script residing in header-functions.js, and I call that function from withing <script> tags near the top of the html body. I am not sure it is best practice to do so, but it certainly helped me in removing the clutter in the pages I was working with.

### Deliverable:
* A theme for your site that you feel comfortable with
* Complete all technical requirements for HTML, CSS, and Javascript
* Have markups of your pages
* Research for a public API that can provide you with content (Optional)
* Include a README file. The file should include technical specifications and description of your website.
* Host on GitHub, include the link to your GitHub account in the README file(optional)
* Submit the project in a ZIP file
* I also included the three Bootstrap links at the bottom of each in a similar utility function residing in footer-function.js that is called at the bottom of each page.

* If JavaScript is needed during page loading, I included it in header-functions.js. Otherwise I included it in footer-functions.js.

### Bootstrap

* I have been waiting for the opportunity to learn higher level, responsive html that allows me to think in aesthetically pleasing ways that also allow for flexibility. And thus my use of Bootstrap. It took a disproportionate amount of my time, but I think it was worth the challenge in terms of future utility.

## Technical requirements
* I feel I have finally understood the power of Bootstrap, thanks to this assignment. I now have a good conceptual understanding of the grid system, which looks deceivingly similar to "tables" in its syntax of "rows" and "columns". One of the insights I have gained is that content always resides in Bootstrap columns. Resist the temptation to place content in a row! A column is where responsiveness is implemented. Create a column, even if a single column, before adding page content. Bootstrap is about the trinity of container, row, and column.

* HTML
* Have at least 3 pages, keep the grid system consistent as much as possible
* Use at least 10 different HTML tags
* Use HTML tables
* Implement at least two uses for forms
* Dropped Down Menu
* Use web fonts
* Use different types of content in the form of text, images, videos, and GIFs
* Use regex validation
* My next challenge was to experiment in ways of customizing Bootstrap without sacrificing its power, which is its responsive design. My process consisted of adding selectors piecemeal and repeatedly checking to make sure that smooth responsive functionality was not sacrificed. The text I added on the cherry blossom background on the first page is not fully responsive. In order to keep track of the html selectors I added, I prefixed each selector I created with my initials: "gn".

* CSS
* Inline, internal, and external styling
* Use five different CSS selectors
* Don’t use too many fonts
* Use colors that complement each other
* Use Flexbox (Optional)
* Use SASS/SCSS (Optional)
* Use animations (Optional)
* I experimented with creating an image background to smooth the edges of Bootstrap components and create continuity that would maintain the power of Bootstrap without necessarily being beholden to its "blocky" look. The newsletter registration page is an example. It contains a Jumbotron and a form on the page, but the background image effaces the component boundaries.

* Javascript
* External scripts
* Use variables, if statements, loops, at least one form of collections, functions/call back, and events
* Use AJAX (Optional)
* Use JSON or XML (Optional)
* Use JQuery (Optional)
### Forms

* I created two forms, one for registering for a newsletter, and another for doing a search that utilizes the National Park Service API.

* My implementation of form validation on the newsletter form is minimal. I tested the functionality of doing validation on the e-mail field. I searched the Web for regular expressions used for checking valid email addresses, and the results were amazing! I used a very simple one that if matched opens a "success" alert box, and "failure" otherwise. I would like to in the future implement a tooltip animation.

## How to Download
* I found myself questioning whether input elements really need to be placed inside form tags. Some of the problems I encountered in implementing event listeners seemed to be complicated by the fact that forms add their own level of functionality to input elements placed inside them, possibly interfering with more customized event handling.

#### Part 1 - Forking the Project
* To _fork_ the project, click the `Fork` button located at the top right of the project.


#### Part 2 - Navigating to _forked_ Repository
* Navigate to your github profile to find the _newly forked repository_.
* Copy the URL of the project to the clipboard.

#### Part 3 - Cloning _forked_ repository
* Clone the repository from **your account** into the `~/dev` directory.
* if you do not have a `~/dev` directory, make one by executing the following command:
* * `mkdir ~/dev`
* navigate to the `~/dev` directory by executing the following command:
* * `cd ~/dev`
* clone the project by executing the following command:
* * `git clone https://github.com/${MYUSERNAME}/${NAMEOFPROJECT}`






## How to Submit

#### Part 1 - _Pushing_ local changes to remote repository
* from a _terminal_ navigate to the root directory of the _cloned_ project.
* from the root directory of the project, execute the following commands:
* * add all changes
* * `git add .`
* * commit changes to be pushed
* * `git commit -m 'I have added changes'`
* * push changes to your repository
* * `git push -u origin master`

#### Part 2 - Submitting assignment
* from the browser, navigate to the _forked_ project from **your** github account.
* click the `Pull Requests` tab.
* select `New Pull Request`
* I spent a bulk of my time implementing the API connection functionality and then understanding its semantics, and after that deciding on an interface that would meaningfully present and manipulate information from the source. The park service provides several categories of information such as: parks, campgrounds, things to do, and more. Within each category any number of additional parameters could be supplied. I decided to provide two drop down menus for doing an information search, one for the main categories (such as parks, campgrouds), and other for the more fine-grained parameters within each of the main categories. Since the second set of search parameters is dependent on the first, the selection of dropdown list items in the second list would have to be dynamically populated in accordance to the choice in the first dropdown list. To keep the implementation simple, I chose a second parameter that is common to all of the main category searches; namely, the state (such as NY, SC, NC, etc.). In a nutshell, I dynamically build a query based on the selections by the user from both lists, and I send the result as raw JSON in the pane right below the selection boxes. I implemented the API search using XmlHttpRequest and "fetch". I got both to work, but I ended up using XmlHttpRequest.
47 changes: 43 additions & 4 deletions css/style.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
body {
background-color: navy;
/*font-family: 'Roboto', sans-serif;*/
font-family: 'Special Elite', cursive;
}

body, html {
height: 100%;
}

.gn-bg-img {

background-image: url("../img/blossom-bg.jpeg");
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 10px;
opacity: 60%;
}

.gn-intro-text {
font-family: 'Special Elite', cursive;
color: white;
font-weight: bold;
position: absolute;
font-size: 5vw;
top: 40%;
left: 72%;
transform: translate(-50%, -50%);
text-align: center;
}


.gn-footer {
border-top: 2px;
background-color: rgb(209, 227, 255);
border-top-color: transparent;
}

.gn-white-font-bg {
color: white;
-webkit-text-stroke: .3px black;
}

object {
height: 100vh;
width: 100vh;
.gn-dark-font-bg {
color: rgb(37, 5, 41);
-webkit-text-stroke: .1px black;
}
Binary file added img/blossom-bg.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/blossom.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed img/platonic-icosahedron.gif
Binary file not shown.
Binary file removed img/platonic-octahedron.gif
Binary file not shown.
Binary file removed img/platonic-pyramid.gif
Binary file not shown.
80 changes: 54 additions & 26 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,82 @@
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<head> <!-- header begins here -->

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">

<link href="./css/style.css" rel="stylesheet">
<script type="text/javascript" src="./js/header-functions.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

</head> <!-- header ends here -->
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<!-- Bootstrap CSS -->


<script type="text/javascript" src="./js/header-functions.js"></script>
<link href="./css/style.css" rel="stylesheet">


</head>

<body ">

<div class=" container">


<script type="text/javascript">
writeNavbarHtml();
</script>
</div>



<div class="container">
<div class="row">

<!--

<div class="col-3" style="height: 600px;">

<!-- ---------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------- -->
<body> <!-- body begins here -->
Just filler for now, hardcoded the height of 600px
</div>
-->


The quickest of brown foxes.
<div class="col-12" style="height: 600px">
<div class="gn-bg-img">

<p class="gn-intro-text" id="gn-intro">
Spring in<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Charleston.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A thing
to<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Remember
</p>
</div>

</div>

</div>
<div class="row">
<div class="col-12">
<script type="text/javascript">
writeFooterHTML();
</script>
</div>

<!-- ====================================================== -->
<!-- ====================================================== -->
<footer>
<!-- footer of page begins here -->
<script type="text/javascript" src="./js/footer-functions.js"></script>
</footer> <!-- footer of page ends here -->
<!-- ====================================================== -->
<!-- ====================================================== -->
</div>
</div>

</body>
<!-- ---------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------- -->

<!-- body begins here -->



<footer>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<!-- These are loaded by footer-functions.js below -->

<script type="text/javascript" src="./js/footer-functions.js"></script>

</footer> <!-- footer of page ends here -->




</html>
46 changes: 44 additions & 2 deletions js/footer-functions.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,44 @@
w3IncludeHTML();
document.write('<script type="text/javascript" src="./js/file-inject.js"></script>');

loadBootstrapScripts();


function loadBootstrapScripts() {
document.write(`
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
crossorigin="anonymous"></script>
`);

}


//email field validation
let emailField = document.getElementById("inputEmail4");
console.log(emailField);

emailField.addEventListener('blur', validateEmail);


function validateEmail(e) {
console.log("Just lost focus");
let regex = new RegExp(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/);
let regex2 = new RegExp(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/);


let inputText = e.target.value;
if (inputText == "") {
console.log("You entered nothing");
//alert("you entered nothing");
}
if (inputText.match(regex2))
alert("Great format!");
else
alert("Incorrect email format!");
}

Loading