First commit
This commit is contained in:
188
Lab 8/funs.js
Executable file
188
Lab 8/funs.js
Executable 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
51
Lab 8/index.html
Executable 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>
|
||||
Reference in New Issue
Block a user