First commit

This commit is contained in:
2025-09-10 14:42:57 -04:00
commit 1d12903e4e
65 changed files with 3587 additions and 0 deletions

255
Lab 10/storadons.html Executable file
View File

@@ -0,0 +1,255 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Storadons</title>
<link rel="icon" href="https://fav.farm/🦕">
<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=Open+Sans:wght@800&family=Roboto&display=swap" rel="stylesheet">
<style>
/* JMU Slate Gray: #333333 Ice Blue: #8EE4D7 JMU Purple: #450084 Teal: #009698 JMU Light Gold: #F4EFE1 */
body {
margin: 0;
display: flex;
height: 100vh;
font-family: Roboto;
}
main {
background-color: #F4EFE1;
color: #333;
flex-grow: 1;
padding: 1rem;
}
aside {
border-inline-start: 1rem solid #009698;
background-color: #450084;
color: #8EE4D7;
max-width: 33vw;
padding: 1rem;
}
main,
aside {
overflow-y: scroll;
}
aside a {
color: #F4EFE1;
}
aside a:visited {
color: #009698;
}
header {
display: flex;
align-items: baseline;
gap: 1rem;
}
h1 {
flex-grow: 1;
}
#downloads {
display: none;
}
code {
background-color: #00000099;
}
</style>
</head>
<body>
<main>
<header>
<h1>🦕 Storadons</h1>
<button id="share" type="button">Get Sharable URL</button>
<button id="export" type="button">Export</button>
<form action="#" id="import-form">
<input type="file" name="import-file" id="import-file" required>
<button id="import" type="submit">Import</button>
</form>
</header>
<form id="new-item-form" action="#">
<label for="item">New todo item</label>
<input type="text" name="item" id="item">
<button type="submit">Add</button>
</form>
<ol id="items"></ol>
<div id="downloads"></div>
</main>
<aside>
<section>
<h2>Overview</h2>
<p>Look at this excellent little TODO app! 🤩 The code as provided implements these features:</p>
<ul>
<li>adding items to the todo list</li>
<li>listing the new item at the end of the existing to do list items</li>
</ul>
</section>
<hr>
<section>
<p>Know what might be neato? I think it needs MOAR ... 🔔</p>
<h2>Part 1: Persistodon</h2>
<p>It'd be nice if we could close the window and not lose all of our data.</p>
<h3>TODO (Part 1)</h3>
<p>There are <code>// TODO (Part 1)</code> comments in the JavaScript code to guide your way while you add
these features:</p>
<ol>
<li><em>persist</em> the todo items to <code>localStorage</code> as they are added to the to do list</li>
<li><em>load any todo items from <code>localStorage</code> when the page loads </em></li>
</ol>
<h2>Part 2: Sharasaurus</h2>
<p>How could we view the same list on our phone as we are viewing on our laptop? Share the list with a friend?
</p>
<h3>TODO (Part 2)</h3>
<p>There are <code>// TODO (Part 2)</code> comments in the JavaScript to guide you in your way while you add these
features:</p>
<ol>
<li>notice if the page was passed a query string and to populate <code>localStorage</code>
initially with the items in the query string</li>
<li>modify the <code>Get Sharable URL</code> button so that it updates the url so that all of the todo
items currently stored in <code>localStorage</code> are encoded in the <code>query string</code> in the
browser's address bar</li>
</ol>
</section>
<hr>
<section>
<h2>Part 3: Transportodon</h2>
<p>URLs have a pretty short length limit. What if we add too much stuff to fit into the URL? How can we share a
file version?</p>
<h3>TODO (Part 3)</h3>
<p>There are <code>// TODO (Part 3)</code> comments in the JavaScript to guide you to add these features:</p>
<ol>
<li>modify the <code>Export</code> button so that it creates a Blob containing the items from
<code>localStorage</code>
</li>
<li>modify the <code>Import</code> button to replace the items in <code>localStorage</code> with the file's text
content</li>
</ol>
</section>
</aside>
<script>
// get the DOM elements
const form = document.getElementById('new-item-form');
const input = document.getElementById('item');
const list = document.getElementById('items');
function addItemToList(item) {
const newLi = document.createElement('li')
newLi.textContent = item;
list.append(newLi);
}
function populateFromLocalStorage() {
// TODO (Part 1)
// Retrieve the stored items from localStorage. Parse the returned string using JSON.parse
// and pass each item in the array to addItemToList.
const todosString = localStorage.getItem('todos')
if (!todosString) return
const todos = JSON.parse(todosString)
todos.forEach(addItemToList)
}
form.addEventListener('submit', (ev) => {
// TODO (Part 1)
// Get the new item from the input field and pass it to addItemToList. Get the array of
// items currently stored in localStorage and add the new item to the end of the list.
// If there aren't any items in localStorage (because the page was just loaded for the
// first time), make an array of just the new item. P.S. don't forget to prevent the
// page from reloading when the form is submitted and clear the input field.
ev.preventDefault()
const newTodo = input.value
const todosString = localStorage.getItem('todos')
const todos = todosString ? JSON.parse(todosString) : []
todos.push(newTodo)
localStorage.setItem('todos', JSON.stringify(todos))
addItemToList(newTodo)
})
function populateLocalStorageFromURLSearch() {
// TODO (Part 2)
// Given the URL index.html?first&second, the query string is ?first&second and can be
// accessed as location.search. If a query string is passed as part of the URL, replace
// the localStorage items with an array created by splitting the query string. In the
// previous example, the new array should be [ 'first', 'second' ].
const queryParams = new URLSearchParams(location.search)
if (queryParams.size == 0) return
localStorage.setItem('todos', JSON.stringify(Array.from(queryParams.keys())))
}
// get url
document.getElementById('share').addEventListener('click', (ev) => {
// TODO (Part 2)
// Generate a sharable link of the current items. The URL should consist of the
// current location (window.location), but add on '?' and a string version of the
// items with an '&' between each. For instance, if the URL is http://foo.com/index.html
// and the list consists of [ 'first', 'second' ], the sharable URL should be
// http://foo.com/index.html?first&second
// Update window.location to this URL so you can copy and paste from the browser's
// URL bar.
// CAUTION: If the URL already has a query string, that should NOT be included in
// this new version. As a hint, use console.log to print out the window.location
// object and see what parts you actually need.
const sharableURL = new URL(location.toString())
const todosString = localStorage.getItem('todos')
todosString ? sharableURL.search = `?${JSON.parse(todosString).join('&')}` : ''
window.location = sharableURL.toString()
});
// export blob
document.getElementById('export').addEventListener('click', (ev) => {
// TODO (Part 3)
// Generate a Blob of the localStorage items. See Week 11 slides for creating
// a blob, a link, and a download action. You'll create the Blob from the
// items in localStorage.
const blob = new Blob([localStorage.getItem('todos')], { type: 'text/plain' })
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = 'data.json'
link.click()
window.URL.revokeObjectURL(url)
link.remove()
});
// import from file
let importForm = document.getElementById('import-form');
importForm.addEventListener('submit', (ev) => {
// TODO (Part 3)
// Get files[0] from the import-file input when the form is submitted.
// Use .text() on the file to get a Promise that resolves to the file
// contents. Store the resolved data as the items in localStorage, then
// use populateFromLocalStorage() to load the items. Do not forget to
// stop the page from reloading.
ev.preventDefault()
const file = importForm['import-file'].files[0]
file.text().then((text) => {
localStorage.setItem('todos', text)
populateFromLocalStorage()
})
});
// initialize the page
(function () {
populateLocalStorageFromURLSearch();
populateFromLocalStorage();
})();
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

131
Lab 11/bootstrap.html Executable file
View File

@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="author" content="Nicholas Tamassia">
<title>CSP Test</title>
<!-- Insert your CSP policies here. Do not change anything else in this file. Well, okay,
you can change your name as the author just above this comment. -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; frame-src 'self'; style-src https:;">
<link rel="stylesheet" href="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/styles.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="nav">
<a class="nav-link border bg-light" href="local.html">Local</a>
<a class="nav-link border bg-light" href="bootstrap.html">Bootstrap</a>
<a class="nav-link border bg-light" href="noframe.html">No frame</a>
</ul>
</nav>
<div class="container">
<div class="row my-4">
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline CSS</p>
</div>
<div class="card-body">
<p style="font-size: 2em;">Large text</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local CSS file</p>
</div>
<div class="card-body">
<p class="h5">Level 5 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote CSS file</p>
</div>
<div class="card-body">
<p class="h6">Level 6 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline JavaScript</p>
</div>
<div class="card-body">
<p>
<script>document.write('This is inline scripting');</script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local JS file</p>
</div>
<div class="card-body">
<p>
<script src="local.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote JS file</p>
</div>
<div class="card-body">
<p>
<script src="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/remote.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Display an image</p>
</div>
<div class="card-body">
<img src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"
alt="Image should not load due to CSP">
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local image in iframe</p>
</div>
<div class="card-body">
<iframe src="JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"></iframe>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote image in iframe</p>
</div>
<div class="card-body">
<iframe src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%"
height="50px"></iframe>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

130
Lab 11/index.html Executable file
View File

@@ -0,0 +1,130 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="author" content="Nicholas Tamassia">
<title>CSP Test</title>
<!-- Insert your CSP policies here. Do not change anything else in this file. Well, okay,
you can change your name as the author just above this comment. -->
<link rel="stylesheet" href="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/styles.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="nav">
<a class="nav-link border bg-light" href="local.html">Local</a>
<a class="nav-link border bg-light" href="bootstrap.html">Bootstrap</a>
<a class="nav-link border bg-light" href="noframe.html">No frame</a>
</ul>
</nav>
<div class="container">
<div class="row my-4">
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline CSS</p>
</div>
<div class="card-body">
<p style="font-size: 2em;">Large text</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local CSS file</p>
</div>
<div class="card-body">
<p class="h5">Level 5 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote CSS file</p>
</div>
<div class="card-body">
<p class="h6">Level 6 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline JavaScript</p>
</div>
<div class="card-body">
<p>
<script>document.write('This is inline scripting');</script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local JS file</p>
</div>
<div class="card-body">
<p>
<script src="local.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote JS file</p>
</div>
<div class="card-body">
<p>
<script src="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/remote.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Display an image</p>
</div>
<div class="card-body">
<img src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"
alt="Image should not load due to CSP">
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local image in iframe</p>
</div>
<div class="card-body">
<iframe src="JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"></iframe>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote image in iframe</p>
</div>
<div class="card-body">
<iframe src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%"
height="50px"></iframe>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

131
Lab 11/local.html Executable file
View File

