# Assignment List

# Assignments

  1. Github Hosting
  2. DOM Manipulation
  3. JS Events
  4. API Fetch
  5. Data Storage

# 1. Github Hosting

Start by downloading this project in a .zip file.

You will be turning this project into your own hosted Github website.

Expand the zip folder and open the folder in VSCode.

Next, edit the index.html file and add your name in the <header> <h2>. Then save the edits.

Next, you will need to turn this project folder into a Git project by opening the Terminal panel in VSCode and running the git init command. Now your project IS a git repository.

Now add a .gitignore file at the root of your project folder. The .gitignore file should contain these two lines:

.DS_Store
node_modules/
1
2

Then run the git add and git commit commands so Git will be tracking your project files and recording the changes.

Now you need to set up a connection between Github and this Git repository. Do this by visiting the Github website (opens new window). Make sure you are logged in to the website using the Github account that you created with your @algonquinlive.com email address.

Create a new PUBLIC Github Repository WITHOUT a Readme file and WITHOUT any licence information.

Save the URL of your new public github repository and go back to VSCODE.

Run the command in the terminal panel:

git remote add origin <URL-OF-YOUR-GITHUB-REPO>
1

Once you have added the remote url to your local git repo, now you can upload the project to Github from the Terminal panel. Here is the command to upload your project

git push origin main
1

You should be able to refresh the Github repository webpage in the browser and immediately see the uploaded files.

Now in your index.html file under the main create a section and add the following information:

  • A professional image of yourself
  • Description list with the following information
    1. Student number
    2. Name of the Program that you are taking
    3. Course code and name in which you are completing this assignment
    4. one interesting fact about you

Proceed by repeating the stages of staging, committing, and pushing your recent changes to the GitHub repository. This action will result in a new commit.

Next, go to the Settings tab for your Github copy of the repository and look for the menu entry called Pages. It should look like this:

Github pages screenshot

Set it to point to your main branch at the /root and click Save.

The page should display the URL for the hosted version of the project.

Within a couple minutes you should be able to see the actual hosted version of the project. If you click on the actions tab at the top, then you can see if the creation of the site is pending, being processed, or complete.

Note If you set your repository to PRIVATE then you will need to have also created your Github Education account AND you will need to go to the Collaborators section of the settings plus add your instructor as a collaborator for the project so they can access your repository.

# Submission

Due Date **Week 6**

(See BS LMS for exact date)

You will need to post TWO URLS in BS LMS on the assignments page as your submission.

  1. The URL for the Repo.
  2. The URL for the hosted Github Pages website.

# 2. DOM Assignment

Remember that you can post questions on the #mad9014 channel in Slack about this assignment.

Start by using ChatGPT to create a JavaScript array of objects with a prompt that is similar to this:

Can you please generate a JavaScript Array of eight objects? Each object should include a uuid plus 4 properties about characters from the tv show supernatural.

Change the subject of the data to something that you are familiar with - movies, food, tv shows, car parts, tropical fruit, cheese, etc. Make sure that there are 4 properties plus a unique id (uuid) for each object. Do NOT use the same subject for your data. Create your own data.

The resulting data should be saved in a file called data.js, which will be imported by your main JS file at the top of main.js.

The main JS file should be loaded by the HTML file using type="module" in the script tag. This way, it will not run until after the HTML is loaded and it will be allowed to import the data.js file.

The HTML should also include a <link> that loads your CSS, and ABOVE YOUR CSS, import a google font and a normalize/reset CSS file that is loaded above your own CSS file.

The Google font needs three link tags. One for the CSS that will fetch the font file, and two for the rel="preconnect".

Keep your normalize/reset CSS in a separate file to your main CSS file.

The following is an example of the sequence of the tags in the <head> of EVERY HTML PAGE THAT YOU BUILD this semester. The Content-Security-Policy is something that we will discuss later in the semester.

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="content-security-policy" content="default-src *;" />
  <title>The name of the website and current page</title>
  <link rel="preconnect" href=" for the google font css domain " />
  <link rel="preconnect" href=" for the google font font domain " />
  <link rel="stylesheet" href=" the url for the google font css" />
  <link rel="stylesheet" href="./css/normalize.css" />
  <link rel="stylesheet" href="./css/main.css" />

  <script type="module" src="./js/main.js"></script>
