From 62ba0e7f6e284e817e6377a5dcf56fee2c31ed3d Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Fri, 21 Sep 2018 14:29:34 +0100 Subject: [PATCH 01/30] Initialise App - Return search results on page Multi-line description of commit, feel free to be detailed. [Ticket: X] --- index.html | 27 ++++++++++++++ src/index.js | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/omdb.http | 1 + src/style.css | 0 4 files changed, 127 insertions(+) create mode 100644 index.html create mode 100644 src/index.js create mode 100644 src/omdb.http create mode 100644 src/style.css diff --git a/index.html b/index.html new file mode 100644 index 00000000..54ab08e0 --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + + + + Document + + + + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..5c146f14 --- /dev/null +++ b/src/index.js @@ -0,0 +1,99 @@ +const paramsInit = { + base: 'http://www.omdbapi.com/?apikey=507b4100' +}; + +const setUrl = (paramsInit, query = '', id = '') => { + return `${paramsInit.base}&s=${query}&i=${id}`; +}; + +const initUrl = setUrl(paramsInit, 'Titanic'); + +const searchFilmBytitle = title => { + console.log(setUrl(paramsInit, title)); + fetch(setUrl(paramsInit, title)) + .then(response => response.json()) + .then(body => console.log(body) || displaySearchResults(body.Search)) + .catch(error => console.log(error)); +}; + +const displaySearchResults = films => { + const searchResults = createElement('div'); + console.log(films); + films.forEach(film => { + const filmListing = createFilmSearchListing( + film.Title, + film.Year, + film.Poster + ); + addElementToParent(searchResults, filmListing); + }); + const searchResultsWrapper = document.querySelector('#search-results'); + searchResultsWrapper.innerHTML = ''; + addElementToParent(searchResultsWrapper, searchResults); +}; + +const createFilmSearchListing = (title, year, poster) => { + const filmListing = createArticle('film'); + const filmTitle = createElement('h2', title); + const releaseYear = createElement('p', year); + const filmPoster = createImageElement(poster); + addElementToParent(filmListing, filmTitle); + console.log(filmListing); + addElementToParent(filmListing, releaseYear); + addElementToParent(filmListing, filmPoster); + + return filmListing; +}; + +const createArticle = (articleClass = '') => { + const article = document.createElement('article'); + article.classList.add(articleClass); + + return article; +}; + +const createElement = (type, title = '') => { + const element = document.createElement(type); + element.innerHTML = title; + + return element; +}; + +const createImageElement = url => { + const image = document.createElement('img'); + image.src = url; + + return image; +}; + +const addElementToParent = (parent, element) => { + return parent.appendChild(element); +}; + +const createFilmDetails = (title, year, poster) => { + document.create; +}; + +searchFilmBytitle('Titanic'); + +// const cleanSearchResults = array => { +// console.log(array.map(film => dataFilterFilm(film))); +// }; + +// const dataFilterFilm = data => { +// const filteredData = Object.assign( +// {}, +// { title: data.Title, year: data.Year, poster: data.Poster } +// ); +// return filteredData; +// }; + +/* event listeners */ + +const searchForm = document.querySelector('#search'); + +searchForm.addEventListener('submit', e => { + e.preventDefault(); + const query = e.currentTarget.query.value; + searchFilmBytitle(query); +}); diff --git a/src/omdb.http b/src/omdb.http new file mode 100644 index 00000000..1fc95eaa --- /dev/null +++ b/src/omdb.http @@ -0,0 +1 @@ +http://www.omdbapi.com/?apikey=507b4100&s=Titanic&t=&i= \ No newline at end of file diff --git a/src/style.css b/src/style.css new file mode 100644 index 00000000..e69de29b From 0fb1e19ba98d552c42e34ea7e57b6ee37cd5adff Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Fri, 21 Sep 2018 17:25:06 +0100 Subject: [PATCH 02/30] show film details --- README.md | 82 ++++++++++++++++++++++++++++++------------------- index.html | 15 +++++---- src/index.js | 85 +++++++++++++++++++++++++++++++++++---------------- src/omdb.http | 2 +- src/style.css | 4 +++ 5 files changed, 122 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 49093dd2..9f291ab1 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,68 @@ # Project Cinema -We want to create a movie search engine. To power it we will use the [Open Movie Database](http://www.omdbapi.com) API. +## A movie search engine powered by the [Open Movie Database](http://www.omdbapi.com) API. -To start using the OMDB API you will first need to sign up with them to receive and API key. The key issued to you will allow you 1000 requests per day and you will need to include this key as part of every request. +--- -To get started, fork and clone this repo. Please submit a pull request after your first commit and push commits regularly. +### Getting started -You should complete as many of the following tasks as you can. +- Search for a film. +- Tap to reveal more details. -- [ ] Work using mobile first, that is create the mobile version first and add tablet and desktop versions after. -- [ ] Create an HTML page which should have a `form` at the top which contains a text input and a submit button. Below it should have a placeholder element for the returned results. -- [ ] Use JavaScript to capture the `submit` event in your search form, extract the query string from the text input and use that to make an API call to the Open Movie Database API to search for films which match the query string using `fetch`. `console.log` the results -- [ ] Display the data returned by the API including title, year and poster picture +### UX -**Movie details** +- [ ] **Work using mobile first, that is create the mobile version first and add tablet and desktop versions after.** +- A mobile-first responsive design responsive that looks great at different screen widths +- [ ] ~~Create an HTML page which should have a `form` at the top which contains a text input and a submit button. Below it should have a placeholder element for the returned results.~~ +- [ ] ~~Use JavaScript to capture the `submit` event in your search form, extract the query string from the text input and use that to make an API call to the Open Movie Database API to search for films which match the query string using `fetch`. `console.log` the results~~ +- [ ] ~~Display the data returned by the API including title, year and poster picture~~ -- [ ] Adjust your layout to create room for a detailed view of movie information -- [ ] Capture clicks on your movie results items and use that information to make another request to the API for detailed movie information. Using event delegation will help you here. `console.log` the returned result -- [ ] Display the detailed movie result in the in the details view you created earlier -- [ ] Make your design responsive and ensure it looks great at different screen widths +### Movie details -**Your own feature** +### Technology used -- [ ] Implement any feature you would find useful or interesting +- HTML +- JavaScript +- CSS -**Stretch goals** +#### Challenges and learnings + +## TODO + +- [ ] **Implement any feature you would find useful or interesting** + +- [ ] **Implement pagination so that users can navigate between all movies in search results rather than just the first ten** + +- [ ] **Include a screenshot of your app in the README.** + +- [ ] **Explain functionality created, mention any outstanding issues and possible features you would include if you had more time** + +--- + +### stretch goal - favourites -- [ ] Implement pagination so that users can navigate between all movies in search results rather than just the first ten - [ ] Create a favourites list. It's up to you how you would add items to favourites. You could add a button or otherwise. Display a list of favourites somewhere on your page. -- [ ] Make the favourites list sortable. Add `up` and `down` buttons to your favourites which on click will move the result in relevant direction -- [ ] Save favourites locally using `localStorage` so that favourites persist in browser after refresh -- [ ] Let's create a search preview. It should listen for change events on input events and submit a search request with current query string. Display the search preview results in an absolute positioned container just below the search box. -Hint: You may want to kick of the searching after at least 3 characters have been typed. -## Objectives +- [ ] Make the favourites list sortable. Add `up` and `down` buttons to your favourites which on click will move the result in relevant direction. + +- [ ] Save favourites locally using `localStorage` so that favourites persist in browser after refresh. + +--- + +## stretch goal - search preview + +- [ ] Let's create a search preview. It should listen for change events on input events and submit a search request with current query string. Display the search preview results in an absolute positioned container just below the search box. + + Hint: You may want to kick of the searching after at least 3 characters have been typed. -* We want to see great looking webpages that work well at all screen widths -* Your code should have consistent indentation and sensible naming -* Use lots of concise, reusable functions with a clear purpose -* Add code comments where it is not immediately obvious what your code does -* Your code should not throw errors and handle edge cases gracefully. For example not break if server fails to return expected results -* Use BEM methodology to style your page -* Try to use pure functions as much as possible, but keep in mind it will not be possible to make all functions pure. +--- -## README.md +### The brief -When finished, include a README.md in your repo. Someone who is not familiar with the project should be able to look at it and understand what it is and what to do with it. Explain functionality created, mention any outstanding issues and possible features you would include if you had more time. List technologies used to create the app. Include a screenshot of your app in the README. +- We want to see great looking webpages that work well at all screen widths +- Your code should have consistent indentation and sensible naming +- Use lots of concise, reusable functions with a clear purpose +- Add code comments where it is not immediately obvious what your code does +- Your code should not throw errors and handle edge cases gracefully. For example not break if server fails to return expected results +- Use BEM methodology in your markup and CSS to style your page +- Try to use pure functions as much as possible, but keep in mind it will not be possible to make all functions pure. diff --git a/index.html b/index.html index 54ab08e0..f1c7469d 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ Document + @@ -14,14 +15,12 @@ -
-
- -
- -
- +
+
- \ No newline at end of file + + + +​ \ No newline at end of file diff --git a/src/index.js b/src/index.js index 5c146f14..73be73c5 100644 --- a/src/index.js +++ b/src/index.js @@ -16,11 +16,14 @@ const searchFilmBytitle = title => { .catch(error => console.log(error)); }; +/* Search resutls */ + const displaySearchResults = films => { const searchResults = createElement('div'); console.log(films); films.forEach(film => { const filmListing = createFilmSearchListing( + film.imdbID, film.Title, film.Year, film.Poster @@ -29,10 +32,11 @@ const displaySearchResults = films => { }); const searchResultsWrapper = document.querySelector('#search-results'); searchResultsWrapper.innerHTML = ''; + addElementToParent(searchResultsWrapper, searchResults); }; -const createFilmSearchListing = (title, year, poster) => { +const createFilmSearchListing = (id, title, year, poster) => { const filmListing = createArticle('film'); const filmTitle = createElement('h2', title); const releaseYear = createElement('p', year); @@ -41,6 +45,8 @@ const createFilmSearchListing = (title, year, poster) => { console.log(filmListing); addElementToParent(filmListing, releaseYear); addElementToParent(filmListing, filmPoster); + console.log(filmListing); + filmListing.setAttribute('data-ID', id); return filmListing; }; @@ -52,6 +58,57 @@ const createArticle = (articleClass = '') => { return article; }; +/* film details */ + +const displayFilmDetails = film => { + const filmDetails = `

Deets

+

${film.Title}

+poster +

${film.Director}

+

${film.Released}

+

${film.Rated}

+

${film.Runtime}

+

${film.imdbRating}

+

${film.Plot}

+ + +`; + const filmDetailsWrapper = document.querySelector('#film-details'); + filmDetailsWrapper.innerHTML = filmDetails; +}; + +const getFilmByID = id => { + console.log(setUrl(paramsInit, '', id)); + fetch(setUrl(paramsInit, '', id)) + .then(response => response.json()) + .then(body => displayFilmDetails(body)) + .catch(error => console.log(error)); +}; + +/* event listeners */ + +document.querySelector('#search').addEventListener('submit', e => { + e.preventDefault(); + const query = e.currentTarget.query.value; + searchFilmBytitle(query); +}); + +document.querySelector('#search-results').addEventListener('click', e => { + console.log(e.target.parentNode.attributes); + const id = e.target.parentNode.attributes[1].nodeValue; + console.log(id); + getFilmByID(id); +}); + +/* utility functions */ + const createElement = (type, title = '') => { const element = document.createElement(type); element.innerHTML = title; @@ -70,30 +127,6 @@ const addElementToParent = (parent, element) => { return parent.appendChild(element); }; -const createFilmDetails = (title, year, poster) => { - document.create; -}; +/* init */ searchFilmBytitle('Titanic'); - -// const cleanSearchResults = array => { -// console.log(array.map(film => dataFilterFilm(film))); -// }; - -// const dataFilterFilm = data => { -// const filteredData = Object.assign( -// {}, -// { title: data.Title, year: data.Year, poster: data.Poster } -// ); -// return filteredData; -// }; - -/* event listeners */ - -const searchForm = document.querySelector('#search'); - -searchForm.addEventListener('submit', e => { - e.preventDefault(); - const query = e.currentTarget.query.value; - searchFilmBytitle(query); -}); diff --git a/src/omdb.http b/src/omdb.http index 1fc95eaa..5f7f2f15 100644 --- a/src/omdb.http +++ b/src/omdb.http @@ -1 +1 @@ -http://www.omdbapi.com/?apikey=507b4100&s=Titanic&t=&i= \ No newline at end of file +http://www.omdbapi.com/?apikey=507b4100&s=&i=tt1640571 \ No newline at end of file diff --git a/src/style.css b/src/style.css index e69de29b..f40ef752 100644 --- a/src/style.css +++ b/src/style.css @@ -0,0 +1,4 @@ +.film-details__actors, +.film-details__genres { + display: none; +} From 1704260a27a62fc9de7a7f25bcb9ff9f9b94b571 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 10:42:09 +0100 Subject: [PATCH 03/30] favourite button --- README.md | 2 ++ index.html | 2 +- src/index.js | 61 +++++++++++++++++++++++++++++++++++----------------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 9f291ab1..9b65b7d5 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ ## TODO +- [ ] **Filter fetch results to show only movies** + - [ ] **Implement any feature you would find useful or interesting** - [ ] **Implement pagination so that users can navigate between all movies in search results rather than just the first ten** diff --git a/index.html b/index.html index f1c7469d..13043232 100644 --- a/index.html +++ b/index.html @@ -17,7 +17,7 @@
- + diff --git a/src/index.js b/src/index.js index 73be73c5..a3a6e518 100644 --- a/src/index.js +++ b/src/index.js @@ -1,18 +1,35 @@ +import * as storage from './localStorage.js'; +// import * as get from './dataGetters'; + +const myStorage = window.localStorage; + +if (storage.storageAvailable('localStorage')) { + // console.log(`Welcome, lets start saving locally!`); +} else { + console.log('Please enable local storage to save your favourites.'); +} + const paramsInit = { - base: 'http://www.omdbapi.com/?apikey=507b4100' + base: 'http://www.omdbapi.com/?apikey=507b4100&type=movie' }; const setUrl = (paramsInit, query = '', id = '') => { return `${paramsInit.base}&s=${query}&i=${id}`; }; -const initUrl = setUrl(paramsInit, 'Titanic'); - const searchFilmBytitle = title => { - console.log(setUrl(paramsInit, title)); + // console.log(setUrl(paramsInit, title)); fetch(setUrl(paramsInit, title)) .then(response => response.json()) - .then(body => console.log(body) || displaySearchResults(body.Search)) + .then(body => displaySearchResults(body.Search)) + .catch(error => console.log(error)); +}; + +const getFilmByID = id => { + // console.log(setUrl(paramsInit, '', id)); + fetch(setUrl(paramsInit, '', id)) + .then(response => response.json()) + .then(body => writeFilmDetails('#film-details', body)) .catch(error => console.log(error)); }; @@ -20,7 +37,7 @@ const searchFilmBytitle = title => { const displaySearchResults = films => { const searchResults = createElement('div'); - console.log(films); + // console.log(films); films.forEach(film => { const filmListing = createFilmSearchListing( film.imdbID, @@ -42,10 +59,10 @@ const createFilmSearchListing = (id, title, year, poster) => { const releaseYear = createElement('p', year); const filmPoster = createImageElement(poster); addElementToParent(filmListing, filmTitle); - console.log(filmListing); + // console.log(filmListing); addElementToParent(filmListing, releaseYear); addElementToParent(filmListing, filmPoster); - console.log(filmListing); + // console.log(filmListing); filmListing.setAttribute('data-ID', id); return filmListing; @@ -60,9 +77,11 @@ const createArticle = (articleClass = '') => { /* film details */ -const displayFilmDetails = film => { - const filmDetails = `

Deets

-

${film.Title}

+const createFilmDetails = film => { + console.log(film); + return `

Details

+

${film.Title}

+ poster

${film.Director}

${film.Released}

@@ -80,16 +99,18 @@ const displayFilmDetails = film => {
  • Drama
  • Romance
  • `; - const filmDetailsWrapper = document.querySelector('#film-details'); - filmDetailsWrapper.innerHTML = filmDetails; }; -const getFilmByID = id => { - console.log(setUrl(paramsInit, '', id)); - fetch(setUrl(paramsInit, '', id)) - .then(response => response.json()) - .then(body => displayFilmDetails(body)) - .catch(error => console.log(error)); +const writeFilmDetails = (parent, film) => { + document.querySelector(parent).innerHTML = createFilmDetails(film); + document.querySelector('#fav').addEventListener('click', e => { + const date = new Date(Date.now()).toDateString().slice(4); + const favData = Object.assign( + {}, + { id: e.target.attributes[2].value, title: film.Title, favOn: date } + ); + console.log(favData); + }); }; /* event listeners */ @@ -129,4 +150,4 @@ const addElementToParent = (parent, element) => { /* init */ -searchFilmBytitle('Titanic'); +searchFilmBytitle('Kidulthood'); From c5ad6d1e49ad6e3850deba51ec9a9e2e1615b65b Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 10:42:56 +0100 Subject: [PATCH 04/30] local storage --- src/localStorage.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/localStorage.js diff --git a/src/localStorage.js b/src/localStorage.js new file mode 100644 index 00000000..7ace6f88 --- /dev/null +++ b/src/localStorage.js @@ -0,0 +1,26 @@ +function storageAvailable(type) { + try { + var storage = window[type], + x = '__storage_test__'; + storage.setItem(x, x); + storage.removeItem(x); + return true; + } catch (e) { + return ( + e instanceof DOMException && + // everything except Firefox + (e.code === 22 || + // Firefox + e.code === 1014 || + // test name field too, because code might not be present + // everything except Firefox + e.name === 'QuotaExceededError' || + // Firefox + e.name === 'NS_ERROR_DOM_QUOTA_REACHED') && + // acknowledge QuotaExceededError only if there's something already stored + storage.length !== 0 + ); + } +} + +export { storageAvailable }; From f2d103c073202a625b089c846ec32e8fa9bab087 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 14:03:27 +0100 Subject: [PATCH 05/30] add favourites and get favourites on page load --- index.html | 6 ++++ src/index.js | 83 +++++++++++++++++++++++++++++++++++++++++++-------- src/style.css | 4 +++ 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/index.html b/index.html index 13043232..237f9944 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,12 @@ +
    +
      +
    • Some Like it Hot 14 + Sep 2018
    • +
    +
    diff --git a/src/index.js b/src/index.js index a3a6e518..341b87e0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,13 @@ import * as storage from './localStorage.js'; -// import * as get from './dataGetters'; const myStorage = window.localStorage; if (storage.storageAvailable('localStorage')) { - // console.log(`Welcome, lets start saving locally!`); + // localStorage.clear(); + for (let key in myStorage) { + console.log(key); + } + console.log(myStorage); } else { console.log('Please enable local storage to save your favourites.'); } @@ -22,7 +25,13 @@ const searchFilmBytitle = title => { fetch(setUrl(paramsInit, title)) .then(response => response.json()) .then(body => displaySearchResults(body.Search)) - .catch(error => console.log(error)); + .catch(error => { + if (films === undefined) { + alert('No films match your query, please search again'); + } else { + alert(error); + } + }); }; const getFilmByID = id => { @@ -103,16 +112,40 @@ const createFilmDetails = film => { const writeFilmDetails = (parent, film) => { document.querySelector(parent).innerHTML = createFilmDetails(film); - document.querySelector('#fav').addEventListener('click', e => { - const date = new Date(Date.now()).toDateString().slice(4); - const favData = Object.assign( - {}, - { id: e.target.attributes[2].value, title: film.Title, favOn: date } - ); - console.log(favData); - }); + setFavButton(film); +}; + +/* favourites list */ +const makeFavourite = id => { + const favFilm = JSON.parse(myStorage[id]); + const favourite = document.createElement('li'); + favourite.classList.add('fav-list__film'); + favourite.setAttribute('data-id', id); + favourite.innerHTML = ` + ${favFilm['title']} + ${favFilm['favDate']} + `; + return favourite; +}; + +const addToFavourites = (id, e) => { + const favouriteFilm = makeFavourite(id, e); + const parent = document.querySelector('#fav-list'); + addElementToParent(parent, favouriteFilm); }; +const getFavourites = data => { + // const favouritesData = JSON.parse(data); + const keys = []; + for (let key in data) { + keys.push(key); + } + keys.forEach(key => { + const favouriteFilm = makeFavourite(key); + const parent = document.querySelector('#fav-list'); + addElementToParent(parent, favouriteFilm); + }); +}; /* event listeners */ document.querySelector('#search').addEventListener('submit', e => { @@ -128,6 +161,30 @@ document.querySelector('#search-results').addEventListener('click', e => { getFilmByID(id); }); +const setFavButton = film => { + document.querySelector('#fav').addEventListener('click', e => { + // e.target.classList.toggle('fav--active'); + const date = new Date(Date.now()) + .toDateString() + .slice(4) + .split(' '); + const favData = Object.assign( + {}, + { + id: e.target.attributes[2].value, + title: film.Title, + isFav: true, + favDate: `${date[1]} ${date[0]}, ${date[2]}` + } + ); + const id = favData.id; + const details = JSON.stringify(favData); + + myStorage.setItem(id, `${details}`); + addToFavourites(id, e); + }); +}; + /* utility functions */ const createElement = (type, title = '') => { @@ -149,5 +206,7 @@ const addElementToParent = (parent, element) => { }; /* init */ +console.log(myStorage); +getFavourites(myStorage); -searchFilmBytitle('Kidulthood'); +// searchFilmBytitle('Kidulthood'); diff --git a/src/style.css b/src/style.css index f40ef752..21631f56 100644 --- a/src/style.css +++ b/src/style.css @@ -2,3 +2,7 @@ .film-details__genres { display: none; } + +.fav--active { + background: green; +} From b933e9c576c6389b42d582448d8eba6e72161509 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 15:21:27 +0100 Subject: [PATCH 06/30] add all favourites on load - fixed bug in itterating over list of favourites --- index.html | 5 +---- src/index.js | 13 +++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/index.html b/index.html index 237f9944..a1a0b648 100644 --- a/index.html +++ b/index.html @@ -16,10 +16,7 @@
    -
      -
    • Some Like it Hot 14 - Sep 2018
    • -
    +
      diff --git a/src/index.js b/src/index.js index 341b87e0..1b19de85 100644 --- a/src/index.js +++ b/src/index.js @@ -135,17 +135,14 @@ const addToFavourites = (id, e) => { }; const getFavourites = data => { - // const favouritesData = JSON.parse(data); - const keys = []; - for (let key in data) { - keys.push(key); - } - keys.forEach(key => { - const favouriteFilm = makeFavourite(key); + for (let i = 0; i < data.length; i++) { + const film = JSON.parse(data.getItem(data.key(i))); + const favouriteFilm = makeFavourite(film.id); const parent = document.querySelector('#fav-list'); addElementToParent(parent, favouriteFilm); - }); + } }; + /* event listeners */ document.querySelector('#search').addEventListener('submit', e => { From b03e5e6072066b5e0345213f195243ddf5d7c7ed Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 15:44:39 +0100 Subject: [PATCH 07/30] count favourite films saved --- index.html | 15 +++++++++------ src/index.js | 36 +++++++++++++++--------------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/index.html b/index.html index a1a0b648..19391e7c 100644 --- a/index.html +++ b/index.html @@ -10,17 +10,20 @@ - -
      -
        +
        +
        +

        You’ve saved 0 favourite films

        +
          +
          -
          -
          - +
          +
          + diff --git a/src/index.js b/src/index.js index 1b19de85..b30eb2c6 100644 --- a/src/index.js +++ b/src/index.js @@ -4,10 +4,7 @@ const myStorage = window.localStorage; if (storage.storageAvailable('localStorage')) { // localStorage.clear(); - for (let key in myStorage) { - console.log(key); - } - console.log(myStorage); + console.log(`You’re all set to save your favourite films`); } else { console.log('Please enable local storage to save your favourites.'); } @@ -21,7 +18,6 @@ const setUrl = (paramsInit, query = '', id = '') => { }; const searchFilmBytitle = title => { - // console.log(setUrl(paramsInit, title)); fetch(setUrl(paramsInit, title)) .then(response => response.json()) .then(body => displaySearchResults(body.Search)) @@ -35,7 +31,6 @@ const searchFilmBytitle = title => { }; const getFilmByID = id => { - // console.log(setUrl(paramsInit, '', id)); fetch(setUrl(paramsInit, '', id)) .then(response => response.json()) .then(body => writeFilmDetails('#film-details', body)) @@ -46,7 +41,6 @@ const getFilmByID = id => { const displaySearchResults = films => { const searchResults = createElement('div'); - // console.log(films); films.forEach(film => { const filmListing = createFilmSearchListing( film.imdbID, @@ -68,10 +62,8 @@ const createFilmSearchListing = (id, title, year, poster) => { const releaseYear = createElement('p', year); const filmPoster = createImageElement(poster); addElementToParent(filmListing, filmTitle); - // console.log(filmListing); addElementToParent(filmListing, releaseYear); addElementToParent(filmListing, filmPoster); - // console.log(filmListing); filmListing.setAttribute('data-ID', id); return filmListing; @@ -87,7 +79,6 @@ const createArticle = (articleClass = '') => { /* film details */ const createFilmDetails = film => { - console.log(film); return `

          Details

          ${film.Title}

          @@ -119,12 +110,16 @@ const writeFilmDetails = (parent, film) => { const makeFavourite = id => { const favFilm = JSON.parse(myStorage[id]); const favourite = document.createElement('li'); - favourite.classList.add('fav-list__film'); + favourite.classList.add('favourites__list__film'); favourite.setAttribute('data-id', id); favourite.innerHTML = ` - ${favFilm['title']} - ${favFilm['favDate']} - `; + ${ + favFilm['title'] + } + ${ + favFilm['favDate'] + } + `; return favourite; }; @@ -135,12 +130,14 @@ const addToFavourites = (id, e) => { }; const getFavourites = data => { + const parent = document.querySelector('#favourites__list'); + parent.innerHTML = ''; for (let i = 0; i < data.length; i++) { const film = JSON.parse(data.getItem(data.key(i))); const favouriteFilm = makeFavourite(film.id); - const parent = document.querySelector('#fav-list'); addElementToParent(parent, favouriteFilm); } + document.querySelector('#favourites__count').textContent = myStorage.length; }; /* event listeners */ @@ -152,14 +149,13 @@ document.querySelector('#search').addEventListener('submit', e => { }); document.querySelector('#search-results').addEventListener('click', e => { - console.log(e.target.parentNode.attributes); const id = e.target.parentNode.attributes[1].nodeValue; - console.log(id); getFilmByID(id); }); const setFavButton = film => { document.querySelector('#fav').addEventListener('click', e => { + // TODO: highlight favourited film when display details // e.target.classList.toggle('fav--active'); const date = new Date(Date.now()) .toDateString() @@ -178,7 +174,8 @@ const setFavButton = film => { const details = JSON.stringify(favData); myStorage.setItem(id, `${details}`); - addToFavourites(id, e); + // addToFavourites(id, e); + getFavourites(myStorage); }); }; @@ -203,7 +200,4 @@ const addElementToParent = (parent, element) => { }; /* init */ -console.log(myStorage); getFavourites(myStorage); - -// searchFilmBytitle('Kidulthood'); From 203777e9559ffbede06345ed5bb2e048df8b7adb Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 16:14:39 +0100 Subject: [PATCH 08/30] delete individual favourites or delete all and update counter --- index.html | 3 +- src/index.js | 81 +++++++++++++++++++++++++++++++++------------------ src/style.css | 4 +++ 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/index.html b/index.html index 19391e7c..50e95b09 100644 --- a/index.html +++ b/index.html @@ -17,7 +17,8 @@
          -

          You’ve saved 0 favourite films

          +

          You’ve saved 0 favourite films

            diff --git a/src/index.js b/src/index.js index b30eb2c6..e696c0cc 100644 --- a/src/index.js +++ b/src/index.js @@ -119,14 +119,40 @@ const makeFavourite = id => { ${ favFilm['favDate'] } - `; + `; return favourite; }; -const addToFavourites = (id, e) => { - const favouriteFilm = makeFavourite(id, e); - const parent = document.querySelector('#fav-list'); - addElementToParent(parent, favouriteFilm); +// const addToFavourites = (id, e) => { +// const favouriteFilm = makeFavourite(id, e); +// const parent = document.querySelector('#fav-list'); +// addElementToParent(parent, favouriteFilm); +// }; + +const setFavButton = film => { + document.querySelector('#fav').addEventListener('click', e => { + // TODO: highlight favourited film when display details + // e.target.classList.toggle('fav--active'); + const date = new Date(Date.now()) + .toDateString() + .slice(4) + .split(' '); + const favData = Object.assign( + {}, + { + id: e.target.attributes[2].value, + title: film.Title, + isFav: true, + favDate: `${date[1]} ${date[0]}, ${date[2]}` + } + ); + const id = favData.id; + const details = JSON.stringify(favData); + + myStorage.setItem(id, `${details}`); + // addToFavourites(id, e); + getFavourites(myStorage); + }); }; const getFavourites = data => { @@ -142,42 +168,39 @@ const getFavourites = data => { /* event listeners */ +/* Search */ + document.querySelector('#search').addEventListener('submit', e => { e.preventDefault(); const query = e.currentTarget.query.value; searchFilmBytitle(query); }); +/* Film details */ + document.querySelector('#search-results').addEventListener('click', e => { - const id = e.target.parentNode.attributes[1].nodeValue; + const id = e.target.parentNode.dataset.id; getFilmByID(id); }); -const setFavButton = film => { - document.querySelector('#fav').addEventListener('click', e => { - // TODO: highlight favourited film when display details - // e.target.classList.toggle('fav--active'); - const date = new Date(Date.now()) - .toDateString() - .slice(4) - .split(' '); - const favData = Object.assign( - {}, - { - id: e.target.attributes[2].value, - title: film.Title, - isFav: true, - favDate: `${date[1]} ${date[0]}, ${date[2]}` - } - ); - const id = favData.id; - const details = JSON.stringify(favData); +/* Favourites */ - myStorage.setItem(id, `${details}`); - // addToFavourites(id, e); +document.querySelector('#favourites').addEventListener('click', e => { + if (e.target.innerText === 'Delete') { + const id = e.target.parentNode.dataset.id; + e.target.parentNode.classList.add('hidden'); + + myStorage.removeItem(id); + document.querySelector('#favourites__count').textContent = myStorage.length; + } else if (e.target.innerText === 'Delete all') { + myStorage.clear(); getFavourites(myStorage); - }); -}; + } +}); + +/* Delete all favourites */ + +/* Delete individual favourite */ /* utility functions */ diff --git a/src/style.css b/src/style.css index 21631f56..37257eff 100644 --- a/src/style.css +++ b/src/style.css @@ -3,6 +3,10 @@ display: none; } +.hidden { + display: none; +} + .fav--active { background: green; } From 8cf774ba7109a901e3c1b79c4d77e25e2b608251 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 17:29:47 +0100 Subject: [PATCH 09/30] pagination --- index.html | 9 ++++++++- src/index.js | 51 ++++++++++++++++++++++++++++++++++++++++----------- src/omdb.http | 2 +- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/index.html b/index.html index 50e95b09..3778d46d 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,14 @@

            You’ve saved 0

              -
              +
              + +
              +
              diff --git a/src/index.js b/src/index.js index e696c0cc..3311ed44 100644 --- a/src/index.js +++ b/src/index.js @@ -9,18 +9,20 @@ if (storage.storageAvailable('localStorage')) { console.log('Please enable local storage to save your favourites.'); } -const paramsInit = { - base: 'http://www.omdbapi.com/?apikey=507b4100&type=movie' +const params = { + base: 'http://www.omdbapi.com/?apikey=507b4100&type=movie', + pageNum: 1 }; const setUrl = (paramsInit, query = '', id = '') => { - return `${paramsInit.base}&s=${query}&i=${id}`; + // console.log(`${paramsInit.base}&page=${params.pageNum}&s=${query}&i=${id}`); + return `${paramsInit.base}&page=${params.pageNum}&s=${query}&i=${id}`; }; const searchFilmBytitle = title => { - fetch(setUrl(paramsInit, title)) + fetch(setUrl(params, title)) .then(response => response.json()) - .then(body => displaySearchResults(body.Search)) + .then(body => displaySearchResults(body)) .catch(error => { if (films === undefined) { alert('No films match your query, please search again'); @@ -31,7 +33,7 @@ const searchFilmBytitle = title => { }; const getFilmByID = id => { - fetch(setUrl(paramsInit, '', id)) + fetch(setUrl(params, '', id)) .then(response => response.json()) .then(body => writeFilmDetails('#film-details', body)) .catch(error => console.log(error)); @@ -40,8 +42,9 @@ const getFilmByID = id => { /* Search resutls */ const displaySearchResults = films => { + console.log(films); const searchResults = createElement('div'); - films.forEach(film => { + films.Search.forEach(film => { const filmListing = createFilmSearchListing( film.imdbID, film.Title, @@ -54,6 +57,7 @@ const displaySearchResults = films => { searchResultsWrapper.innerHTML = ''; addElementToParent(searchResultsWrapper, searchResults); + createPagination(films); }; const createFilmSearchListing = (id, title, year, poster) => { @@ -76,6 +80,34 @@ const createArticle = (articleClass = '') => { return article; }; +const createPagination = data => { + const numPages = Math.ceil(Number(data.totalResults) / 10); + document.querySelector('.page-total').textContent = numPages; +}; + +const nextPage = document.querySelector('#page-nav .next'); +console.log(nextPage); +nextPage.addEventListener('click', e => { + const currentPageNum = document.querySelector('.page-current'); + const totalPageNum = document.querySelector('.page-total'); + e.preventDefault(); + +currentPageNum.textContent < +totalPageNum.textContent // Prevent next page advancing beyond total no. of pages + ? params.pageNum++ + : false; + + searchFilmBytitle(params.query); + currentPageNum.textContent = params.pageNum; +}); + +const prevPage = document.querySelector('#page-nav .prev'); +prevPage.addEventListener('click', e => { + e.preventDefault(); + params.pageNum > 1 ? params.pageNum-- : false; // Prevent previous page returning negative page number + + searchFilmBytitle(params.query); + document.querySelector('.page-current').textContent = params.pageNum; +}); + /* film details */ const createFilmDetails = film => { @@ -173,6 +205,7 @@ const getFavourites = data => { document.querySelector('#search').addEventListener('submit', e => { e.preventDefault(); const query = e.currentTarget.query.value; + params.query = query; searchFilmBytitle(query); }); @@ -198,10 +231,6 @@ document.querySelector('#favourites').addEventListener('click', e => { } }); -/* Delete all favourites */ - -/* Delete individual favourite */ - /* utility functions */ const createElement = (type, title = '') => { diff --git a/src/omdb.http b/src/omdb.http index 5f7f2f15..edef38c9 100644 --- a/src/omdb.http +++ b/src/omdb.http @@ -1 +1 @@ -http://www.omdbapi.com/?apikey=507b4100&s=&i=tt1640571 \ No newline at end of file +http://www.omdbapi.com/?apikey=507b4100&s=&s=titanic \ No newline at end of file From b28d6a5f4b459e8baef89ab3b4dbfed084f6833c Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sat, 22 Sep 2018 19:33:17 +0100 Subject: [PATCH 10/30] hide favourites when deleted and set isFav: false in local storage --- README.md | 12 ++++++------ src/index.js | 36 +++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 9b65b7d5..5a6729ad 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ - [ ] **Work using mobile first, that is create the mobile version first and add tablet and desktop versions after.** - A mobile-first responsive design responsive that looks great at different screen widths -- [ ] ~~Create an HTML page which should have a `form` at the top which contains a text input and a submit button. Below it should have a placeholder element for the returned results.~~ + ### Movie details @@ -29,11 +29,11 @@ ## TODO -- [ ] **Filter fetch results to show only movies** + - [ ] **Implement any feature you would find useful or interesting** -- [ ] **Implement pagination so that users can navigate between all movies in search results rather than just the first ten** + - [ ] **Include a screenshot of your app in the README.** @@ -43,11 +43,11 @@ ### stretch goal - favourites -- [ ] Create a favourites list. It's up to you how you would add items to favourites. You could add a button or otherwise. Display a list of favourites somewhere on your page. + - [ ] Make the favourites list sortable. Add `up` and `down` buttons to your favourites which on click will move the result in relevant direction. -- [ ] Save favourites locally using `localStorage` so that favourites persist in browser after refresh. + --- diff --git a/src/index.js b/src/index.js index 3311ed44..fbb69f4c 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ const myStorage = window.localStorage; if (storage.storageAvailable('localStorage')) { // localStorage.clear(); console.log(`You’re all set to save your favourite films`); + console.log(myStorage); } else { console.log('Please enable local storage to save your favourites.'); } @@ -44,6 +45,7 @@ const getFilmByID = id => { const displaySearchResults = films => { console.log(films); const searchResults = createElement('div'); + searchResults.setAttribute('id', `page-${params.pageNum}`); films.Search.forEach(film => { const filmListing = createFilmSearchListing( film.imdbID, @@ -83,10 +85,10 @@ const createArticle = (articleClass = '') => { const createPagination = data => { const numPages = Math.ceil(Number(data.totalResults) / 10); document.querySelector('.page-total').textContent = numPages; + // document.querySelector('#page-nav').classList.toggle('hidden'); }; const nextPage = document.querySelector('#page-nav .next'); -console.log(nextPage); nextPage.addEventListener('click', e => { const currentPageNum = document.querySelector('.page-current'); const totalPageNum = document.querySelector('.page-total'); @@ -108,6 +110,11 @@ prevPage.addEventListener('click', e => { document.querySelector('.page-current').textContent = params.pageNum; }); +/* infinite scroll */ +const infiniteScroll = () => { + const trigger = document.querySelector('#'); +}; + /* film details */ const createFilmDetails = film => { @@ -155,12 +162,6 @@ const makeFavourite = id => { return favourite; }; -// const addToFavourites = (id, e) => { -// const favouriteFilm = makeFavourite(id, e); -// const parent = document.querySelector('#fav-list'); -// addElementToParent(parent, favouriteFilm); -// }; - const setFavButton = film => { document.querySelector('#fav').addEventListener('click', e => { // TODO: highlight favourited film when display details @@ -181,7 +182,7 @@ const setFavButton = film => { const id = favData.id; const details = JSON.stringify(favData); - myStorage.setItem(id, `${details}`); + myStorage.setItem(`${myStorage.length}`, `${details}`); // addToFavourites(id, e); getFavourites(myStorage); }); @@ -191,9 +192,12 @@ const getFavourites = data => { const parent = document.querySelector('#favourites__list'); parent.innerHTML = ''; for (let i = 0; i < data.length; i++) { - const film = JSON.parse(data.getItem(data.key(i))); - const favouriteFilm = makeFavourite(film.id); - addElementToParent(parent, favouriteFilm); + // if isFav = true + console.log(data[i]); + if (data[i].includes('"isFav":true')) { + const favouriteFilm = makeFavourite(`${i}`); + parent.insertBefore(favouriteFilm, parent.firstChild); + } } document.querySelector('#favourites__count').textContent = myStorage.length; }; @@ -220,10 +224,16 @@ document.querySelector('#search-results').addEventListener('click', e => { document.querySelector('#favourites').addEventListener('click', e => { if (e.target.innerText === 'Delete') { + console.log(e.target); const id = e.target.parentNode.dataset.id; e.target.parentNode.classList.add('hidden'); - - myStorage.removeItem(id); + console.log(typeof myStorage); + console.log(typeof myStorage[id]); + // const myFilm = JSON.parse(myStorage[id]); + // myFilm.isFav = false; + // console.log(myFilm); + const updatedFav = myStorage[id].replace('isFav":true', 'isFav":false'); + myStorage.setItem(id, updatedFav); document.querySelector('#favourites__count').textContent = myStorage.length; } else if (e.target.innerText === 'Delete all') { myStorage.clear(); From a67b6f6f9c5393b0390a73ea99935c18e7a320be Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sun, 23 Sep 2018 09:37:48 +0100 Subject: [PATCH 11/30] basic form styling --- index.html | 49 ++++--- src/data.json | 93 +++++++++++++ src/index.js | 89 +++++++++++++ src/modern-normalize.css | 273 +++++++++++++++++++++++++++++++++++++++ src/style.css | 73 +++++++++++ 5 files changed, 557 insertions(+), 20 deletions(-) create mode 100644 src/data.json create mode 100644 src/modern-normalize.css diff --git a/index.html b/index.html index 3778d46d..8bf6f57a 100644 --- a/index.html +++ b/index.html @@ -6,31 +6,40 @@ Document + - -
              -
              -

              You’ve saved 0 favourite films

              -
                -
                -
                -
                +
                +
                +

                The Reel Thing

                + +
                + +
                +
                +

                You’ve saved 0 favourite films

                +
                  +
                  +
                  + -
                  - -
                  +
                  + +
                  + +
                  + diff --git a/src/data.json b/src/data.json new file mode 100644 index 00000000..1cd2fc36 --- /dev/null +++ b/src/data.json @@ -0,0 +1,93 @@ +HTTP/1.1 200 OK +Date: Sun, 23 Sep 2018 07:24:17 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: keep-alive +Cache-Control: public, max-age=86400 +Expires: Mon, 24 Sep 2018 07:24:17 GMT +Last-Modified: Sat, 22 Sep 2018 15:18:36 GMT +Vary: *, Accept-Encoding +X-AspNet-Version: 4.0.30319 +X-Powered-By: ASP.NET +Access-Control-Allow-Origin: * +CF-Cache-Status: HIT +Server: cloudflare +CF-RAY: 45eb4552917f0a7e-LHR +Content-Encoding: gzip + +{ + "Search": [ + { + "Title": "Titanic", + "Year": "1997", + "imdbID": "tt0120338", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMDdmZGU3NDQtY2E5My00ZTliLWIzOTUtMTY4ZGI1YjdiNjk3XkEyXkFqcGdeQXVyNTA4NzY1MzY@._V1_SX300.jpg" + }, + { + "Title": "Titanic II", + "Year": "2010", + "imdbID": "tt1640571", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMTMxMjQ1MjA5Ml5BMl5BanBnXkFtZTcwNjIzNjg1Mw@@._V1_SX300.jpg" + }, + { + "Title": "Titanic: The Legend Goes On...", + "Year": "2000", + "imdbID": "tt0330994", + "Type": "movie", + "Poster": "https://ia.media-imdb.com/images/M/MV5BMTg5MjcxODAwMV5BMl5BanBnXkFtZTcwMTk4OTMwMg@@._V1_SX300.jpg" + }, + { + "Title": "Titanic", + "Year": "1953", + "imdbID": "tt0046435", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMTU3NTUyMTc3Nl5BMl5BanBnXkFtZTgwOTA2MDE3MTE@._V1_SX300.jpg" + }, + { + "Title": "Titanic", + "Year": "1996", + "imdbID": "tt0115392", + "Type": "series", + "Poster": "https://m.media-amazon.com/images/M/MV5BMTIyNjc0NjgyMl5BMl5BanBnXkFtZTcwMDAzMTAzMQ@@._V1_SX300.jpg" + }, + { + "Title": "Raise the Titanic", + "Year": "1980", + "imdbID": "tt0081400", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BM2MyZWYzOTQtMTYzNC00OWIyLWE2NWItMzMwODA0OGQ2ZTRkXkEyXkFqcGdeQXVyMjI4MjA5MzA@._V1_SX300.jpg" + }, + { + "Title": "The Legend of the Titanic", + "Year": "1999", + "imdbID": "tt1623780", + "Type": "movie", + "Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMjMxNDU5MTk1MV5BMl5BanBnXkFtZTgwMDk5NDUyMTE@._V1_SX300.jpg" + }, + { + "Title": "Titanic", + "Year": "2012–", + "imdbID": "tt1869152", + "Type": "series", + "Poster": "https://m.media-amazon.com/images/M/MV5BMTcxNzYxOTAwMF5BMl5BanBnXkFtZTcwNzU3Mjc2Nw@@._V1_SX300.jpg" + }, + { + "Title": "Titanic: Blood and Steel", + "Year": "2012–", + "imdbID": "tt1695366", + "Type": "series", + "Poster": "https://m.media-amazon.com/images/M/MV5BMjI2MzU2NzEzN15BMl5BanBnXkFtZTcwMzI5NTU3Nw@@._V1_SX300.jpg" + }, + { + "Title": "In Search of the Titanic", + "Year": "2004", + "imdbID": "tt1719665", + "Type": "movie", + "Poster": "https://ia.media-imdb.com/images/M/MV5BMTAzNjY0NDA2NzdeQTJeQWpwZ15BbWU4MDIwMzc1MzEx._V1_SX300.jpg" + } + ], + "totalResults": "190", + "Response": "True" +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index fbb69f4c..468df774 100644 --- a/src/index.js +++ b/src/index.js @@ -263,3 +263,92 @@ const addElementToParent = (parent, element) => { /* init */ getFavourites(myStorage); + +const mockResults = { + Search: [ + { + Title: 'Titanic', + Year: '1997', + imdbID: 'tt0120338', + Type: 'movie', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMDdmZGU3NDQtY2E5My00ZTliLWIzOTUtMTY4ZGI1YjdiNjk3XkEyXkFqcGdeQXVyNTA4NzY1MzY@._V1_SX300.jpg' + }, + { + Title: 'Titanic II', + Year: '2010', + imdbID: 'tt1640571', + Type: 'movie', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMTMxMjQ1MjA5Ml5BMl5BanBnXkFtZTcwNjIzNjg1Mw@@._V1_SX300.jpg' + }, + { + Title: 'Titanic: The Legend Goes On...', + Year: '2000', + imdbID: 'tt0330994', + Type: 'movie', + Poster: + 'https://ia.media-imdb.com/images/M/MV5BMTg5MjcxODAwMV5BMl5BanBnXkFtZTcwMTk4OTMwMg@@._V1_SX300.jpg' + }, + { + Title: 'Titanic', + Year: '1953', + imdbID: 'tt0046435', + Type: 'movie', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMTU3NTUyMTc3Nl5BMl5BanBnXkFtZTgwOTA2MDE3MTE@._V1_SX300.jpg' + }, + { + Title: 'Titanic', + Year: '1996', + imdbID: 'tt0115392', + Type: 'series', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMTIyNjc0NjgyMl5BMl5BanBnXkFtZTcwMDAzMTAzMQ@@._V1_SX300.jpg' + }, + { + Title: 'Raise the Titanic', + Year: '1980', + imdbID: 'tt0081400', + Type: 'movie', + Poster: + 'https://m.media-amazon.com/images/M/MV5BM2MyZWYzOTQtMTYzNC00OWIyLWE2NWItMzMwODA0OGQ2ZTRkXkEyXkFqcGdeQXVyMjI4MjA5MzA@._V1_SX300.jpg' + }, + { + Title: 'The Legend of the Titanic', + Year: '1999', + imdbID: 'tt1623780', + Type: 'movie', + Poster: + 'https://images-na.ssl-images-amazon.com/images/M/MV5BMjMxNDU5MTk1MV5BMl5BanBnXkFtZTgwMDk5NDUyMTE@._V1_SX300.jpg' + }, + { + Title: 'Titanic', + Year: '2012–', + imdbID: 'tt1869152', + Type: 'series', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMTcxNzYxOTAwMF5BMl5BanBnXkFtZTcwNzU3Mjc2Nw@@._V1_SX300.jpg' + }, + { + Title: 'Titanic: Blood and Steel', + Year: '2012–', + imdbID: 'tt1695366', + Type: 'series', + Poster: + 'https://m.media-amazon.com/images/M/MV5BMjI2MzU2NzEzN15BMl5BanBnXkFtZTcwMzI5NTU3Nw@@._V1_SX300.jpg' + }, + { + Title: 'In Search of the Titanic', + Year: '2004', + imdbID: 'tt1719665', + Type: 'movie', + Poster: + 'https://ia.media-imdb.com/images/M/MV5BMTAzNjY0NDA2NzdeQTJeQWpwZ15BbWU4MDIwMzc1MzEx._V1_SX300.jpg' + } + ], + totalResults: '190', + Response: 'True' +}; + +// searchFilmBytitle(mockResults); diff --git a/src/modern-normalize.css b/src/modern-normalize.css new file mode 100644 index 00000000..3f645c85 --- /dev/null +++ b/src/modern-normalize.css @@ -0,0 +1,273 @@ +/*! modern-normalize | MIT License | https://github.com/sindresorhus/modern-normalize */ + +/* Document + ========================================================================== */ + +/** + * Use a better box model (opinionated). + */ + +html { + box-sizing: border-box; +} + +*, +*::before, +*::after { + box-sizing: inherit; +} + +/** + * Use a more readable tab size (opinionated). + */ + +:root { + -moz-tab-size: 4; + tab-size: 4; +} + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) + */ + +body { + font-family: + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol'; +} + +/* Grouping content + ========================================================================== */ + +/** + * Add the correct height in Firefox. + */ + +hr { + height: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Add the correct text decoration in Chrome, Edge, and Safari. + */ + +abbr[title] { + text-decoration: underline dotted; +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp, +pre { + font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Remove the inheritance of text transform in Edge and Firefox. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type='button']::-moz-focus-inner, +[type='reset']::-moz-focus-inner, +[type='submit']::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type='button']:-moz-focusring, +[type='reset']:-moz-focusring, +[type='submit']:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers. + */ + +legend { + padding: 0; +} + +/** + * Add the correct vertical alignment in Chrome and Firefox. + */ + +progress { + vertical-align: baseline; +} + +/** + * Correct the cursor style of increment and decrement buttons in Safari. + */ + +[type='number']::-webkit-inner-spin-button, +[type='number']::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Chrome and Safari. + */ + +summary { + display: list-item; +} diff --git a/src/style.css b/src/style.css index 37257eff..72730610 100644 --- a/src/style.css +++ b/src/style.css @@ -10,3 +10,76 @@ .fav--active { background: green; } + +div#app{ + position: relative; +} + +/* header */ + +header{ + background: black; + color:red; + display: flex; + height: 4rem; + justify-content: space-between; + padding-left: 1rem; +} + +#title{ + font-size: 1.5rem; +} + +/* account */ +#account{ + background: skyblue; + position: fixed; + top: 4rem; + left: -100vw; + width: 100vw; +} + +/* search form */ + +#search{ + align-items: center; + background: orangered; + display: flex; + flex-direction: column; + height: 100vh; +} + +.search__label{ + margin: 5rem 0 2rem 0; + font-size: 1.5rem; +} + +.search__input { + background: orangered; + border-width: 0 0 1px 0; + height: 3rem; + margin-bottom: 1.5rem; + padding-left: 1rem; + width: 80vw; + color: whitesmoke; +} + +.search__btn { + color: white; + display: block; + font-size: 1.5rem; + font-weight: 400; + height: 5rem; + width: 5rem; +/* background-image: linear-gradient(to bottom, rgba(0,0, 255,0.5), rgba(0,0,255,0.7) 80%); */ + background: skyblue; + border-radius: 2.5rem; + border: none; + box-shadow: 0px 2px 5px rgba(0,0,0,0.2); + text-shadow: 0 1px rgba(0,0,0,1); +} +/* search results */ + +#search-results{ + height: 100vh; +} \ No newline at end of file From c824db7ab5e8f9d21584ab0b74a3481e1bb92772 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sun, 23 Sep 2018 09:45:39 +0100 Subject: [PATCH 12/30] refactor Search results items using template strings --- src/index.js | 8 ++----- src/style.css | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 468df774..f0f52814 100644 --- a/src/index.js +++ b/src/index.js @@ -64,12 +64,8 @@ const displaySearchResults = films => { const createFilmSearchListing = (id, title, year, poster) => { const filmListing = createArticle('film'); - const filmTitle = createElement('h2', title); - const releaseYear = createElement('p', year); - const filmPoster = createImageElement(poster); - addElementToParent(filmListing, filmTitle); - addElementToParent(filmListing, releaseYear); - addElementToParent(filmListing, filmPoster); + filmListing.innerHTML = ` +

                  ${title}

                  ${year}

                  `; filmListing.setAttribute('data-ID', id); return filmListing; diff --git a/src/style.css b/src/style.css index 72730610..9031894b 100644 --- a/src/style.css +++ b/src/style.css @@ -82,4 +82,61 @@ header{ #search-results{ height: 100vh; -} \ No newline at end of file +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5922af48b7939cee6a248c5d17f3e38d47b722c6 Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sun, 23 Sep 2018 10:26:20 +0100 Subject: [PATCH 13/30] basic search results styling --- index.html | 4 +++- src/index.js | 6 ++++-- src/style.css | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 8bf6f57a..25925eaf 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,8 @@ Document + @@ -27,7 +29,7 @@

                  You’ve saved 0
                  diff --git a/src/index.js b/src/index.js index f0f52814..cdf1e2e6 100644 --- a/src/index.js +++ b/src/index.js @@ -45,6 +45,7 @@ const getFilmByID = id => { const displaySearchResults = films => { console.log(films); const searchResults = createElement('div'); + searchResults.classList.add('search-results__page'); searchResults.setAttribute('id', `page-${params.pageNum}`); films.Search.forEach(film => { const filmListing = createFilmSearchListing( @@ -64,8 +65,10 @@ const displaySearchResults = films => { const createFilmSearchListing = (id, title, year, poster) => { const filmListing = createArticle('film'); + // poster === 'N/A' ? (poster = './img/placeholder.jpg') : poster; + poster === 'N/A' ? (poster = 'http://placekitten.com/g/300/460') : poster; filmListing.innerHTML = ` -

                  ${title}

                  ${year}

                  `; +

                  ${title} (${year})

                  `; filmListing.setAttribute('data-ID', id); return filmListing; @@ -81,7 +84,6 @@ const createArticle = (articleClass = '') => { const createPagination = data => { const numPages = Math.ceil(Number(data.totalResults) / 10); document.querySelector('.page-total').textContent = numPages; - // document.querySelector('#page-nav').classList.toggle('hidden'); }; const nextPage = document.querySelector('#page-nav .next'); diff --git a/src/style.css b/src/style.css index 9031894b..e8b092b8 100644 --- a/src/style.css +++ b/src/style.css @@ -15,6 +15,11 @@ div#app{ position: relative; } +button { + background: none; + border: none; +} + /* header */ header{ @@ -24,6 +29,8 @@ header{ height: 4rem; justify-content: space-between; padding-left: 1rem; + position: fixed; + width: 100vw; } #title{ @@ -50,7 +57,7 @@ header{ } .search__label{ - margin: 5rem 0 2rem 0; + margin: 40vw 0 2rem 0; font-size: 1.5rem; } @@ -67,7 +74,7 @@ header{ .search__btn { color: white; display: block; - font-size: 1.5rem; + font-size: 2rem; font-weight: 400; height: 5rem; width: 5rem; @@ -76,18 +83,52 @@ header{ border-radius: 2.5rem; border: none; box-shadow: 0px 2px 5px rgba(0,0,0,0.2); - text-shadow: 0 1px rgba(0,0,0,1); + text-shadow: 0 3px rgba(0,0,0,0.3); } /* search results */ #search-results{ - height: 100vh; +/* height: 100vh; */ } +.search-results__page { + display: flex; + height: 80vh; + overflow-y: scroll; +} +.film { + display: flex; + flex-direction: column; + margin-right: 1rem; + padding: 1rem; + width: 70vw; +} + +.film__title{ + font-size: 1rem; + order: 2; +} + +.film__poster { + order: 1; + object-fit: scale-down; + width: 60vw; +} +.film__year { + font-weight: 400; + order: 3; +} +#page-nav{ + display: flex; + justify-content: space-around; +} +.next{ + border:none; +} From 6da274688d5649621e5727370ca0468050a358eb Mon Sep 17 00:00:00 2001 From: Joe Lamb Date: Sun, 23 Sep 2018 11:19:04 +0100 Subject: [PATCH 14/30] search results refined and placeholder for missing image --- index.html | 8 ++----- src/index.js | 63 +++++++++++++++++++++++++++++++++------------------ src/style.css | 14 ++++++++---- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/index.html b/index.html index 25925eaf..43efa99e 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@

                  The Reel Thing

                  - +
                  @@ -35,11 +35,7 @@

                  You’ve saved 0
                  - +

                  diff --git a/src/index.js b/src/index.js index cdf1e2e6..3e4bf188 100644 --- a/src/index.js +++ b/src/index.js @@ -60,13 +60,19 @@ const displaySearchResults = films => { searchResultsWrapper.innerHTML = ''; addElementToParent(searchResultsWrapper, searchResults); - createPagination(films); + const paginationButtons = createPagination(films); + console.log(paginationButtons); + addElementToParent(searchResultsWrapper, paginationButtons); + addPaginationControls(); }; const createFilmSearchListing = (id, title, year, poster) => { const filmListing = createArticle('film'); // poster === 'N/A' ? (poster = './img/placeholder.jpg') : poster; - poster === 'N/A' ? (poster = 'http://placekitten.com/g/300/460') : poster; + poster === 'N/A' + ? (poster = + 'https://dummyimage.com/300x400/8a8a8a/ffd900.jpg&text=Sorry,+no+poster+available') + : poster; filmListing.innerHTML = `

                  ${title} (${year})

                  `; filmListing.setAttribute('data-ID', id); @@ -82,31 +88,44 @@ const createArticle = (articleClass = '') => { }; const createPagination = data => { + const pagination = createElement('nav'); const numPages = Math.ceil(Number(data.totalResults) / 10); - document.querySelector('.page-total').textContent = numPages; + // document.querySelector('.page-total').textContent = numPages; + pagination.innerHTML = `