@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="author" content="Nicholas Tamassia">
<title>CSP Test</title>
<!-- Insert your CSP policies here. Do not change anything else in this file. Well, okay,
you can change your name as the author just above this comment. -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'; frame-src 'self' https:;">
<link rel="stylesheet" href="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/styles.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="nav">
<a class="nav-link border bg-light" href="local.html">Local</a>
<a class="nav-link border bg-light" href="bootstrap.html">Bootstrap</a>
<a class="nav-link border bg-light" href="noframe.html">No frame</a>
</ul>
</nav>
<div class="container">
<div class="row my-4">
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline CSS</p>
</div>
<div class="card-body">
<p style="font-size: 2em;">Large text</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local CSS file</p>
</div>
<div class="card-body">
<p class="h5">Level 5 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote CSS file</p>
</div>
<div class="card-body">
<p class="h6">Level 6 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline JavaScript</p>
</div>
<div class="card-body">
<p>
<script>document.write('This is inline scripting');</script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local JS file</p>
</div>
<div class="card-body">
<p>
<script src="local.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote JS file</p>
</div>
<div class="card-body">
<p>
<script src="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/remote.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Display an image</p>
</div>
<div class="card-body">
<img src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"
alt="Image should not load due to CSP">
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local image in iframe</p>
</div>
<div class="card-body">
<iframe src="JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"></iframe>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote image in iframe</p>
</div>
<div class="card-body">
<iframe src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%"
height="50px"></iframe>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

7
Lab 11/local.js Executable file
View File

@@ -0,0 +1,7 @@
(function() {
let scripts = document.getElementsByTagName('script');
let script = scripts[scripts.length - 1];
let parent = script.parentNode;
parent.textContent = 'This is locally generated';
})();

131
Lab 11/noframe.html Executable file
View File

@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="author" content="Nicholas Tamassia">
<title>CSP Test</title>
<!-- Insert your CSP policies here. Do not change anything else in this file. Well, okay,
you can change your name as the author just above this comment. -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https:; frame-src 'none'; img-src 'none';">
<link rel="stylesheet" href="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/styles.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="nav">
<a class="nav-link border bg-light" href="local.html">Local</a>
<a class="nav-link border bg-light" href="bootstrap.html">Bootstrap</a>
<a class="nav-link border bg-light" href="noframe.html">No frame</a>
</ul>
</nav>
<div class="container">
<div class="row my-4">
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline CSS</p>
</div>
<div class="card-body">
<p style="font-size: 2em;">Large text</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local CSS file</p>
</div>
<div class="card-body">
<p class="h5">Level 5 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote CSS file</p>
</div>
<div class="card-body">
<p class="h6">Level 6 heading</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Inline JavaScript</p>
</div>
<div class="card-body">
<p>
<script>document.write('This is inline scripting');</script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local JS file</p>
</div>
<div class="card-body">
<p>
<script src="local.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote JS file</p>
</div>
<div class="card-body">
<p>
<script src="https://w3.cs.jmu.edu/kirkpams/343/labs/lab11/remote.js"></script>
</p>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Display an image</p>
</div>
<div class="card-body">
<img src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"
alt="Image should not load due to CSP">
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Local image in iframe</p>
</div>
<div class="card-body">
<iframe src="JMU-Logo-RGB-horiz-purple.png" width="100%" height="50px"></iframe>
</div>
</div>
</div>
<div class="col-4 my-2">
<div class="card">
<div class="card-header">
<p class="h4">Remote image in iframe</p>
</div>
<div class="card-body">
<iframe src="https://w3.cs.jmu.edu/kirkpams/images/JMU-Logo-RGB-horiz-purple.png" width="100%"
height="50px"></iframe>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

3
Lab 11/styles.css Executable file
View File