</head>
1
2
3
4
5
6
7
8
9
10
11
12
13

Your HTML body should have a <header> with an <h1> that includes your name, plus a <main> element, which is where the data will be displayed on the page.

Inside your main JS file, you can use an IIFE or a function triggered by a DOMContentLoaded event to start the script running. Inside the initial function you will call THREE functions. Each function will read the imported data and generate the same HTML inside <main>. So, you will have the same content shown three times on the page.

The functions need to demonstrate three different approaches to generating new HTML content on a page.

  1. <template> in the HTML which will be copied with cloneNode() and appended to a single documentFragment.
  2. document.createElement() for each piece of HTML which will be appended into a single documentFragment.
  3. Appending once to the .innerHTML of the <main> with data read from imported array with map().join().

In all three of these functions you are only allowed to, set the innerHTML of <main> or call append() to add elements to the <main> element (the DOM), ONCE. Do not update the page more than once per function.

Your code needs to be saved on GitHub in a private repo. You can call the repo whatever you like but you will have to invite your instructor as a collaborator on the repo.

# Demo Video

Here a short video explaining the goal of the assignment and explaining some of the details.

# Submission

Due Date **Week 7**

(See BS LMS for exact date)

Create a private Github Repo.

Open BS LMS and go to the Activities > Assignments page.

Go to the DOM Assignment.

Submit URL for private GitHub Repo.

Submit URL for Github Pages hosted version.

Invite griffis@algonquincollege.com to your private repo.

# 3. Events Assignment

Remember that you can post questions on the #mad9014 channel in Slack about this assignment.

For the Events assignment, start with the finished version of your previous assignment. If your previous assignment went off the rails, or you don't like what you did and you would like a clean starter version from Steve, let him know. Once the other students have all submitted assignment 2 then he can give you a starter copy to use for this assignment.

In this assignment you will be adding an <input> element inside of a <nav> below the header. The input will be connected to a <datalist>. Your script needs to load the <detail> and <summary> elements with data, just like in assignment 2. Then, you will call another function that adds all of the names to the <option> elements inside of the <datalist>. Remember that <input> elements should always be placed inside of a <form> element.

Once the details and the datalist are built, then you need to add some event listeners.

  1. An event listener for the input event must be added to the <input> element. This will trigger a function each time the value inside the input changes.
  2. An event listener for the toggle event must be added to each of the <details> elements on the page. These events all trigger the same function each time the user clicks on a details element and toggles it open or closed.
  3. An event listener for the click event must be added to the <main> element. This will call a function when the user clicks anywhere inside the main element.
  4. An event listner for the submit event must be added to the <form> element. This function only needs to preventDefault on the event to stop the form submitting and the page reloading.
  5. An event listener for the DOMContentLoaded event must be added to the document object. This event listener will call an initial main function for your website and start the other code running.

ALL EVENT LISTENERS SHOULD CALL A NAMED FUNCTION. DO NOT USE ANONYMOUS FUNCTIONS FOR THE LISTENERS. DO NOT NEST FUNCTIONS INSIDE FUNCTIONS.

# input event function

As the user types in the input, the datalist will show the possible matches to what the user has typed. Additionally, the input event gets triggered as the user types. The input event contains a target property that will reference the <input> element. The input element has a value property that will tell you what the user has typed. The function will start looking like the snippet below.

function handleInput(ev) {
  let input = ev.target;
  let typedValue = input.value;
}
1
2
3
4

Once you have the value that the user has typed so far, loop through all of the <details> elements looking for a matching name. All details that have a <summary> with a name that includes the text from the input event value, should remain visible. All other details elements should be set to display: none. You can use a CSS className that you add and remove from the details to show and hide them. This is the recommended approach, instead of element.style to target individual properties.

# toggle event function

The toggle event has a property called newState which will be either open or closed. You can use that when determining if the toggled details element is open or closed.

When the user toggles a details element, retrieve either the name or the uuid value from that element or the summary. Then, loop through all of the details elements on the page and compare their name or uuid value. If they match then either add or remove the open attribute on the details element based on the value of the newState property.

This will make the matching details elements open or close at the same time.

# click event function

Clicking on the main element will change the background color and font color of the header and h1. The function should generate a random integer between 0 and 359. Then use the CSS hsl() method to set the header element background color value and the h1 element color value. The random number will be the hue value for the color.

