Projects
1. Midterm Project
Section titled “1. Midterm Project”The midterm project is to create a single page web site that dynamically builds content cards based on ai generated data that is imported into the main script. The user will see all the generated cards as soon as the page loads. They can click on a card header to remove the card from the page, and they can filter the order of the cards by selecting a field from a dropdown list and clicking a sort button.
The basic project structure should look like the following.
- .gitignore
- favicon.ico
- index.html
Directorycss
- main.css
Directoryimg
- logo.png
Directoryjs
- data.js
- main.js
Create a new folder and Github repo for this project. Copy the files from the Project Exercise into this project folder.
Data Creation
Section titled “Data Creation”You can create the data by yourself or by using an AI chatbot. It should have this general structure.
//a single data object declared as a const and exported//the variable can be called whatever you wantconst info = { last_updated: '', //a valid date string or timestamp results: [ { id: '' }, // a series of objects inside the results array { id: '' }, ],};
export { info }; //export your data objectThe content of the data should be about a movie or tv show that you like. It could be a list of cast members or episodes or reviews. You choose. You can find the images that you want to use online. Resize your images to be similar sizes and save them in your img folder.
The results array should have at least 12 objects.
Each object should have a unique id string plus at least 6 properties, including an image.
General Requirements
Section titled “General Requirements”The main.js file should be loaded as a module and should import your data object from the data.js file. Here is a sample starter for the main.js file for you to use if you wish.
import myDataArray from './mymoviedata.js';
document.addEventListener('DOMContentLoaded', init);
let arrayCopy = []; //so deletes can happen
function init() { // set up page, // make a copy of the imported array // populate list of fields, // build cards html, // add listeners,}function addListeners() { //add event listeners to page for //form submit || changing select value //card section click}function buildCards(arr) { //turn the Array:arr passed in into cards using the innerHTML String method //replace the old list of cards.}function displayFields(obj) { //populate the <select> for sort selection. //based on the fields inside Object:obj}function removeCard(ev) { //ev is the click event somewhere in the card container //remove a card based with the matching Number:id //when user clicks on a card header}function sortBy(ev) { //ev is the submit event from the form //sort the displayData based on the String:field from the selected option //call the buildCards method and pass the sorted array}function changeSelection(ev) { //change text on screen indicating the current sort field being used //call the sortBy function}After the page loads, the user should be able to see all the cards built using the imported data. Each card should have a title and at least three other fields of information. Each <div class="card"> should have a data- attribute that holds the id of its imported array object.
Your script should read the names of all the properties from one of the imported array objects. Add new <option> elements to the <select> for each field, except for the id field.
Clicking anywhere on any card, should trigger an event listener which will find the <div class="card"> that contains the clicked header and extract the id from the data- attribute. Then use the Array filter method to remove the object with the matching id from the Array.
On each load of the page, make a full deep copy, with structuredClone, or a shallow copy with the spread operator, of the imported array so it can be used and modified independently of the imported array. We do this in case, in the future, we want to add a reset button to copy the full array back into our created displayData array. If you want to challenge yourself a bit, add this feature to the page.
When the user clicks on the sort button in the form, it will trigger the form submit event. We need to listen for this event and call a function to sort the displayData array based on the selected field. If the selected value from the <select> is empty then we should exit from the sort function. After sorting the displayData array, pass it to the function which replaces the current cards with the new sorted list of cards.
Design
Section titled “Design”There is a demo video below that shows a rough example of how the site will work. Do NOT try to match the interface or colour scheme.
Create your own colour scheme. Use CSS variables for all the colours, and declare them inside :root{ }. All the colours in the CSS should be a variable.
Use a single imported Google Font. Create a CSS variable for the font stack inside :root{ } to hold the font stack.
Use different font-sizes, font-weights, letter-spacing, and line-heights to create your typographic hierarchy. Create 5 font-size CSS variables that use clamp() for the values of the font-sizes. ALL text on your page should use 1 of those 5 font-sizes.
Each card should show an image, a title, and three other property values. Labels for the values are not needed if the values are obvious. Eg: show titles, actor name, etc. The id for each item should be put into the card’s HTML as a data- property.
The content on the page should have spacing and alignment that meets good design practices.
Rough Demo
Section titled “Rough Demo”You do not need to match this UI exactly. Make your own design.
midterm demo
Submission
Section titled “Submission”Please post general questions about this project on the Slack #mad9014 channel so everyone can see the answers.
See BS LMS for submission instructions.
Due in Week 7
2. Final Project
Section titled “2. Final Project”For the Final Project we will be building a Quiz Game web app. You will be using two APIs https://dummyjson.com/ as the source for user authentication when logging in, and https://opentdb.com/ as the data source for your web app trivia.
The opentdb is free and requires no api key. It has questions across a broad range of topics including: Entertainment, sports, mythology, science, geography, history, politics, celebrities, art, animals, celebrities, and more. This page will let you experiment with different parameters and get the URL for sample data sets from the API.
The website needs to have three HTML files: index.html (Home/Login), main.html (Main), and quiz.html (Quiz).
Home page
Section titled “Home page”The home page is the login screen for the website. It should display a login form centered on the page. No logout link should be shown in the header bar.
When this page loads it should automatically check to see if an authorization token exists in document.cookie. Using a fetch call to dummyjson.com/auth/me a valid response should be returned. If a valid response is return then redirect the user to the main page.
If no token exists, then wait for the user to submit the login form. The user’s username and password should be sent to dummyjson.com/auth/login to get a valid response with a token. The token should saved as a cookie.
Main page
Section titled “Main page”The main page will display a logout link in the header, plus there should be several things in the main area of the page:
- The number of quizzes saved in the local cache.
- A button to download another quiz from the
opentdbAPI and save it in the cache. - A button start a quiz.
- A button to resume a currently active quiz.
When the user clicks the download button, a call to the opentdb API will download a quiz and save it in the Cache as a JSON file with any other previously saved quizzes. After a new quiz is saved in the Cache, the text display of how many quizzes exist in the cache should be updated automatically.
Use the multiple choice question type from the API.
When a user clicks the button to start a quiz, then several steps need to take place. First, download a json file from the quiz cache. Second, add a couple custom properties to the quiz data - the current index of the quiz question being asked, the count of how many questions have been answered correctly. Third, save the contents of that quiz in LocalStorage. Fourth, the json file should be removed from the quiz cache.
The button to resume the current quiz should only appear if there is a quiz in localStorage AND the current question index property is less than the number of questions in the quiz.
Clicking on either the start or resume button will navigate to the quiz page.
Quiz page
Section titled “Quiz page”The quiz page will use an HTML template to display the current question and it’s possible answers as radio buttons in a form. The question text and the label text for the radio buttons should be decoded so that no characters entities are shown.
Just like the main page, check for a valid token in the cookies and if one does not exist then redirect the user back to the login page.
After answering a question there should be an animated visual indicator if the question was answered correctly. This animation should appear after the user clicks the button to submit their answer. After the animation, update the quiz data with the new question index, and the form should be refreshed with the next question. Do NOT reload the page. Make sure to prevent the submission of the form.
The name of the question category and the current question number should both be displayed somewhere on the page.
After the user answers all the questions, then instead of the form, should a message to the user about how many questions they have answered correctly, plus a button to take them back to the main page.
Feature Requirements
Section titled “Feature Requirements”This web app needs to have the following web app features:
- Authorization token needs to be saved in
document.cookie. - When the user clicks the Logout link, the cookie should be removed by changing the Max-Age or Expiry date.
- The current quiz object needs to be saved in localStorage.
- The current quiz object in localStorage should have properties for the number of correct answers and the index of the current questions being asked.
- Quiz objects for future quizzes should be saved in a cache.
- The main and quiz pages need to check for a valid token or redirect to the login page.
- The home/login page should redirect to the main page if a valid token already exists.
- The pages should be able to run without errors.
- Any error messages in the console should be ones output inside by
try catchor.catch(). - The HTML pages should only have one script tag and load the
main.jsfile as a module. - All the code for
localStorageorcacheshould be inside a file calledstorage.js, whose methods are imported intomain.js. - There should be an
error.jsfile with two custom errors -FetchErrorandCacheError. - All fetch and cache code that uses promises should have a
.catch()method. - All fetch and cache failures should
throw newerror of theFetchErrororCacheErrortype. - You should have a utility JS file, with generic functions like the array shuffle function.
- AI SHOULD NOT be used to generate the code for this assignment. This is the demonstration of understanding of material that will be required knowledge next semester.
Design
Section titled “Design”You can use either your own CSS or TailwindCSS to style the three pages.
There needs to be one CSS file shared across the three HTML files.
There should be a google web font with its three links in the head of all three pages and used in your CSS file.
You need to have a colour scheme and typographic scale defined as a series of css variables inside the :root{ } style.
Good design practices must be followed on all pages, and both the CSS and HTML should be accessible.
Video Demo
Section titled “Video Demo”Demo done in class.
Deployment
Section titled “Deployment”Since the preparatory exercise for this project used the main branch in the github repo, we will need a new branch. Create a new branch called final. It will be a copy of the code in the main branch at the point when it is created.
You can use either Vercel or Netlify to host this web app.
When configuring your hosting, be sure to point to the main branch when setting up the hosting.
Submission
Section titled “Submission”Please post general questions about this project on the Slack #mad9014 channel so everyone can see the answers.
See BS LMS for submission instructions.
You will be submitting a Github.com link for your repo, plus a link for the Netlify or Vercel hosted site, plus you need to invite Steve to your private project repo.
Due in Week 15