@@ -0,0 +1,3 @@
.h5 {
font-style: italic;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

109
Lab 2/index.html Executable file
View File

@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Nicholas Tamassia">
<meta name="description" content="Lab 2 submission">
<title>CS 343 Lab 2</title>
</head>
<body>
<script>
let header1 = 'Course Information', header2 = 'Detailed Course Objectives', header3 = 'Course Catalog Description'
let showFooter = true
</script>
<header>
<h1>CS 343: Application Development</h1>
<h2>Fall 2023</h2>
<blockquote cite="https://uxdworld.com">
<p>"A user interface is like a joke. If you have to explain it, it&rsquo;s not that good."</p>
<p>- Martin LeBlanc</p>
</blockquote>
</header>
<hr>
<section>
<h3 id="header1"></h3>
<p>
Learning to work with the tools and technologies that are used to build and
create web sites is both empowering and fun. With these tools, you can build
your own web sites and customize the experience of those you visit. You can
also create interactive applications for storing and manipulating personal or
enterprise data. And you can dynamically generate images and graphics to help
visualize data sets.
</p>
<p>
The goal of this course is to explore these technologies - HTML, CSS, and
Javascript - that define the structure, presentation, and interactions for
modern web development. In addition to covering the basics of how to use these
tools, we will explore guidelines to ensure the sites we create are accessible
for a variety of users, including users with disabilities. After completing
this course, you will have a solid foundation to continue learning more
advanced web development techniques.
</p>
<ul>
<li><strong>Website: </strong><a>https://w3.cs.jmu.edu/kirkpams/343</a></li>
<li><strong>Time: </strong>M/W/F 9:10 - 10:00 AM</li>
<li><strong>Location: </strong>King Hall 243</li>
<li><strong>Textbook: </strong><cite>Fundamentals of Web Development, 3rd Edition</cite></li>
</ul>
</section>
<hr>
<section>
<h3 id="header2"></h3>
<p>
Following the successful completion of this course, students will be able to:
</p>
<ol type="1">
<li>Summarize the key steps and processes for retrieving and displaying a web page.</li>
<li>Structure text documents as HTML and publish them on a server.</li>
<li>Apply accessibility standards to web documents.</li>
<li>Create and adapt CSS style sheets for consistent web site presentation and styling.</li>
<li>Use a web framework to create a modern, responsive web site.</li>
<li>Generate HTML content dynamically with Javascript.</li>
<li>Create handlers to detect and respond to user input events.</li>
<li>Store and retrieve data in client-side storage.</li>
<li>Build images dynamically using provided data.</li>
<li>Learn to consult a web framework documentation and tutorials for additional help.</li>
</ol>
</section>
<hr>
<section>
<h3 id="header3"></h3>
<p>
Projects or topics in computer science which are of interest to the lower
division student. May be repeated for credit when course content changes.
Topics may vary. Prerequisite: Fully admitted Computer Science majors or
minors only and students should consult the instructor prior to enrolling
for the course.
</p>
</section>
<hr>
<footer id="footer"></footer>
<script>
document.querySelector('#header1').innerText = header1
document.querySelector('#header2').innerText = header2
document.querySelector('#header3').innerText = header3
const footer = document.querySelector('#footer')
if (showFooter) {
footer.innerHTML = '<img src="./JMU-Logo-RGB-horiz-purple.png" alt="James Madison University logo in purple" />'
} else {
footer.innerText = 'JMU logo is not shown'
}
</script>
</body>
</html>

104
Lab 2/lab2.txt Executable file
View File

@@ -0,0 +1,104 @@
# CONVERT # LINES TO COMMENTS (DELETE THIS ONE AND THE HORIZONTAL LINES)
# Create an HTML header using the author (your name), description
# ("Lab 2 submission"), and charset ("UTF-8") meta tags. Add a title of
# "CS 343 Lab 2".
# Define 4 JavaScript variables here:
# One is a Boolean that controls whether or not the footer image is shown.
# The Boolean MUST be named showFooter for testing purposes.
# The other three are the level-3 headings, including both the <h3> tag
# and the associated text. The names are not important.
# Wrap the title, subtitle, and blockquote inside a <header> element
# Page title and subtitle (should both be bigger than section headers)
CS 343: Application Development
Fall 2023
# Block quotation. Use an attribute to add the citation "https://uxdworld.com".
# The quote and the name should be two paragraphs.
"A user interface is like a joke. If you have to explain it, its not that good."
- Martin LeBlanc
# End of the <header>
# HORIZONTAL LINE
# Section header - MUST BE WRITTEN BY JAVASCRIPT
Course Information
# Two separate paragraphs
Learning to work with the tools and technologies that are used to build and
create web sites is both empowering and fun. With these tools, you can build
your own web sites and customize the experience of those you visit. You can
also create interactive applications for storing and manipulating personal or
enterprise data. And you can dynamically generate images and graphics to help
visualize data sets.
The goal of this course is to explore these technologies - HTML, CSS, and
Javascript - that define the structure, presentation, and interactions for
modern web development. In addition to covering the basics of how to use these
tools, we will explore guidelines to ensure the sites we create are accessible
for a variety of users, including users with disabilities. After completing
this course, you will have a solid foundation to continue learning more
advanced web development techniques.
# Make this a bullet-point list. Format the text as shown in the sample
# solution image. Note that <b> is NOT allowed for bold text. For the book
# title, use the <cite> tag to mark it as a citation.
* Website: https://w3.cs.jmu.edu/kirkpams/343
* Time: M/W/F 9:10 - 10:00 AM
* Location: King Hall 243
* Textbook: Fundamentals of Web Development, 3rd Edition
# HORIZONTAL LINE
# Section header - MUST BE WRITTEN BY JAVASCRIPT
Detailed Course Objectives
# Paragraph
Following the successful completion of this course, students will be able to:
# Make this a numbered list and do NOT hard-code the numbers
1. Summarize the key steps and processes for retrieving and displaying a web page.
2. Structure text documents as HTML and publish them on a server.
3. Apply accessibility standards to web documents.
4. Create and adapt CSS style sheets for consistent web site presentation and styling.
5. Use a web framework to create a modern, responsive web site.
6. Generate HTML content dynamically with Javascript.
7. Create handlers to detect and respond to user input events.
8. Store and retrieve data in client-side storage.
9. Build images dynamically using provided data.
10. Learn to consult a web framework documentation and tutorials for additional help.
# HORIZONTAL LINE
# Section header - MUST BE WRITTEN BY JAVASCRIPT
Course Catalog Description
# Paragraph
Projects or topics in computer science which are of interest to the lower
division student. May be repeated for credit when course content changes.
Topics may vary. Prerequisite: Fully admitted Computer Science majors or
minors only and students should consult the instructor prior to enrolling
for the course.
# HORIZONTAL LINE
# Wrap the following image inside a <footer> element
# If the Boolean variable at the top is set to tru:
# Embed the JMU-Logo-RGB-horiz-purple.png image. Add the following text as its
# description: "James Madison University logo in purple"
# Otherwise:
# Show the text "JMU logo is not shown"
# End of the <footer>

125
Lab 3/index.html Executable file
View File

@@ -0,0 +1,125 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="icon" href="https://fav.farm/🕸️">
</head>
<body>
<nav class="navbar navbar-expand-md bg-body-primary">
<div class="container">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo02"
aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex" role="search" data-bs-theme="light">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-light" type="submit">Search</button>
</form>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<main class="col-md-8">
<h1>Bootstrap demo</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet asperiores neque quis ut ipsa
nostrum
repellat itaque, ullam delectus recusandae eum repellendus necessitatibus, corporis deleniti
placeat. Ipsam
rerum nihil enim.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa possimus dolorum aliquam nisi
praesentium
adipisci aliquid. Provident quasi, unde dignissimos, repellat eaque voluptas id sapiente porro
necessitatibus pariatur, eum culpa?</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil assumenda velit, repudiandae nulla
excepturi
ea voluptatibus odit at temporibus nam beatae perferendis non corporis! Nam error fugiat earum
commodi
similique.</p>
</main>
<aside class="col-md-4 d-none d-sm-block">
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Accordion Item #1
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show"
data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the first item's accordion body.</strong> It is shown by default, until
the collapse plugin adds the appropriate classes that we use to style each element.
These classes control the overall appearance, as well as the showing and hiding via CSS
transitions. You can modify any of this with custom CSS or overriding our default
variables. It's also worth noting that just about any HTML can go within the
<code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Accordion Item #2
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the second item's accordion body.</strong> It is hidden by default,
until the collapse plugin adds the appropriate classes that we use to style each
element. These classes control the overall appearance, as well as the showing and hiding
via CSS transitions. You can modify any of this with custom CSS or overriding our
default variables. It's also worth noting that just about any HTML can go within the
<code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Accordion Item #3
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the third item's accordion body.</strong> It is hidden by default, until
the collapse plugin adds the appropriate classes that we use to style each element.
These classes control the overall appearance, as well as the showing and hiding via CSS
transitions. You can modify any of this with custom CSS or overriding our default
variables. It's also worth noting that just about any HTML can go within the
<code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
</div>
</aside>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
</body>
</html>

79
Lab 4/basic.html Executable file
View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>CSS Fundamentals</title>
</head>
<body>
<header>
<h1>Lorem Ipsum</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
vel leo sed ante vulputate porta id ac sapien. Nulla lacinia commodo
augue. Ut risus mauris, consectetur sed neque quis, sollicitudin sodales
nulla. Nullam eu porta arcu. Curabitur in erat sagittis, malesuada lorem
ac, vehicula nulla. Praesent rhoncus magna eu elit lobortis, ac congue
augue semper. Duis interdum consequat cursus. Morbi rutrum dapibus est
vel volutpat. Pellentesque in malesuada ante.
</p>
</header>
<nav>
<ul>
<li><a href="basic.html">Basic</a></li>
<li><a href="spaces.html">Spacing</a></li>
<li><a href="colors.html">Colorful</a></li>
<li><a href="navs.html">Navigation</a></li>
</ul>
</nav>
<main>
<section>
<h2>Part One <span>1</span></h2>
<p>
Etiam euismod pretium risus quis venenatis. Fusce finibus lacinia urna
sit amet pretium. Interdum et malesuada fames ac ante ipsum primis in
faucibus. Etiam consectetur, justo ac ornare volutpat, ante mi vehicula
quam, eget vehicula velit ex at orci. Pellentesque turpis est, convallis
eget finibus eu, hendrerit non mauris. Sed at sapien eu erat iaculis
porta nec sed ante. Nullam quis aliquam felis. Mauris gravida urna
blandit nisl posuere, tristique accumsan nibh mollis. Sed faucibus
malesuada arcu, et ultrices turpis laoreet lobortis. Mauris hendrerit
commodo ex, vitae venenatis arcu volutpat ut. In in nisi rhoncus,
fringilla risus ac, aliquet nunc. Fusce ut quam eleifend, fringilla
ante sed, congue nisi. Sed ut est elit.
</p>
<p>Back to <a href="basic.html">basic</a>.</p>
</section>
<section>
<h2>Part Two <span>2</span></h2>
<p>
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Quisque nec arcu eget eros fermentum efficitur non
vitae ante. Suspendisse semper dapibus dui ac volutpat. Morbi consectetur
mi a nunc posuere tristique. Vivamus interdum tincidunt arcu. Integer
volutpat ipsum in pellentesque tempus. Nulla aliquet congue ex at
elementum. Vestibulum imperdiet quam ac dui finibus, eget elementum erat
aliquam. Sed erat neque, cursus vulputate consectetur et, vulputate sit
amet orci. Duis fringilla aliquet mauris, nec semper nisl blandit ut.
Fusce iaculis vestibulum pulvinar. Morbi facilisis, ligula non
consectetur fringilla, elit magna auctor velit, at pretium magna lacus
sit amet nulla.
</p>
<ul>
<li><a href="spaces.html">Lorem</a></li>
<li><a href="color.html">Ipsum</a></li>
<li><a href="navs.html">Dolor</a></li>
</ul>
</section>
</main>
</body>
</html>

BIN
Lab 4/colors-annot.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

19
Lab 4/colors.css Executable file
View File

@@ -0,0 +1,19 @@
/* colors.css -- Controlling the colors and borders for Lab 4
* author: Nicholas Tamassia
*/
header {
background: #450084;
color: #f5f5f5;
border-bottom: solid #dacce6 1vh;
}
body {
background: #dfd2aa;
}
section {
background: #f4efe1;
border: solid black 3px;
border-radius: 1vh;
}

81
Lab 4/colors.html Executable file
View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>CSS Fundamentals</title>
<link href="spaces.css" rel="stylesheet">
<link href="colors.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Lorem Ipsum</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
vel leo sed ante vulputate porta id ac sapien. Nulla lacinia commodo
augue. Ut risus mauris, consectetur sed neque quis, sollicitudin sodales
nulla. Nullam eu porta arcu. Curabitur in erat sagittis, malesuada lorem
ac, vehicula nulla. Praesent rhoncus magna eu elit lobortis, ac congue
augue semper. Duis interdum consequat cursus. Morbi rutrum dapibus est
vel volutpat. Pellentesque in malesuada ante.
</p>
</header>
<nav>
<ul>
<li><a href="basic.html">Basic</a></li>
<li><a href="spaces.html">Spacing</a></li>
<li><a href="colors.html">Colorful</a></li>
<li><a href="navs.html">Navigation</a></li>
</ul>
</nav>
<main>
<section>
<h2>Part One <span>1</span></h2>
<p>
Etiam euismod pretium risus quis venenatis. Fusce finibus lacinia urna
sit amet pretium. Interdum et malesuada fames ac ante ipsum primis in
faucibus. Etiam consectetur, justo ac ornare volutpat, ante mi vehicula
quam, eget vehicula velit ex at orci. Pellentesque turpis est, convallis
eget finibus eu, hendrerit non mauris. Sed at sapien eu erat iaculis
porta nec sed ante. Nullam quis aliquam felis. Mauris gravida urna
blandit nisl posuere, tristique accumsan nibh mollis. Sed faucibus
malesuada arcu, et ultrices turpis laoreet lobortis. Mauris hendrerit
commodo ex, vitae venenatis arcu volutpat ut. In in nisi rhoncus,
fringilla risus ac, aliquet nunc. Fusce ut quam eleifend, fringilla
ante sed, congue nisi. Sed ut est elit.
</p>
<p>Back to <a href="basic.html">basic</a>.</p>
</section>
<section>
<h2>Part Two <span>2</span></h2>
<p>
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Quisque nec arcu eget eros fermentum efficitur non
vitae ante. Suspendisse semper dapibus dui ac volutpat. Morbi consectetur
mi a nunc posuere tristique. Vivamus interdum tincidunt arcu. Integer
volutpat ipsum in pellentesque tempus. Nulla aliquet congue ex at
elementum. Vestibulum imperdiet quam ac dui finibus, eget elementum erat
aliquam. Sed erat neque, cursus vulputate consectetur et, vulputate sit
amet orci. Duis fringilla aliquet mauris, nec semper nisl blandit ut.
Fusce iaculis vestibulum pulvinar. Morbi facilisis, ligula non
consectetur fringilla, elit magna auctor velit, at pretium magna lacus
sit amet nulla.
</p>
<ul>
<li><a href="spaces.html">Lorem</a></li>
<li><a href="color.html">Ipsum</a></li>
<li><a href="navs.html">Dolor</a></li>
</ul>
</section>
</main>
</body>
</html>

BIN
Lab 4/colors.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

BIN
Lab 4/css.zip Executable file

Binary file not shown.

BIN
Lab 4/navs-annot.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

34
Lab 4/navs.css Executable file
View File

@@ -0,0 +1,34 @@
/* navs.css -- Styling the nav elements for Lab 4
* author: Nicholas Tamassia
*/
nav a {
font-family: sans-serif;
text-decoration: none;
font-weight: 900;
color: #450084;
}
nav {
border: solid black 2px;
border-radius: 1vh;
overflow: hidden;
color: #dcdcdc;
background: #dcdcdc;
}
nav > ul {
list-style-type: none;
margin: 0;
padding: 0;
}
nav > ul li {
padding: 8px 13px;
background-color: #dcdcdc;
text-align: center;
}
nav > ul li:not(:last-child) {
border-bottom: solid 2px #f5f5f5;
}

82
Lab 4/navs.html Executable file
View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>CSS Fundamentals</title>
<link href="spaces.css" rel="stylesheet">
<link href="colors.css" rel="stylesheet">
<link href="navs.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Lorem Ipsum</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
vel leo sed ante vulputate porta id ac sapien. Nulla lacinia commodo
augue. Ut risus mauris, consectetur sed neque quis, sollicitudin sodales
nulla. Nullam eu porta arcu. Curabitur in erat sagittis, malesuada lorem
ac, vehicula nulla. Praesent rhoncus magna eu elit lobortis, ac congue
augue semper. Duis interdum consequat cursus. Morbi rutrum dapibus est
vel volutpat. Pellentesque in malesuada ante.
</p>
</header>
<nav>
<ul>
<li><a href="basic.html">Basic</a></li>
<li><a href="spaces.html">Spacing</a></li>
<li><a href="colors.html">Colorful</a></li>
<li><a href="navs.html">Navigation</a></li>
</ul>
</nav>
<main>
<section>
<h2>Part One <span>1</span></h2>
<p>
Etiam euismod pretium risus quis venenatis. Fusce finibus lacinia urna
sit amet pretium. Interdum et malesuada fames ac ante ipsum primis in
faucibus. Etiam consectetur, justo ac ornare volutpat, ante mi vehicula
quam, eget vehicula velit ex at orci. Pellentesque turpis est, convallis
eget finibus eu, hendrerit non mauris. Sed at sapien eu erat iaculis
porta nec sed ante. Nullam quis aliquam felis. Mauris gravida urna
blandit nisl posuere, tristique accumsan nibh mollis. Sed faucibus
malesuada arcu, et ultrices turpis laoreet lobortis. Mauris hendrerit
commodo ex, vitae venenatis arcu volutpat ut. In in nisi rhoncus,
fringilla risus ac, aliquet nunc. Fusce ut quam eleifend, fringilla
ante sed, congue nisi. Sed ut est elit.
</p>
<p>Back to <a href="basic.html">basic</a>.</p>
</section>
<section>
<h2>Part Two <span>2</span></h2>
<p>
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Quisque nec arcu eget eros fermentum efficitur non
vitae ante. Suspendisse semper dapibus dui ac volutpat. Morbi consectetur
mi a nunc posuere tristique. Vivamus interdum tincidunt arcu. Integer
volutpat ipsum in pellentesque tempus. Nulla aliquet congue ex at
elementum. Vestibulum imperdiet quam ac dui finibus, eget elementum erat
aliquam. Sed erat neque, cursus vulputate consectetur et, vulputate sit
amet orci. Duis fringilla aliquet mauris, nec semper nisl blandit ut.
Fusce iaculis vestibulum pulvinar. Morbi facilisis, ligula non
consectetur fringilla, elit magna auctor velit, at pretium magna lacus
sit amet nulla.
</p>
<ul>
<li><a href="spaces.html">Lorem</a></li>
<li><a href="color.html">Ipsum</a></li>
<li><a href="navs.html">Dolor</a></li>
</ul>
</section>
</main>
</body>
</html>

BIN
Lab 4/navs.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

BIN
Lab 4/spaces-annot.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

38
Lab 4/spaces.css Executable file
View File

@@ -0,0 +1,38 @@
/* basics.css -- Controlling the spacing for Lab 4
* author: Nicholas Tamassia
*/
html, body {
margin: 0;
padding: 0;
}
header {
padding: 1vh 2vw;
}
nav {
width: 10vw;
display: inline-block;
vertical-align: top;
margin: 1vh 2vw;
}
main {
width: 80vw;
padding: 3vh 0;
display: inline-block;
}
section {
margin: 3vh 0 0;
padding: 1vw;
}
h1, h2 {
font-family: sans-serif;
}
p {
padding: 0 2vw;
}

80
Lab 4/spaces.html Executable file
View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>CSS Fundamentals</title>
<link href="spaces.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Lorem Ipsum</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
vel leo sed ante vulputate porta id ac sapien. Nulla lacinia commodo
augue. Ut risus mauris, consectetur sed neque quis, sollicitudin sodales
nulla. Nullam eu porta arcu. Curabitur in erat sagittis, malesuada lorem
ac, vehicula nulla. Praesent rhoncus magna eu elit lobortis, ac congue
augue semper. Duis interdum consequat cursus. Morbi rutrum dapibus est
vel volutpat. Pellentesque in malesuada ante.
</p>
</header>
<nav>
<ul>
<li><a href="basic.html">Basic</a></li>
<li><a href="spaces.html">Spacing</a></li>
<li><a href="colors.html">Colorful</a></li>
<li><a href="navs.html">Navigation</a></li>
</ul>
</nav>
<main>
<section>
<h2>Part One <span>1</span></h2>
<p>
Etiam euismod pretium risus quis venenatis. Fusce finibus lacinia urna
sit amet pretium. Interdum et malesuada fames ac ante ipsum primis in
faucibus. Etiam consectetur, justo ac ornare volutpat, ante mi vehicula
quam, eget vehicula velit ex at orci. Pellentesque turpis est, convallis
eget finibus eu, hendrerit non mauris. Sed at sapien eu erat iaculis
porta nec sed ante. Nullam quis aliquam felis. Mauris gravida urna
blandit nisl posuere, tristique accumsan nibh mollis. Sed faucibus
malesuada arcu, et ultrices turpis laoreet lobortis. Mauris hendrerit
commodo ex, vitae venenatis arcu volutpat ut. In in nisi rhoncus,
fringilla risus ac, aliquet nunc. Fusce ut quam eleifend, fringilla
ante sed, congue nisi. Sed ut est elit.
</p>
<p>Back to <a href="basic.html">basic</a>.</p>
</section>
<section>
<h2>Part Two <span>2</span></h2>
<p>
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Quisque nec arcu eget eros fermentum efficitur non
vitae ante. Suspendisse semper dapibus dui ac volutpat. Morbi consectetur
mi a nunc posuere tristique. Vivamus interdum tincidunt arcu. Integer
volutpat ipsum in pellentesque tempus. Nulla aliquet congue ex at
elementum. Vestibulum imperdiet quam ac dui finibus, eget elementum erat
aliquam. Sed erat neque, cursus vulputate consectetur et, vulputate sit
amet orci. Duis fringilla aliquet mauris, nec semper nisl blandit ut.
Fusce iaculis vestibulum pulvinar. Morbi facilisis, ligula non
consectetur fringilla, elit magna auctor velit, at pretium magna lacus
sit amet nulla.
</p>
<ul>
<li><a href="spaces.html">Lorem</a></li>
<li><a href="color.html">Ipsum</a></li>
<li><a href="navs.html">Dolor</a></li>
</ul>
</section>
</main>
</body>
</html>

BIN
Lab 4/spaces.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

47
Lab 5/flex.js Executable file
View File

@@ -0,0 +1,47 @@
const picsumBase = "https://picsum.photos/200";
let mainElement;
let addButton;
let spreadButton;
let rotateButton;
function spacing() {
spreadButton.classList.toggle("active");
mainElement.classList.toggle("spread");
}
function rotate() {
rotateButton.classList.toggle("active");
mainElement.classList.toggle("vert");
}
function addImg() {
const randomNumber = document.getElementsByTagName("img").length + 1;
const newImg = document.createElement("img");
newImg.src = `${picsumBase}?random=${randomNumber}`;
newImg.alt = "random square image";
newImg.addEventListener("click", removeImg.bind(null, newImg));
mainElement.appendChild(newImg);
}
function removeImg(element) {
element.remove();
}
(function () {
mainElement = document.querySelector("main");
addButton = document.querySelector("#add");
spreadButton = document.querySelector("#spread");
rotateButton = document.querySelector("#rotate");
addButton.addEventListener("click", addImg);
spreadButton.addEventListener("click", spacing);
rotateButton.addEventListener("click", rotate);
document
.querySelectorAll("img")
.forEach((img) => img.addEventListener("click", removeImg.bind(null, img)));
})();

28
Lab 5/index.html Executable file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flexbox Layout</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<nav>
<ul>
<li><button id="add">Add Image</button></li>
<li><button id="spread">Spread Out</button></li>
<li><button id="rotate">Rotate Direction</button></li>
</ul>
</nav>
</header>
<main>
<img src="https://picsum.photos/200?random=1" alt="random square image" />
<img src="https://picsum.photos/200?random=2" alt="random square image" />
</main>
<script src="flex.js"></script>
</body>
</html>

79
Lab 5/styles.css Executable file
View File

@@ -0,0 +1,79 @@
:root {
--foreground-color: #343a40;
--background-color: #f8f9fa;
--nav-background-color: #ced4da;
}
body {
/* Do not change: <body> includes vertical margin only */
margin: 2vh 0vw;
padding: 0;
}
header {
background-color: var(--nav-background-color);
top: 0;
width: 100vw;
display: flex;
justify-content: flex-end;
position: fixed;
}
main {
height: 96vh;
display: flex;
justify-content: flex-start;
align-items: center;
}
main.spread {
justify-content: space-around;
}
main.vert {
flex-direction: column;
}
nav > ul {
list-style: none;
margin-right: 5vw;
}
nav > ul > li {
display: inline;
}
nav > ul > li > button {
padding: 1vh 2vw;
font-size: 1.2em;
border: none;
border-radius: 10px;
background-color: var(--background-color);
color: var(--foreground-color);
}
nav > ul > li > button:hover {
outline: 3px solid var(--foreground-color);
}
nav > ul > li > button.active {
background-color: var(--foreground-color);
color: var(--background-color);
}
/* TODO: Define rules for the nav buttons:
* The coloring will be controlled dynamically:
*
* Start with the default background and foreground colors
* If the mouse is hovering, add an outline using the foreground color
* If the "active" class is present, reverse the colors
*/
/* TODO: Define rules for the main flexbox:
*
* If the "spread" class is present, use space-around to space the images out
* If the "vert" class is present, make the flexbox a column
*/
/* BONUS: Make <img> tags show up in front of the header bar */

100
Lab 6/cards.css Executable file
View File

@@ -0,0 +1,100 @@
/* Use this file to control the layout of cards (articles) within the
* main region of the page. */
/* TODO: Map the articles to grid areas */
main > h2 {
grid-area: heading;
}
main > article:nth-of-type(1) {
grid-area: article1;
}
main > article:nth-of-type(2) {
grid-area: article2;
}
main > article:nth-of-type(3) {
grid-area: article3;
}
main > article:nth-of-type(4) {
grid-area: article4;
}
main > article:nth-of-type(5) {
grid-area: article5;
}
main > article:nth-of-type(6) {
grid-area: article6;
}
/* TODO: Make the main element into a grid to hold the cards */
main {
display: grid;
}
/* TODO: Tiny and small layouts:
* All articles in a vertical column using grid-template-areas with
* the main h2 title at the top. */
@media (max-width: 699px) {
main {
grid-template-columns: 1fr;
grid-template-areas:
"heading"
"article1"
"article2"
"article3"
"article4"
"article5"
"article6";
}
}
/* TODO: Medium layouts:
* Article cards are displayed 2 per row (articles 1 and 2 in the top row,
* 3 and 4 in the second, 5 and 6 in the third). Use 1vh for row gaps and
* 2vw for column gaps. Both columns should have the same width. Again,
* place the main h2 title at the top. */
@media (min-width: 700px) {
main {
grid-template-columns: 1fr 1fr;
grid-template-areas:
"heading heading"
"article1 article2"
"article3 article4"
"article5 article6";
}
}
/* TODO: Large layouts:
* Article cards are now in 3 equal-width columns with the main h2 title
* at the top. */
@media (min-width: 1000px) {
main {
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
"heading heading heading"
"article1 article2 article3"
"article4 article5 article6";
}
}
@media print {
main {
display: flex;
flex-direction: column;
justify-content: space-between;
}
article h3,
p {
padding-top: 0;
padding-bottom: 0;
}
main > h2 {
display: none;
}
}
/* TODO: Print formatting:
* Make the main content into a flex-box with the articles
* in a column with space between the items vertically. Get rid
* of the vertical padding on the p and h3 elements inside
* the articles (keeping 1vw padding on the sides).
* Remove the main h2 title from the display. */

52
Lab 6/dark.css Executable file
View File

@@ -0,0 +1,52 @@
:root {
--dark: #333;
--mid: #555;
--light: #ddd;
--white: #fff;
}
/* Set default to light mode */
body {
background-color: var(--white);
color: var(--dark);
}
/* TODO: In light stealth mode, set font colors to light. This should
* all text, including the buttons. */
.stealth {
color: var(--light);
}
/* TODO: Dark mode:
* Switch the background color to dark and switch the article
* border to white. Any text on a gray background should become
* dark while text on the new dark background becomes light.
*/
@media (prefers-color-scheme: dark) {
body {
background-color: var(--dark);
color: var(--light);
}
article {
border-color: var(--white);
}
main h2,
main h3 {
color: var(--dark);
}
body.stealth {
color: var(--mid);
}
body.stealth > main h2,
body.stealth > main h3,
body.stealth > nav button {
color: var(--light);
}
}
/* TODO: Stealth dark mode:
* Set the font colors to mid, except for those that are on a gray
* background. Make that text have a light font color.
*/

82
Lab 6/index.html Executable file
View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Grids and Dark Mode</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap-reboot.css">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="layout.css">
<link rel="stylesheet" href="cards.css">
<link rel="stylesheet" href="dark.css">
</head>
<!-- To check your layout, you can add class="debug" to the body element to
add colors and borders to the major sections -->
<body>
<header>
<h1>Header</h1>
</header>
<nav>
<ul>
<li><button type="button" id="mode-print">Print Layout</button></li>
<li><button type="button" id="theme-stealth">Stealth Mode</button></li>
</ul>
</nav>
<main>
<h2>Main Content</h2>
<article id="article-1">
<h3>Main</h3>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dapibus mi sed
facilisis finibus. Cras ut mollis eros. Aliquam commodo quis purus et tempus.
</article>
<article id="article-2">
<h3>Second</h3>
<p>Fusce nisi enim, interdum efficitur magna quis, feugiat ornare sapien. Quisque
molestie maximus diam, in egestas elit elementum vel. Morbi in faucibus odio.
</article>
<article id="article-3">
<h3>Third</h3>
<p> In consectetur, odio id malesuada venenatis, diam dolor consequat erat, sed
blandit nisi nunc ac libero.
</article>
<article id="article-4">
<h3>Fourth</h3>
<p> Etiam consequat, sem sit amet volutpat tempus, justo mi dapibus erat, in
maximus odio metus id ex. Pellentesque finibus eleifend tempor.
</article>
<article id="article-5">
<h3>Fifth</h3>
<p> Morbi in imperdiet sem, at ultrices ligula. Curabitur bibendum quis leo non
lacinia. In hac habitasse platea dictumst. Nullam malesuada consequat efficitur.
</article>
<article id="article-6">
<h3>Sixth</h3>
<p> Nulla laoreet vestibulum hendrerit. Aenean ut velit eget lectus molestie
bibendum. In ac elit a eros iaculis scelerisque dictum in nulla.
</article>
</main>
<aside id="side">
<h2>Sidebar</h2>
</aside>
<aside id="ad">
<h2>Advertising</h2>
</aside>
<footer>
<h2>The footer</h2>
</footer>
<script src="script.js"></script>
</body>
</html>

107
Lab 6/layout.css Executable file
View File

@@ -0,0 +1,107 @@
/* Map the semantic elements to grid area names: */
header {
grid-area: header;
}
main {
grid-area: content;
}
nav {
grid-area: nav;
}
#side {
grid-area: sidebar;
}
#ad {
grid-area: ad;
}
footer {
grid-area: footer;
}
/* Set default values for the body and list */
body {
display: grid;
gap: 20px;
}
nav ul {
padding: 0;
margin: 0;
display: flex;
list-style: none;
flex-direction: row;
justify-content: space-around;
}
/* (Default) Tiny screen */
@media (max-width: 499px) {
body {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"content"
"footer";
}
#ad,
#side {
display: none;
}
}
/* (Default) Tiny screen */
/* Small screen */
@media (min-width: 500px) {
body {
padding-right: 2vw;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
}
/* Small screen */
/* Medium & Large screens */
@media (min-width: 700px) {
body {
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
align-items: center;
}
nav ul > li {
margin-bottom: 3vh;
}
}
@media print {
body {
grid-template-columns: 1fr 9fr;
grid-template-areas:
"header header"
". content"
"footer footer";
}
nav,
#side,
#ad {
display: none;
}
}
/* TODO: Print formatting:
* Make two columns with the right taking up 90% width.
* The header and footer span both columns at the top and
* bottom, respectively. The main content is only in the
* right. Do not show the #side, #ad, or nav bar.
*/