For the background-color and color, we need to have accessible colors. So, for the lightness value in the hsl(), use something like 20% for one and 80% for the other. The number is not important, as long as there is a separation of at least 50%. Use the same hue, but different lightness values.

The saturation value should be the same for both colors. It can be randomly generated with each function call or a hard-coded value.

# Demo Video

# Submission

Due Date **Week 10**

(See BS LMS for exact date)

Create a private Github Repo.

Open BS LMS and go to the Activities > Assignments page.

Go to the JS Event assignment.

Submit URL for private GitHub Repo.

Submit URL for Github Pages hosted version.

Invite griffis@algonquincollege.com to your private repo.

# 4. Fetch Assignment

Remember that you can post questions on the #mad9014 channel in Slack about this assignment.

For this assignment you will be building a SPA that simulates a login / logout process as well as fetching and displaying data from and API request. All of the fetch calls will be made to the https://dummyjson.com (opens new window) API, which provides testing data for developers to build proof-of-concept type apps.

When the page first loads, the script needs to check if the person is logged in.

The determining factor of whether or not a user is logged in, is the existence of an object in sessionStorage which includes a JWT token.

When the web app first loads, the default appearance of the page is a welcome message along with a form that requests a username and email. In the sample HTML below, this is the <section id="authentication"> element.

If the user is already logged in, then we change what is shown to hide the login form and show the part of the page that will contain the post data. In the sample HTML below, this is the <section id="authenticated"> element.

While the web app tries to fetch the post data, a message and loader animation need to be shown, until the data has been returned from the API. Once the data has been returned, then the message and animation can be hidden and the data converted into HTML on the page. The data will be added to the <section class="loaded"> element which is inside the <section id="authenticated"> element.

The post data from the dummyjson API needs to be the authorized version - https://dummyjson.com/auth/posts. This means that you must pass the Authorization: "Bearer token" header along with the request.

Inside the <header> there is a logout button that is only shown after the user logs in and the screen is updated. After the user is logged in, you also need to show information about the user - their firstName, lastName, and image. If you want you can display this information in a different place on the page than in the <h1>. You can also show different information, as long as you are showing at least three things about the user, to identify them.

Clicking the logout button will delete the token and user information from sessionStorage, delete all the post information from the DOM, hide the logout button, remove any user details from the screen, and show the login form section again.

When errors occur with your fetch calls, use a <dialog> to display the error messages.

The API end points you will use are:

# Starter Code

Here is a sample version of the HTML body that you can use.

<body class="public">
  <header>
    <h1>Authorized Posts <span></span></h1>
    <nav class="logout">
      <a href="#logout" id="logout"><img src="./img/account_circle_24dp.svg" /> Log Out</a>
    </nav>
  </header>
  <main>
    <section id="authentication">
      <h2>Welcome to the Site</h2>
      <p>To access the content, please login below.</p>
      <form id="login_form">
        <label for="username">Username</label>
        <input type="text" id="username" name="username" maxlength="30" required autocomplete="username" />
        <label for="pass">Password</label>
        <input type="password" id="pass" name="pass" maxlength="30" required />
        <span>&nbsp;</span>
        <button id="btnLogin"><img src="./img/account_circle_24dp.svg" /> Log In</button>
      </form>
    </section>
    <section id="authenticated">
      <section class="loading">
        <div class="coffee">
          <div></div>
          <div></div>
          <div></div>
        </div>
        <p>Waiting for the good stuff...</p>
      </section>
      <section class="loaded">
        <!-- post data goes here -->
      </section>
    </section>
  </main>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

You are free to edit and change this HTML if you want.

A good practice to follow when you want to change parts of the page to display is add classnames to the <main> or <body> elements. These classes indicate the current state of the page. Here are some examples.

<body class=""></body>
<body class="authenticating"></body>
<body class="authenticated"></body>
<body class="fetching"></body>
<body class="loaded"></body>
1
2
3
4
5

Then, in your CSS you write styles that will change parts of the page. For example:

body {
  /* default state when page loads */
  section#authentication {
    /* public content */
    display: block;
  }
  section#authenticated {
    /*private content */
    display: none;
  }
}