31
Lab 6/script.js Executable file
View File

@@ -0,0 +1,31 @@
(function () {
const modePrint = document.querySelector("#mode-print");
modePrint.addEventListener("click", () => window.print());
const themeStealth = document.querySelector("#theme-stealth");
const header = document.querySelector("body > header > h1");
const body = document.querySelector("body");
themeStealth.addEventListener("click", () => {
body.classList.toggle("stealth");
if (body.classList.contains("stealth")) {
header.innerText += "(Stealth Mode)";
} else {
header.innerText = "Header";
}
});
const articleH3s = document.querySelectorAll("article > h3");
articleH3s.forEach((element) => {
element.addEventListener("click", (event) => {
event.target.nextElementSibling.hidden =
!event.target.nextElementSibling.hidden;
});
});
/* TODO: Add a click event listener to the article h3 titles. When
* clicked, make the text of the associated p element hidden. HINT:
* event listener callback functions receive an event parameter
* object. event.target will refer to the object clicked (i.e., the
* h3 title). If you print that element out to the console, you can
* examine its fields to find how to access the p element that
* follows. */
})();

52
Lab 6/styles.css Executable file
View File

@@ -0,0 +1,52 @@
/* Create rounded-corner buttons */
nav button {
border: 2px black solid;
border-radius: 5px;
width: 80px;
}
/* Make the articles into cards */
article {
border: 1px solid black;
border-radius: 5px;
padding: 0;
}
article > h3, main > h2 {
background: lightgray;
padding: 1vh 1vw;
font-size: 1.6em;
}
article > p {
padding: 1vh 1vw;
}
/* Set the debug class on body to view outlines of the regions */
.debug {
header {
background-color: red;
border: 5px dashed #450085;
}
main {
background-color: orange;
border: 5px dashed #333333;
}
nav {
background-color: yellow;
border: 5px dashed #009698;
}
#side {
background-color: green;
border: 5px dashed #8EE4D7 ;
}
#ad {
background-color: #F4EFE1;
border: 5px dashed blue;
}
footer {
background-color: #cbb677;
border: 5px dashed #b599ce;
}
}

81
Lab 7/card-creator.html Executable file
View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Card Creator</title>
<link rel="stylesheet" href="cards.css">
<link rel="stylesheet" href="modal.css">
</head>
<body>
<aside class="modal fade" tabindex="-1" role="dialog" id="user-modal">
<div class="modal-dialog">
<form class="modal-content card-form" id="user-form">
<header class="modal-header">
<h3>Add/Edit User</h3>
</header>
<section class="modal-body">
<input name="guest-full" type="text" />
<input name="guest-short" type="text" />
<div class="invalid-feedback">Short name must be unique</div>
<input name="old-short" type="hidden" />
</section>
<footer class="modal-footer">
<button type="submit">Submit</button>
</footer>
</form>
</div>
</aside>
<nav>
<h1>Guest List</h1>
<ul id="guest-list" class="card-list">
<li id="alice">Alice <button class="btn-edit-guest" data-user="alice">Edit</button></li>
<li id="bob">Bob <button class="btn-edit-guest" data-user="bob">Edit</button></li>
<li id="charlie">Charlie <button class="btn-edit-guest" data-user="charlie">Edit</button></li>
</ul>
<button type="button" id="btn-add-guest">Add Guest</button>
</nav>
<main class="left-right pt-4">
<section id="form-area">
<h2>Invitation Details</h2>
<form class="card-form" id="preview-form">
<div class="form-group">
<label for="host">Host</label>
<input name="host" type="text" placeholder="Message sender">
</div>
<div class="form-group">
<label for="title">Title</label>
<input name="title" type="text" placeholder="Message title">
</div>
<div class="form-group">
<label for="date">Party Date</label>
<input name="date" type="date">
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea name="message" placeholder="Message content" rows="8"></textarea>
</div>
<div class="form-buttons">
<button type="reset" id="reset-btn">Clear Form</button>
</div>
</form>
</section>
<section id="preview-area">
<div class="card-display">
<div class="card-page page-one">
<div class="title"><span id="preview-title">TITLE</span></div>
<div class="subtitle"><span id="preview-date">DATE</span></div>
</div>
<div class="card-page page-two">
<div class="to">Dear <span id="preview-guest">GUEST</span>,</div>
<div class="message"><span id="preview-message">YOUR MESSAGE HERE</span></div>
<div class="from">Sincerely, <span id="preview-host">HOST</span></div>
</div>
</div>
</section>
</main>
<script src="createcard.js"></script>
</body>
</html>

214
Lab 7/cards.css Executable file
View File

@@ -0,0 +1,214 @@
body {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f0f0f0;
display: grid;
grid-template-rows: 1fr 9fr;
}
button {
border: 2px solid black;
border-radius: 5px;
padding: 0.2rem 0.2rem;
}
nav {
grid-row: 1;
grid-column:1;
ul {
list-style: none;
width: 90%;
}
li {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 100%;
border:1px solid black;
background: white;
padding: 1vh 1vw;
text-wrap: wrap;
}
li.blank {
border: none;
background-color: #f0f0f0;
justify-content: flex-end;
}
li:not(.blank):hover {
background: #c0c0b0;
}
.btn-edit-guest {
z-index: 2;
}
#btn-add-guest {
float: right;
}
}
.left-right {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
grid-row: 1;
grid-column: 2;
}
#card-list {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
[contenteditable] {
border: 1px solid #ccc;
}
}
.card-form {
margin: 20px;
min-width: 500px;
.form-buttons {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: baseline;
margin: 10px;
}
.form-buttons > button {
margin: 0px 5px;
}
.form-group {
margin: 10px;
width: auto;
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr;
grid-template-areas: "label input"
". feedback";
& label {
grid-area: label;
text-align: right;
padding-right: 10px;
}
& input,
& textarea {
grid-area: input;
}
}
}
.card-display {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: fit-content;
background-color: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
font-size: 18px;
font-family: 'Garamond', Times, serif;
.card-page {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 2fr 2fr 1fr;
width: 300px;
height: 400px;
padding: 40px;
}
.page-one {
background: rgb(240, 240, 240);
background: linear-gradient(270deg, rgba(240, 240, 240, 1) 0%, rgba(255, 255, 255, 1) 20%);
grid-template-areas:
"delete"
"title"
"subtitle"
".";
.title {
grid-area: title;
font-size: 24px;
font-weight: bold;
text-align: center;
justify-self: center;
align-self: center;
font-family: "Lucida Handwriting", cursive;
}
.subtitle {
grid-area: subtitle;
font-size: 20px;
font-weight: bold;
text-align: center;
justify-self: center;
align-self: start;
}
.delete-btn {
grid-area: delete;
justify-self: center;
align-self: start;
}
}
.page-two {
background: rgb(230, 230, 230);
background: linear-gradient(90deg, rgba(230, 230, 230, 1) 0%, rgba(255, 255, 255, 1) 5%);
grid-template-areas:
"to"
"message"
"message"
"from";
.to {
grid-area: to;
justify-self: start;
align-self: start;
}
.message {
grid-area: message;
white-space: pre-wrap;
}
.from {
grid-area: from;
justify-self: end;
align-self: end;
}
}
}
form .invalid-feedback {
color: red;
font-size: 0.8em;
grid-area: feedback;
visibility: hidden;
}
form .invalid {
border-color: red;
outline: none;
}
form .invalid ~ .invalid-feedback {
visibility: visible;
}