body.loaded {
  /* user logged in and data also fetched */
  section#authentication {
    display: none;
  }
  section#authenticated {
    display: block;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Continue this approach to style other aspects like logout buttons, loaders and spinners, etc.

# Demo Video

# Challenge Tasks

Here are some additional features that you can add to your web app. Think of these as challenges for yourself to improve your version of this web app for your portfolio. These are not required for grades.

  • Use a custom Error object that you can throw when fetch calls fail. This error object should contain the details of the Response object, like the status code and url.
  • Create a common modal dialog that is self-removing and that can be used to display success and failure messages at any time. It should have styling that matches the status - info, success, or failure. Use this dialog to tell important things to the user.
  • Add more of the POST data to the page after the request, such as the likes, dislikes, and views. Add colors, icons, and interactivity to these.
  • Add some styling and interactivity to the tags for each post.
  • Add pagination for the posts so only 10 are shown at a time.

# Submission

Due Date **Week 12**

(See BS LMS for exact date)

Create a private Github Repo.

Open BS LMS and go to the Activities > Assignments page.

Go to the Fetch assignment.

Submit URL for private GitHub Repo.

Submit URL for Github Pages hosted version.

Invite griffis@algonquincollege.com to your private repo.


# 5. Storage Assignment

Remember that you can post questions on the #mad9014 channel in Slack about this assignment.

For this assignment we are working with fetch, the DOMContentLoaded event listener, the Page Visibility API and its visibilitychange event listener, and the Cache API.

Each time the page loads(DOMContentLoaded event), or switches from the inactive tab to the active one (visibilitychange event), a fetch call will be made to the picsum.photos API to request a random image that is 800px wide by 200px high.

When the image is retrieved is needs to be set as the src of the <img> element in the <main> element of the page. To add the fetched image to the image element, you will need to use the Response blob() method instead of the json() method. Then use the URL.createObjectURL() method on that blob to create a URL that can be passed to the image element.

The page also needs to have a <header> element with an <h1> - showing your name. Use a CSS text-shadow on your name to make sure that it can be read on any background. Use CSS to keep the size of the background-image in the header such that it will always make the image cover the whole header, but maintain the original aspect ratio. The <header> should have NO background image until the user selects one.

The <main> element also needs to have a button, which will save the image, currently displayed in the <img> into the Cache API, using the url /header-background.jpg. Once saved, update the background of the <header> so that it is filled with the saved image.

Each time the visibilitychange event is triggered and indicates that the page is the current active one, check the Cache API to see if there is a /header-background.jpg image. If it exists, retrieve it and set it as the background for the <header>.

When the page first loads, use a placeholder image in the <main> <img> element. This will be shown until the fetch completes and new image is shown. You can do this through the HTML or in the JavaScript.

In your script:

  • No function should be nested inside another function
  • All event listeners should use named, not anonymous functions
  • fetch should ONLY be called ONCE per image. Fetch the image for the main area when the page loads or when the page becomes active again.
  • Do NOT call fetch again when you want to put it into the header. You already have the image. You can either use a global variable to hold a copy of the Response or Blob after fetching it the first time, or you can use the more complicated approach of copying the image from the main section into an HTML <canvas> element, to create a new blob or base-64 string that you can save to the Cache and put in the header. The global variable is a much simpler solution.

# Starter Code

Here is some basic starter code that you can use or create your own.

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Storage Assignment</title>

  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="css/normalize.css" />
  <link rel="stylesheet" href="css/main.css" />
  <script src="js/main.js" type="module"></script>
</head>
<body>
  <header>
    <h1>Steve Griffith</h1>
  </header>
  <main>
    <p>If you like this image, click the button below to save it as the header background image.</p>
    <p><img src="https://dummyjson.com/image/800x200" alt="" /></p>
    <p><button id="btnSave">Save Image and Set as Header Background</button></p>
    <!-- clicking this button puts the image into the cache AND
     sets the background image for the header. -->
  </main>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Demo Video

# Submission

Due Date **Week 13**

(See BS LMS for exact date)

Create a private Github Repo.

Open BS LMS and go to the Activities > Assignments page.

Go to the Storage assignment.

Submit URL for private GitHub Repo.

Submit URL for Github Pages hosted version.

Invite griffis@algonquincollege.com to your private repo.

Last Updated: 12/17/2024, 1:23:19 PM