154
Lab 7/createcard.js Executable file
View File

@@ -0,0 +1,154 @@
/* Default users in the invitation list */
let userList = [
{ shortName: "Alice", fullName: "Alice N. Wonderland" },
{ shortName: "Bob", fullName: "Bob Malooga" },
{ shortName: "Charlie", fullName: "Charlie Bucket" },
];
/* STEP 1:
* Update a field of the card preview based on the current value of the
* preview-form field. For the preview-form, use the field's .value field.
* Find the corresponding preview-X field (i.e., for the preview-form host
* field, you should update preview-host's textContent. */
function updateField(field) {
document.querySelector(`#preview-${field.name}`).textContent = field.value;
}
/* STEP 1:
* When the Clear Form button is clicked, set all of the preview-area's
* fields back to the default values as given in the HTML file. */
function defaultPreview() {
document.querySelector("#preview-host").textContent = "HOST";
document.querySelector("#preview-title").textContent = "TITLE";
document.querySelector("#preview-message").textContent = "YOUR MESSAGE HERE";
document.querySelector("#preview-date").textContent = "DATE";
}
/* STEP 2:
* Update the preview of the card to show the selected user. Use the
* user parameter to search through the userList, trying to match the
* shortName field. You should do a case-insensitive match, meaning
* the shortName field should be passed to the toLowerCase() function.
* Get the preview-guest field and set its textContent to the user's
* fullName field. */
function previewCard(user) {
const guestPreview = document.querySelector("#preview-guest");
const listUser = userList.find(
(listUser) => listUser.shortName.toLowerCase() === user.id
);
guestPreview.textContent = listUser.fullName;
}
(function () {
// STEP 1:
// Get the preview form. For each of the text fields (host, title, message),
// add a keyup event listener to call updateField on that field name. For
// the date field, use a change event listener to do the same.
const form = document.querySelector("#preview-form");
const { host, title, message, date } = form;
host.addEventListener("keyup", updateField.bind(null, host));
title.addEventListener("keyup", updateField.bind(null, title));
message.addEventListener("keyup", updateField.bind(null, message));
date.addEventListener("change", updateField.bind(null, date));
// STEP 1:
// When the reset-btn button is clicked, call defaultPreview() to restore
// the preview fields to their original values.
document
.querySelector("#reset-btn")
.addEventListener("click", defaultPreview);
// STEP 2:
// For each of the existing users in the invitation list, add a click
// listener that will put their name into the card preview.
// HINT: You can grab all of them and use .forEach:
document
.querySelectorAll("#guest-list > li")
.forEach((userCard) =>
userCard.addEventListener("click", previewCard.bind(null, userCard))
);
// STEP 3:
// Grab all elements with the "modal" class. When clicked, remove the
// "show" class from the target element.
const modal = document.querySelector(".modal");
modal.addEventListener("click", (event) => {
if (event.target === modal) {
modal.classList.remove("show");
}
});
// STEP 3:
// For each of the btn-edit-guest buttons, add a click event listener. When
// clicked, get the data-user attribute from the clicked item and find the
// guest from the userList with that shortName. Store the guest's fullName
// and shortName into the user-form fields and show the modal. Also store
// the shortName in the old-short field and stop the event propagation.
const userForm = document.querySelector("#user-form");
document.querySelectorAll(".btn-edit-guest").forEach((btn) => {
btn.addEventListener("click", (event) => {
event.stopPropagation();
const dataUser = btn.dataset.user;
const listUser = userList.find(
(listUser) => listUser.shortName.toLowerCase() === dataUser
);
userForm["guest-full"].value = listUser.fullName;
userForm["guest-short"].value = listUser.shortName;
userForm["old-short"].value = listUser.shortName;
modal.classList.add("show");
});
});
// STEP 3:
// When the modal form is submitted, user the user-form's old-short field
// to find the user from the userList. Also look for the new short-name value
// in the userList. If the new short-name is found and it is not the same
// user as before (e.g., the new name conflicts with someone else), add the
// "invalid" class to the guest-short input and return.
//
// If the short-name is valid, get the guest-short and guest-full values from
// the form and update the user in the userList. Hide the modal.
//
// BONUS: Update the short name that appears in the guest-list item. Note
// that you'll need to first get the item, then access its firstChild. Otherwise,
// setting the textContent will accidentally remove the edit button.
userForm.addEventListener("submit", (event) => {
event.preventDefault();
const guestFull = userForm["guest-full"].value;
const guestShort = userForm["guest-short"].value;
const oldShort = userForm["old-short"].value;
const newId = guestShort.toLowerCase();
const oldId = oldShort.toLowerCase();
const listUserIndex = userList.findIndex(
(listUser) => listUser.shortName.toLowerCase() === oldId
);
for (let i = 0; i < userList.length; i++) {
const shortNameMatches = userList[i].shortName.toLowerCase() === newId;
if (i !== listUserIndex && shortNameMatches) {
userForm["guest-short"].classList.add("invalid");
return;
}
}
userList[listUserIndex].fullName = guestFull;
userList[listUserIndex].shortName = guestShort;
const oldListItem = document.querySelector(`#guest-list > li#${oldId}`);
oldListItem.id = newId;
const newNode = document.createElement("div");
newNode.textContent = guestShort;
oldListItem.replaceChild(newNode.firstChild, oldListItem.firstChild);
oldListItem.firstElementChild.dataset.user = newId;
userForm["guest-short"].classList.remove("invalid");
modal.classList.remove("show");
});
})();

95
Lab 7/modal.css Executable file
View File

@@ -0,0 +1,95 @@
/* Modal interactions based on Bootstrap */
.modal {
/* The modal covers the entire screent */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
/* The modal has a dark color */
background-color: rgb(33, 37, 41, .5);
}
.fade:not(.show) {
/* When not shown, the modal is see-through and (important!) doesn't capture clicks */
pointer-events: none;
transition: opacity .15s linear;
opacity: 0;
z-index: -1;
}
.fade {
/* Controls the speed of the fade in/out transitions */
transition: opacity .15s linear;
z-index: 10;
}
.show {
/* When shown, make the dark gray (somewhat transparent) background solid */
opacity: 1;
}
/* Controls the drop-down motion of the dialog box */
.modal-dialog {
display: flex;
justify-content: center;
width: 100%;
pointer-events: none;
position: relative;
}
/* When the modal gets the show class added, drop down from 0 to 10vh from the top */
.modal.show .modal-dialog {
transition: transform .3s ease-out;
transform: translate(0,10vh);
}
/* When the modal is dismissed, raise it before making it disappear */
.modal.fade:not(.show) .modal-dialog {
transition: transform .3s ease-out;
transform: translate(0,-10vh);
}
/* Create the box around the modal content */
.modal-content {
pointer-events: auto;
background: white;
opacity: 1;
min-height: 10vh;
min-width: 30vw;
border: 1px solid rgba(0,0,0,.2);
border-radius: .3rem;
background-clip: padding-box;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border-bottom: 1px solid gray;
}
.modal-header * {
margin: 0;
}
.modal-body {
padding: 0rem 1rem;
}
.modal-footer {
display: flex;
align-items: center;
justify-content: flex-end;
border-top: 1px solid gray;
padding: 1rem;
}

188
Lab 8/funs.js Executable file
View File

@@ -0,0 +1,188 @@
/* STEP 1: Given a movie object, copy its title into a new field called
* textContent and return the movie.
*
* @param {object} movie A movie object from the JSON data set
*/
function setTitleContent(movie) {
movie.textContent = movie.title;
return movie;
}
/* STEP 2: Given a movie object, append the remaining fields into the
* textContent field. Each function should append only the relevant field.
* Chaining them together would create a textContent string such as the
* following:
* Mad Max: Fury Road (2015) - 120 minutes [8.1]
* Make sure to include the correct spacing and punctuation marks.
*
* @param {object} movie A movie object from the JSON data set with the
* title already copied into the movie.textContent field.
*/
function appendYear(movie) {
movie.textContent = movie.textContent.concat(` (${movie.year})`);
return movie;
}
function appendRuntime(movie) {
movie.textContent = movie.textContent.concat(` - ${movie.runtime} minutes`);
return movie;
}
function appendRating(movie) {
movie.textContent = movie.textContent.concat(` [${movie.rating}]`);
return movie;
}
/* STEP 3: Return a closure (arrow function) that takes a movie argument
* and compares its .rating field with this function's rating argument.
* Return true if the movie's rating satisfies this minimum criterion.
* Note that you need to call parseFloat on the movie.rating field because
* JSON data defaults to a string type.
*
* @param {number} rating The minimum movie rating that will cause the
* closure to return true for a movie.
*/
function setMinRating(rating) {
// If the minimum rating value passed in the query string is NaN,
// the closure should always evaluate to false.
// Whether or not this is desireable is up to the designer
const minRating = Number.parseFloat(rating);
return (movie) => Number.parseFloat(movie.rating) >= minRating;
}
/* STEP 3: Complete the following functions just as you did setMinRating.
* You'll need to use parseInt instead of parseFloat, because these are
* all integer values.
*/
function setMinYear(year) {
const minYear = Number.parseFloat(year);
return (movie) => Number.parseFloat(movie.year) >= minYear;
}
function setMaxYear(year) {
const maxYear = Number.parseFloat(year);
return (movie) => Number.parseFloat(movie.year) <= maxYear;
}
function setMinTime(mins) {
const minMins = Number.parseFloat(mins);
return (movie) => Number.parseFloat(movie.runtime) >= minMins;
}
function setMaxTime(mins) {
const maxMins = Number.parseFloat(mins);
return (movie) => Number.parseFloat(movie.runtime) <= maxMins;
}
/* buildItem - Helper function that creates a DOM <li> element, adds the
* list-group-item class, and inserts the movie's text content. Do not
* modify.
*
* @param {object} movie The movie object to create as a list item
* @param {object} list The <ul> to add the item to
*/
function buildItem(movie, list) {
let item = document.createElement("li");
item.classList.add("list-group-item");
item.textContent = movie.textContent;
list.append(item);
}
(async function () {
// STEP 1: Start your anonymous initialization function here. Be sure to
// end the file with the needed syntax to call the function.
// FIRST CODE IN THE INITIALIZATION FUNCTION
// Get the <ul> object from the HTML (do not modify)
let ul = document.querySelector("#target");
// Set default values (do not modify)
let minYear = 0;
let maxYear = 3000;
let minTime = 0;
let maxTime = 500;
let minRating = 0.0;
// Get the query string and split it into an array of distinct queries.
// (do not modify)
// For example, given index.html?minyear=1990&minrating=9.0, the query
// variable is the array [ 'minyear=1990', 'minrating=9.0' ]
let query = window.location.search.substring(1); //.split('&');
if (query !== "") {
query = query.split("&");
} else {
query = undefined;
}
// KEEP THIS HARD-CODED TO AVOID CORS ISSUES
const hostname = "https://w3.cs.jmu.edu/kirkpams/343/labs/lab8";
const url = `${hostname}/data.json`;
// STEP 1: Fetch the JSON data from the URL. If the query string is empty
// (i.e., query is undefined), grab just the first 10 data entries. Given
// this array, use .map to call setTitleContent on each entry and .forEach
// to call buildItem for each. You may NOT use a traditional loop (e.g.,
// for-of, while, etc.) for this lab.
//
// STEP 2: Extend the movie's textContent by using .map with the additional
// functions to append the year, runtime, and rating values.
//
// STEP 3: If the query variable is defined, then the URL contains a query
// string of criteria. Use the criteria specified in the query string to
// filter the data. Each criterion would be of the form minyear=2000, with
// the criteria being minyear, maxyear, mintime, maxtime, or minrating. Use
// the values here to change the default minYear, etc., listed above. Note
// that you will need to use parseInt or parseFloat to convert the query
// string value into a number.
//
// Once you've processed all of the filter criteria, run the full JSON data
// set through these using .filter, then use .map and .forEach as before to
// generate the data.
// END OF THE INITIALIZATION FUNCTION
// ! Important caveat of this implementation, there is no specification for
// ! how to handle situations where the same query param is passed multiple
// ! times, or when query params contradict each other.
// ! This implementation sequentially applies filters for every query param
// ! regardless of the other conditions in list of query params.
let movieData = await fetch(url)
.then((response) => response.json())
.catch(() => null);
if (!movieData) return;
// In order to constrain all current and potential future filter functions
// to a singular interface all filter functions will accept a single string
// parameter (the query value).
// Any parsing of this string will be handled by the individual filter functions.
const filterMap = {
minyear: setMinYear,
maxyear: setMaxYear,
mintime: setMinTime,
maxtime: setMaxTime,
minrating: setMinRating,
};
query?.forEach((queryString) => {
const [name, value] = queryString.split("=");
if (name in filterMap) {
movieData = movieData.filter(filterMap[name](value));
}
});
if (!query) {
movieData = movieData.slice(0, 10);
}
movieData
.map(setTitleContent)
.map(appendYear)
.map(appendRuntime)
.map(appendRating)
.forEach((movie) => buildItem(movie, ul));
})();

51
Lab 8/index.html Executable file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="author" content="Michael S. Kirkpatrick">
<title>IMDb Demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
<!-- Step 0: Create the nav bar in all files -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.html">Lab 9</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item"> <a class="nav-link active" href="index.html?minrating=8.5">High Rating</a>
<li class="nav-item"> <a class="nav-link active" href="index.html?minyear=1970&maxyear=1979">The '70s</a>
<li class="nav-item"> <a class="nav-link active" href="index.html?mintime=150">Long Movies</a>
<li class="nav-item"> <a class="nav-link active" href="index.html?maxtime=100&minrating=8.0">Best Short Movies</a>
<li class="nav-item"> <a class="nav-link active" href="index.html?minrating=8.0&minyear=1980&maxyear=1990&mintime=116&maxtime=120">Blade Runner</a>
</ul>
</div>
</div>
</nav>
<br>
<header class="container">
<h1>IMDb Sample</h1>
<p>This page uses a small sample of records from IMDb's public web service.
</header>
<main class="container">
<ul class="list-group" id="target"></ul>
</main>
</body>
<script src="funs.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
</html>

88
Modals/modal.css Executable file
View File

@@ -0,0 +1,88 @@
/* Start by styling the outermost element defining a modal. This element
* should cover the entire screen with a dark but transparent background
* color. It needs a z-index value to make sure it is placed over
* everything else. */
.modal {
position: fixed;
left: 0;
width: 100%;
height: 100%;
background-color: rgb(33, 37, 41, 0.5);
/* STEP 0: Initially, occupy only the bottom half of the screen. You'll
* change this later to cover the whole thing. */
top: 0;
/* STEP 1: Add an opacity value of 0 to make the modal initially
* invisible (completely transparent). */
opacity: 0;
z-index: 0;
}
/* Helper class for the modal. When the modal is activated, it "fades in"
* over the course of .15 seconds, going from fully transparent (can't
* be seen) to fully opaque (blocks out the background). This is optional,
* but it makes for a nicer looking transition. */
.fade {
transition: opacity 0.15s linear;
}
/* STEP 1a: Define a combined selector that applies to any element that has
* the 'fade' class but doesn't have the 'show' class. HINT: There is a
* :not pseudoclass where :not(...) means the rule applies when ... is not
* true. */
.fade:not(.show) {
pointer-events: none;
}
.show {
opacity: 1;
}
/* STEP 2: Define a descendant selector to grab any element with the
* 'modal-dialog' class that is a descendant of a shown modal (has both
* the 'modal' and 'show' classes). */
TODO {
/* The transform property is used to define a change to an element. */
transition: transform 0.3s ease-out;
transform: translate(0, 10vh);
}
/* STEP 2a: Make the modal dialog a centered flexbox to add spacing to
* center the modal content horizontally. */
.modal-dialog {
}
/* STEP 2a: As above, use a descendant selector to grab the 'modal-dialog'
* that is a descendant of 'modal', but only if the 'modal' element doesn't
* have the 'show' class. */
TODO {
transition: transform 0.3s ease-out;
transform: translate(0, -10vh);
}
/* Create the box around the modal content */
.modal-content {
background: white;
min-height: 10vh;
min-width: 30vw;
border: 1px solid black;
border-radius: 0.3rem;
}
/* Basic styling - not part of the tutorial */
body {
background: lightgray;
font-family: "Trebuchet MS", sans-serif;
}
ul {
list-style: none;
}
li {
width: 15vw;
background: white;
border: 1px black solid;
padding: 0.5vh 1vw;
}

63
Modals/modal.html Executable file
View File

@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Modal Demo</title>
<link rel="stylesheet" href="modal.css">
</head>
<body>
<main>
<h1>Modal demo</h1>
<ul>
<li id="modal-btn-1">Modal Step 1</li>
<li id="modal-btn-2">Modal Step 2</li>
<li id="modal-btn-3">Modal Step 3</li>
</ul>
</main>
<!-- STEP 1: add the modal fade classes -->
<div id="modal-step-1" class="modal fade">
<p style="background: blue; color: white">Modal Step 1</p>
</div>
<!-- STEP 2: copy modal 1 and add a modal-dialog around the p -->
<div id="modal-step-2" class="modal fade modal-dialog">
<p style="background: blue; color: white">Modal Step 2</p>
</div>
<!-- STEP 3: copy modal 2 and add a modal-content around the p -->
</body>
<script>
(function () {
/* STEP 1: Add a click event listener to modal-btn-1. When clicked,
* add the 'show' class to modal-step-1. */
//document.querySelector(???).addEventListener('click', () =>
// document.querySelector(???).???);
const modal = document.getElementById('modal-step-1')
const modalBtn1 = document.getElementById('modal-btn-1')
modalBtn1.addEventListener('click', () => modal.classList.add('show'))
modal.addEventListener('click', () => modal.classList.remove('show'))
/* STEP 1: Add a click event listener to modal-step-1 (NOT the button).
* When clicked, from the 'show' class from modal-step-1. */
/* STEP 2: Add click event listeners for modal-btn-2 and modal-step-2
* similar to those above. */
/* STEP 3: Comment out the click event listeners above. Make a loop to
* generate the modal-btn-n and modal-step-n values for n = 1, 2, 3. In
* the loop, add click event listeners to add the 'show' class. */
/* STEP 3a: Instead of relying on a for loop on the indexes, use
* document.querySelectorAll to grab all 'modal' elements. This function
* returns an array. Loop through that array using .forEach and add an
* event to remove the 'show' class from modal-step-N. */
})();
</script>
</html>

33
Prep 2/ch03-proj01.html Executable file
View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chapter 03 Project 01</title>
</head>
<body>
<h1>Fundamentals of Web Development</h1>
<p>
<em>By Randy Connolly and Ricardo Hoar</em>
</p>
<a href="./funwebdev-3rd-ed-cover.jpg">
<img src="./funwebdev-3rd-ed-cover-small.jpg" alt="funwebdev-3rd-ed-cover-small">
</a>
<p>
This textbook covers a broad range of topics required for modern web development.
</p>
<p>
<a href="http://www.funwebdev.com">Learn more</a>
</p>
<h2>First Chapters</h2>
<ol>
<li>Introduction to Web Development</li>
<li>How the Web Works</li>
<li>Introduction to HTML</li>
<li>Introduction to CSS</li>
</ol>
</body>
</html>

30
Prep 2/codingjs-1.js Executable file
View File

@@ -0,0 +1,30 @@
// s/o to https://the-winter.github.io/codingjs
// https://the-winter.github.io/codingjs/exercise.html?name=sleepIn&title=Warmup-1
function sleepIn(weekday, vacation) {
return !weekday || vacation
}
// https://the-winter.github.io/codingjs/exercise.html?name=monkeyTrouble&title=Warmup-1
function monkeyTrouble(aSmile, bSmile) {
return (aSmile && bSmile) || (!aSmile && !bSmile)
}
// https://the-winter.github.io/codingjs/exercise.html?name=sumDouble&title=Warmup-1
function sumDouble(a, b){
return a === b ? a * 4 : a + b
}
// https://the-winter.github.io/codingjs/exercise.html?name=frontBack&title=Warmup-1
function frontBack(str){
const chars = str.split("")
;[chars[0], chars[chars.length - 1]] = [chars[chars.length - 1], chars[0]];
return chars.join("")
}
// https://the-winter.github.io/codingjs/exercise.html?name=intMax&title=Warmup-1
function intMax(a, b, c){
// I'll assume Math.max(a, b, c) is cheating
return a > b && a > c ? a : b > c ? b : c
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
Prep 2/funwebdev-3rd-ed-cover.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

61
Prep 3/ch03-proj02.html Executable file
View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Share Your Travels</title>
</head>
<body>
<header>
<img src="images/share-logo.png" alt="logo" />
<nav>
<a href="#description">Description</a> | <a href="#related">Related</a> | <a href="#reviews">Reviews</a>
</nav>
</header>
<h2>Venice - Grand Canal</h2>
<main>
<section>
<h3 id="description">Description</h3>
<p>This view of the Grand Canal in
<a href="https://en.wikipedia.org/wiki/Venice">Venice</a>
was taken from the <strong>Ponte di Rialto</strong>.
</p>
<figure>
<img src="images/venice.jpg" alt="Venice" />
<figcaption>Photo by Randy Connolly</figcaption>
</figure>
</section>
<section>
<h3 id="related">Related Images</h3>
<img src="images/v1.jpg" alt="More Venice" />
<img src="images/v2.jpg" alt="More Venice" />
<img src="images/v3.jpg" alt="More Venice" />
</section>
<section>
<h3 id="reviews">Reviews</h3>
<article>
<p>By Hypatia on <time>2019-10-23</time></p>
<p>I love Venice in the morning.</p>
</article>
<hr>
<article>
<p>By Curia on <time>2019-12-11</time></p>
<p>I want to visit Venice!</p>
</article>
<p>Copyright &copy; 2020 Share Your Travels</p>
</section>
</main>
<footer>
<p>
<a href="#description">Description</a> | <a href="#related">Related</a> | <a href="#reviews">Reviews</a>
</p>
</footer>
</body>
</html>

BIN
Prep 3/images/share-logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
Prep 3/images/v1.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
Prep 3/images/v2.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
Prep 3/images/v3.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
Prep 3/images/venice.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

101
Prep 4/arrays.html Executable file
View File

@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Array Champion 3000</title>
<link rel="icon" href="https://fav.farm/🏆">
</head>
<body>
<p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
<script>
// It's time to work out those array muscles! 💪
// Complete the following exercises to get your array game on point.
// Become an array CHAMPION!!!1!! 🏆🏆🏆
// Some data we can work with
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
const people = [
'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',
'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',
'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',
'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',
'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'
];
// Array.prototype.filter()
// 1. Filter the list of inventors for those who were born in the 1500's
// Store the result in a variable called 'fifteen'
const fifteen = inventors.filter((inventor) => inventor.year >= 1500 && inventor.year < 1600)
// Array.prototype.map()
// 2. Give us an array of the inventors first and last names
// Store the result in a variable called 'fullNames'
const fullNames = inventors.map((inventor) => `${inventor.first} ${inventor.last}`)
// Array.prototype.toSorted()
// 3. Sort the inventors by birthdate, oldest to youngest
// Store the result in a variable called 'ordered'
const ordered = inventors.toSorted((previous, current) => previous.year - current.year)
// Array.prototype.reduce()
// 4. How many years did all the inventors live all together?
// Store the result in a variable called 'totalYears'
const totalYears = inventors.reduce((previous, current) => previous + (current.passed - current.year), 0)
// 5. Sort the inventors by years lived
// Store the result in a variable called 'oldest'
const oldest = inventors.toSorted((previous, current) => (current.passed - current.year) - (previous.passed - previous.year))
// 6. Create a list of Boulevards in Paris that contain 'de' anywhere in the name
// https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris
// Store the result in a variable called 'category'
const boulevards = [
'Boulevards of Paris', 'City walls of Paris', 'Thiers wall', 'Wall of Charles V', 'Wall of Philip II Augustus', 'City gates of Paris',
"Haussmann's renovation of Paris", 'Boulevards of the Marshals', 'Boulevard Auguste-Blanqui', 'Boulevard Barbès', 'Boulevard Beaumarchais',
"Boulevard de l'Amiral-Bruix", 'Boulevard Mortier', 'Boulevard Poniatowski', 'Boulevard Soult', 'Boulevard des Capucines',
'Boulevard de la Chapelle', 'Boulevard de Clichy', 'Boulevard du Crime', "Boulevard du Général-d'Armée-Jean-Simon", 'Boulevard Haussmann',
"Boulevard de l'Hôpital", 'Boulevard des Italiens', 'Boulevard Lefebvre', 'Boulevard de la Madeleine', 'Boulevard de Magenta',
'Boulevard Malesherbes', 'Boulevard Marguerite-de-Rochechouart', 'Boulevard Montmartre', 'Boulevard du Montparnasse', 'Boulevard Raspail',
'Boulevard Richard-Lenoir', 'Boulevard Saint-Germain', 'Boulevard Saint-Michel', 'Boulevard de Sébastopol', 'Boulevard de Strasbourg',
'Boulevard du Temple', 'Boulevard Voltaire', 'Boulevard de la Zone']
const category = boulevards.filter((boulevard) => /de/.test(boulevard))
// 7. Sorting exercise
// Sort the people alphabetically by last name
// Store the result in a variable called 'alpha'
const alpha = people.toSorted((previous, current) => previous.split(", ")[0].localeCompare(current.split(", ")[0]))
// 8. Reduce Exercise
// Sum up the instances of each of these:
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck'];
// Store the result in a variable called 'transportation'
// The result should be an object where the keys are the names of the transportation methods and the values are the number of instances
const transportation = data.reduce((obj, current) => Object.assign(obj, { [current]: (obj[current] ?? 0) + 1 }), {})
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

BIN
Prep 6/Screenshots/Holy Grail.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 KiB

72
Prep 6/fluid-columns.css Executable file
View File

@@ -0,0 +1,72 @@
.wrapper {
display: grid;
grid-template-areas:
"header"
"nav"
"content"
"sidebar"
"ad"
"footer";
gap: 20px;
}
.wrapper > * {
background-color: #ffec99;
border-radius: 5px;
border: 1px solid red;
padding: 10px;
}
.main-head {
grid-area: header;
}
.content {
grid-area: content;
}
.main-nav {
grid-area: nav;
}
.side {
grid-area: sidebar;
}
.ad {
grid-area: ad;
}
.main-footer {
grid-area: footer;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
@media (min-width: 500px) {
.wrapper {
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
nav ul {
display: flex;
justify-content: space-between;
}
}
@media (min-width: 700px) {
.wrapper {
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
}
}

35
Prep 6/fluid-columns.html Executable file
View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fluid Columns</title>
<link rel="stylesheet" href="fluid-columns.css">
</head>
<body>
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Animi deserunt placeat molestiae vitae
voluptates modi distinctio repudiandae, expedita suscipit tenetur nesciunt magnam autem maxime ea libero
totam soluta ipsa fuga.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
</body>
</html>

34
Prep 6/holy-grail.css Executable file
View File

@@ -0,0 +1,34 @@
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
header,
footer {
background-color: sandybrown;
}
.middler {
display: flex;
flex-direction: row;
flex-grow: 1;
}
aside {
flex-basis: 150px;
background-color: cornsilk;
}
main {
flex-grow: 1;
flex-basis: 0;
}
main,
aside,
header,
footer {
padding: 10px;
}

42
Prep 6/holy-grail.html Executable file
View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Holy Grail</title>
<link rel="stylesheet" href="holy-grail.css" />
</head>
<body>
<header>
<h1>header</h1>
</header>
<div class="middler">
<aside class="lefter">
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quibusdam sed, ad voluptas itaque quasi
voluptatum ea iure doloremque reprehenderit et illo dolores cum magni odio consequatur id ab ipsa
provident!</p>
</aside>
<main>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quibusdam sed, ad voluptas itaque quasi
voluptatum ea iure doloremque reprehenderit et illo dolores cum magni odio consequatur id ab ipsa
provident!</p>
</main>
<aside class="righter">
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quibusdam sed, ad voluptas itaque quasi
voluptatum ea iure doloremque reprehenderit et illo dolores cum magni odio consequatur id ab ipsa
provident!</p>
</aside>
</div>
<footer>
<h2>footer</h2>
</footer>
</body>
</html>

61
Prep 7/index.html Executable file
View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Prep 7</title>
<meta author="Nicholas Tamassia">
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<form action="" id="number-form">
<label for="number-input">Number of images:</label>
<input id="number-input" name="image-number" type="number">
<button type="submit">Generate</button>
</form>
<form action="" id="color-form">
<label for="color-input">Background color</label>
<input id="color-input" name="background-color" type="color" />
<button type="submit">Change background</button>
</form>
<div id="wrapper"></div>
<script>
const wrapper = document.getElementById('wrapper')
const numberForm = document.getElementById('number-form')
const colorForm = document.getElementById('color-form')
numberForm.onsubmit = (event) => {
event.preventDefault()
const imageCount = Number(new FormData(numberForm).get('image-number'))
if (imageCount < 0) return
while (wrapper.firstChild) {
wrapper.removeChild(wrapper.lastChild)
}
for (let i = 0; i < imageCount; i++) {
const img = new Image(200, 200)
img.src = `https://picsum.photos/200/200?random=${Math.ceil(Math.random() * 100)}`
wrapper.appendChild(img)
}
}
colorForm.onsubmit = (event) => {
event.preventDefault()
const formData = new FormData(colorForm)
document.body.style.backgroundColor = formData.get('background-color')
}
</script>
</body>
</html>

34
Prep 8/load.html Executable file
View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Nicholas Tamassia - Prep 8 - Load</title>
<style>
/* YOUR STYLE HERE */
</style>
</head>
<body>
<div id="name-display"></div>
<div id="favorite-display"></div>
<div id="quotes-display"></div>
<script>
const nameDisplay = document.getElementById('name-display')
const favoriteDisplay = document.getElementById('favorite-display')
const quotesDisplay = document.getElementById('quotes-display')
nameDisplay.textContent = localStorage.getItem('fullname')
favoriteDisplay.textContent = Number.parseFloat(localStorage.getItem('favnumber')) + 5
JSON.parse(localStorage.getItem('quotes')).forEach((quote) => {
const listItem = document.createElement('li')
listItem.textContent = quote
quotesDisplay.appendChild(listItem)
});
</script>
</body>
</html>

33
Prep 8/save.html Executable file
View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Nicholas Tamassia - Prep 8 - Save</title>
<style>
/* YOUR STYLE HERE */
</style>
</head>
<body>
Data saved!
<script>
const items = {
'fullname': 'Nicholas Tamassia',
'favnumber': '28', // It's a Perfect Number! Literally.
'quotes': [
"Savior, conqueror, hero, villain. You are all things, Revan... and yet you are nothing. In the end, you belong to neither the light nor the darkness. You will forever stand alone.",
"Do you know the difference between an error and a mistake? Anyone can make an error. But that error doesn't become a mistake until you refuse to correct it.",
"It is said that one should keep one's allies within view, and one's enemies within reach"
]
}
for (const [key, value] of Object.entries(items)) {
localStorage.setItem(key, typeof value === "string" ? value : JSON.stringify(value))
}
</script>
</body>
</html>