From cf560daabd5d87cf83510d1a4f69c000349eb876 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Fri, 14 Sep 2018 10:58:27 +0100 Subject: [PATCH 01/13] initial commit - template layout complete, displays all required info --- index.html | 23 ++++++++++++++++++ src/scripts.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++ styles/styles.css | 27 +++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 index.html create mode 100644 src/scripts.js create mode 100644 styles/styles.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..1b3e168 --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + + + + Resonsive News Reader + + + +
+

Responsive news reader

+ +
+
+ +
+ + + + + diff --git a/src/scripts.js b/src/scripts.js new file mode 100644 index 0000000..ec7007c --- /dev/null +++ b/src/scripts.js @@ -0,0 +1,60 @@ +// News API key: 9ed005ef4eb94baf913fce701c69972f + +const apiRequests = { + usTop20: 'https://newsapi.org/v2/top-headlines?country=us&apiKey=9ed005ef4eb94baf913fce701c69972f', + + ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', +} + +function createStoryPanel(article){ + const contentElement = document.querySelector(".content") + const storyDivElement = document.createElement("div") + storyDivElement.className = "story-div-element" + + const headlineElement = document.createElement("h4") + headlineElement.className = "headline" + headlineElement.textContent = article.title + + const publicationNameElement = document.createElement("h6") + publicationNameElement.textContent = article.source.name + + const publicationDateElement = document.createElement("h6") + publicationDateElement.textContent = article.publishedAt + + const storyImageElement = document.createElement("img") + storyImageElement.setAttribute("src", article.urlToImage) + storyImageElement.className = "story-image" + + const descriptionElement = document.createElement("p") + descriptionElement.textContent = article.description + + const linkElement = document.createElement("a") + linkElement.setAttribute("href", article.url) + linkElement.textContent = "See full story" + + storyDivElement.appendChild(headlineElement) + storyDivElement.appendChild(publicationNameElement) + storyDivElement.appendChild(publicationDateElement) + storyDivElement.appendChild(storyImageElement) + storyDivElement.appendChild(descriptionElement) + storyDivElement.appendChild(linkElement) + contentElement.appendChild(storyDivElement) + + +} + + +function fetchNews(apiAddress){ + fetch(apiAddress) + .then(response => { + return response.json() + }) + .then(body => { + body.articles.forEach(article => { + createStoryPanel(article) + }) + }) +} + + +fetchNews(apiRequests.usTop20) diff --git a/styles/styles.css b/styles/styles.css new file mode 100644 index 0000000..e0770c8 --- /dev/null +++ b/styles/styles.css @@ -0,0 +1,27 @@ +body { + margin: 0; + display: flex; + flex-direction: column; + height: 100vh; +} + +header{ + background-color: blue; + height: 100px; +} + + +.content{ + background-color: grey; + height: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; +} + + +.story-image{ + display: none; +} From e960600e8188aab5d7e27d68a4a4f11b4efdb195 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Fri, 14 Sep 2018 11:59:41 +0100 Subject: [PATCH 02/13] Added country change functionality, from Us-uk --- index.html | 4 ++-- src/scripts.js | 27 +++++++++++++++++++++++++-- styles/styles.css | 8 ++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 1b3e168..c908559 100644 --- a/index.html +++ b/index.html @@ -5,13 +5,13 @@ - Resonsive News Reader + Responsive News Reader

Responsive news reader

- +
diff --git a/src/scripts.js b/src/scripts.js index ec7007c..7bbf60b 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -6,8 +6,26 @@ const apiRequests = { ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', } +const pageHandlers = { + changeCountry: function(){ + console.log("test") + const countryButtonElement = document.querySelector(".country-button") + countryButtonElement.addEventListener("click", event => { + contentElement.innerHTML = "" + countryButtonElement.textContent === "UK" + ? ( countryButtonElement.textContent = "US", + fetchNews(apiRequests.ukTop20)) + : (countryButtonElement.textContent = "UK", + fetchNews(apiRequests.usTop20)) + }) + } + +} + + + + function createStoryPanel(article){ - const contentElement = document.querySelector(".content") const storyDivElement = document.createElement("div") storyDivElement.className = "story-div-element" @@ -39,9 +57,11 @@ function createStoryPanel(article){ storyDivElement.appendChild(descriptionElement) storyDivElement.appendChild(linkElement) contentElement.appendChild(storyDivElement) +} + + -} function fetchNews(apiAddress){ @@ -57,4 +77,7 @@ function fetchNews(apiAddress){ } +const contentElement = document.querySelector(".content") + fetchNews(apiRequests.usTop20) +pageHandlers.changeCountry() diff --git a/styles/styles.css b/styles/styles.css index e0770c8..b387290 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -22,6 +22,14 @@ header{ } + +.story-div-element{ + background-color: white; + margin: 1em; + border: black 1px solid; + padding: 0.5em; +} + .story-image{ display: none; } From 00e43ff9877621b90b6a22099fafce240205d83f Mon Sep 17 00:00:00 2001 From: DanGRT Date: Fri, 14 Sep 2018 13:04:06 +0100 Subject: [PATCH 03/13] added basic search functionality --- index.html | 4 ++++ src/scripts.js | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index c908559..8fb639b 100644 --- a/index.html +++ b/index.html @@ -12,6 +12,10 @@

Responsive news reader

+
+ + +
diff --git a/src/scripts.js b/src/scripts.js index 7bbf60b..086b879 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -4,6 +4,11 @@ const apiRequests = { usTop20: 'https://newsapi.org/v2/top-headlines?country=us&apiKey=9ed005ef4eb94baf913fce701c69972f', ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', + + searchURL: function(userString){ + return `https://newsapi.org/v2/everything?q=${userString}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + + } } const pageHandlers = { @@ -18,7 +23,21 @@ const pageHandlers = { : (countryButtonElement.textContent = "UK", fetchNews(apiRequests.usTop20)) }) - } + }, + + search: function(){ + const searchFormElement = document.querySelector(".search-form") + const searchTextElement = document.querySelector(".search-text") + searchFormElement.addEventListener("submit", event => { + event.preventDefault(); + const searchString = apiRequests.searchURL(searchTextElement.value) + contentElement.innerHTML = "" + fetchNews(searchString) + + }) + } + + } @@ -81,3 +100,4 @@ const contentElement = document.querySelector(".content") fetchNews(apiRequests.usTop20) pageHandlers.changeCountry() +pageHandlers.search() From ff9f1a528c40be0aea4101e4aeeb476f6e9bb719 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Fri, 14 Sep 2018 15:28:34 +0100 Subject: [PATCH 04/13] Added basic search functionality, with daterange --- index.html | 10 +++++++++- src/scripts.js | 34 ++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 8fb639b..9cb81b8 100644 --- a/index.html +++ b/index.html @@ -11,11 +11,19 @@

Responsive news reader

- + +
+
+
diff --git a/src/scripts.js b/src/scripts.js index 086b879..b0ee822 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -5,9 +5,12 @@ const apiRequests = { ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', - searchURL: function(userString){ - return `https://newsapi.org/v2/everything?q=${userString}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` - + searchURL: function(userString, daterange){ + if (daterange === null){ + return `https://newsapi.org/v2/everything?q=${userString}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + }else{ + return `https://newsapi.org/v2/everything?q=${userString}${daterange}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + } } } @@ -17,10 +20,10 @@ const pageHandlers = { const countryButtonElement = document.querySelector(".country-button") countryButtonElement.addEventListener("click", event => { contentElement.innerHTML = "" - countryButtonElement.textContent === "UK" - ? ( countryButtonElement.textContent = "US", + countryButtonElement.textContent === "Top UK Stories" + ? ( countryButtonElement.textContent = "Top US Stories", fetchNews(apiRequests.ukTop20)) - : (countryButtonElement.textContent = "UK", + : (countryButtonElement.textContent = "Top UK Stories", fetchNews(apiRequests.usTop20)) }) }, @@ -28,10 +31,15 @@ const pageHandlers = { search: function(){ const searchFormElement = document.querySelector(".search-form") const searchTextElement = document.querySelector(".search-text") + const dateRangeElement = document.querySelector(".date-range") searchFormElement.addEventListener("submit", event => { event.preventDefault(); - const searchString = apiRequests.searchURL(searchTextElement.value) + console.log(dateRangeElement.value) + const dateRange = formatDate(dateRangeElement.value) + console.log(dateRange) + const searchString = apiRequests.searchURL(searchTextElement.value, dateRange) contentElement.innerHTML = "" + searchTextElement.value = "" fetchNews(searchString) }) @@ -79,7 +87,17 @@ function createStoryPanel(article){ } - +function formatDate(monthsAgo){ + if ( monthsAgo != "all-time") { + const newDate = new Date + newDate.setMonth(newDate.getMonth() - monthsAgo); + const isoDate = newDate.toISOString().slice(0,10) + console.log(isoDate) + return `&from=${isoDate}` + }else{ + return null + } +} From 01728a53020859b2ae91b9f0ad1639947ae26023 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Fri, 14 Sep 2018 16:30:46 +0100 Subject: [PATCH 05/13] slightly neatened up styling, story panels now equal width --- index.html | 4 ++++ src/scripts.js | 3 --- styles/styles.css | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 9cb81b8..0287e10 100644 --- a/index.html +++ b/index.html @@ -27,6 +27,10 @@

Responsive news reader

+
diff --git a/src/scripts.js b/src/scripts.js index b0ee822..88ac513 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -34,9 +34,7 @@ const pageHandlers = { const dateRangeElement = document.querySelector(".date-range") searchFormElement.addEventListener("submit", event => { event.preventDefault(); - console.log(dateRangeElement.value) const dateRange = formatDate(dateRangeElement.value) - console.log(dateRange) const searchString = apiRequests.searchURL(searchTextElement.value, dateRange) contentElement.innerHTML = "" searchTextElement.value = "" @@ -92,7 +90,6 @@ function formatDate(monthsAgo){ const newDate = new Date newDate.setMonth(newDate.getMonth() - monthsAgo); const isoDate = newDate.toISOString().slice(0,10) - console.log(isoDate) return `&from=${isoDate}` }else{ return null diff --git a/styles/styles.css b/styles/styles.css index b387290..b95b4b5 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -7,7 +7,8 @@ body { header{ background-color: blue; - height: 100px; + height: 140px; + } @@ -28,6 +29,7 @@ header{ margin: 1em; border: black 1px solid; padding: 0.5em; + min-width: 90vw; } .story-image{ From e77414cf8a4da8db29b1b1ab40f075591e8e1836 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sat, 15 Sep 2018 15:53:04 +0100 Subject: [PATCH 06/13] Added pagination function for searches only --- index.html | 10 +++-- src/scripts.js | 107 ++++++++++++++++++++++++++++++++++++---------- styles/styles.css | 29 ++++++++++++- 3 files changed, 120 insertions(+), 26 deletions(-) diff --git a/index.html b/index.html index 0287e10..c71ab31 100644 --- a/index.html +++ b/index.html @@ -26,11 +26,15 @@

Responsive news reader

+
- -
+ +
diff --git a/src/scripts.js b/src/scripts.js index 88ac513..845e77e 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -1,32 +1,54 @@ // News API key: 9ed005ef4eb94baf913fce701c69972f +//TODO: pagination, stylization, excludeDomains/blocklist + +//Object contains possible URLS for fetch requests const apiRequests = { usTop20: 'https://newsapi.org/v2/top-headlines?country=us&apiKey=9ed005ef4eb94baf913fce701c69972f', ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', - searchURL: function(userString, daterange){ + displayTop20: true, + +//function takes search string, and if specified a date range + searchURL: function(userString, daterange, page){ + this.displayTop20 = false if (daterange === null){ - return `https://newsapi.org/v2/everything?q=${userString}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + this.currentSearchURL = `https://newsapi.org/v2/everything?q=${userString}&page=1&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + return this.currentSearchURL }else{ - return `https://newsapi.org/v2/everything?q=${userString}${daterange}&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + this.currentSearchURL = `https://newsapi.org/v2/everything?q=${userString}${daterange}&page=1&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` + return this.currentSearchURL } - } + }, + + pageChange: function(inputPage){ + const currentURL = this.currentSearchURL + const pageRegex = /page=(\d)/ + this.currentPage = inputPage + return currentURL.replace(pageRegex, `page=${inputPage}`) + }, + + currentSearchURL: null, + + currentPage: 1 } + +//Object contains functions attached to buttons and page features const pageHandlers = { changeCountry: function(){ - console.log("test") - const countryButtonElement = document.querySelector(".country-button") - countryButtonElement.addEventListener("click", event => { - contentElement.innerHTML = "" - countryButtonElement.textContent === "Top UK Stories" - ? ( countryButtonElement.textContent = "Top US Stories", - fetchNews(apiRequests.ukTop20)) - : (countryButtonElement.textContent = "Top UK Stories", - fetchNews(apiRequests.usTop20)) - }) - }, + const countryButtonElement = document.querySelector(".country-button") + countryButtonElement.addEventListener("click", event => { + paginationElement.style.display = "none"; + newsDisplayElement.innerHTML = "" + countryButtonElement.textContent === "Top UK Stories" + ? ( countryButtonElement.textContent = "Top US Stories", + fetchNews(apiRequests.ukTop20)) + : (countryButtonElement.textContent = "Top UK Stories", + fetchNews(apiRequests.usTop20)) + }) + }, search: function(){ const searchFormElement = document.querySelector(".search-form") @@ -36,24 +58,59 @@ const pageHandlers = { event.preventDefault(); const dateRange = formatDate(dateRangeElement.value) const searchString = apiRequests.searchURL(searchTextElement.value, dateRange) - contentElement.innerHTML = "" + newsDisplayElement.innerHTML = "" searchTextElement.value = "" + paginationElement.style.display = "inline" fetchNews(searchString) + this.checkPage() }) + }, + + checkPage: function(){ + apiRequests.currentPage === 1 + ? prevPageElement.disabled = true + : prevPageElement.disabled = false + }, + + + paginationControl: function(){ + nextPageElement.addEventListener("click", event => { + let currentPage = apiRequests.currentPage + currentPage ++ + const requestedPage = apiRequests.pageChange(currentPage) + newsDisplayElement.innerHTML = "" + fetchNews(requestedPage) + this.checkPage() + }) + + prevPageElement.addEventListener("click", event => { + let currentPage = apiRequests.currentPage + currentPage -- + const requestedPage = apiRequests.pageChange(currentPage) + newsDisplayElement.innerHTML = "" + fetchNews(requestedPage) + this.checkPage() + }) + } -} +} + +//creates each story panel from fetch response function createStoryPanel(article){ const storyDivElement = document.createElement("div") storyDivElement.className = "story-div-element" + const headerElement = document.createElement("div") + headerElement.className = "story-header" + const headlineElement = document.createElement("h4") headlineElement.className = "headline" headlineElement.textContent = article.title @@ -75,16 +132,18 @@ function createStoryPanel(article){ linkElement.setAttribute("href", article.url) linkElement.textContent = "See full story" - storyDivElement.appendChild(headlineElement) + headerElement.appendChild(headlineElement) + headerElement.appendChild(storyImageElement) + storyDivElement.appendChild(headerElement) storyDivElement.appendChild(publicationNameElement) storyDivElement.appendChild(publicationDateElement) - storyDivElement.appendChild(storyImageElement) + storyDivElement.appendChild(descriptionElement) storyDivElement.appendChild(linkElement) - contentElement.appendChild(storyDivElement) + newsDisplayElement.appendChild(storyDivElement) } - +//formats date for search function formatDate(monthsAgo){ if ( monthsAgo != "all-time") { const newDate = new Date @@ -97,7 +156,6 @@ function formatDate(monthsAgo){ } - function fetchNews(apiAddress){ fetch(apiAddress) .then(response => { @@ -112,7 +170,12 @@ function fetchNews(apiAddress){ const contentElement = document.querySelector(".content") +const newsDisplayElement = document.querySelector(".news-display") +const paginationElement = document.querySelector(".pagination") +const nextPageElement = document.querySelector(".next-page") +const prevPageElement = document.querySelector(".back-page") fetchNews(apiRequests.usTop20) pageHandlers.changeCountry() pageHandlers.search() +pageHandlers.paginationControl() diff --git a/styles/styles.css b/styles/styles.css index b95b4b5..3599fbd 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -15,13 +15,16 @@ header{ .content{ background-color: grey; height: 100%; - height: 100%; display: flex; flex-direction: column; align-items: center; overflow-y: auto; } +.pagination{ + display: none; +} + .story-div-element{ @@ -32,6 +35,30 @@ header{ min-width: 90vw; } +.story-header{ + display: flex; + flex-direction: row; +} + .story-image{ display: none; } + + +/* Medium devices (landscape tablets, 768px and up) */ +@media only screen and (min-width: 768px) { + .story-image{ + display: inline; + width: 40vw; + height: auto; + align-self: center + } + + +} + +/* Large devices (laptops/desktops, 992px and up) */ +@media only screen and (min-width: 992px) { + + +} From 228ad5376e15ec12dc0471fe782f8d75a1e0ceb5 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sat, 15 Sep 2018 19:23:40 +0100 Subject: [PATCH 07/13] added placeholder if image is not found --- src/scripts.js | 43 +++++++++++++++++++++++++++++++++---------- styles/styles.css | 27 +++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 845e77e..0e9c432 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -1,6 +1,6 @@ // News API key: 9ed005ef4eb94baf913fce701c69972f -//TODO: pagination, stylization, excludeDomains/blocklist +//TODO: stylization, excludeDomains/blocklist //Object contains possible URLS for fetch requests const apiRequests = { @@ -8,8 +8,6 @@ const apiRequests = { ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', - displayTop20: true, - //function takes search string, and if specified a date range searchURL: function(userString, daterange, page){ this.displayTop20 = false @@ -56,6 +54,9 @@ const pageHandlers = { const dateRangeElement = document.querySelector(".date-range") searchFormElement.addEventListener("submit", event => { event.preventDefault(); + if (searchTextElement.value === ""){ + return + } const dateRange = formatDate(dateRangeElement.value) const searchString = apiRequests.searchURL(searchTextElement.value, dateRange) newsDisplayElement.innerHTML = "" @@ -111,18 +112,27 @@ function createStoryPanel(article){ const headerElement = document.createElement("div") headerElement.className = "story-header" - const headlineElement = document.createElement("h4") + const headerLeftElement = document.createElement("div") + headerLeftElement.className = "story-header-left" + + const publicationInfoElement = document.createElement("span") + publicationInfoElement.className = "publication-info" + + const headlineElement = document.createElement("h2") headlineElement.className = "headline" headlineElement.textContent = article.title - const publicationNameElement = document.createElement("h6") + const publicationNameElement = document.createElement("h4") publicationNameElement.textContent = article.source.name - const publicationDateElement = document.createElement("h6") - publicationDateElement.textContent = article.publishedAt + const publicationDateElement = document.createElement("h4") + publicationDateElement.textContent = convertDateForDisplay(article.publishedAt) const storyImageElement = document.createElement("img") storyImageElement.setAttribute("src", article.urlToImage) + if (storyImageElement.src === "http://127.0.0.1:3000/null"){ + storyImageElement.setAttribute("src", "../images/No_Image_Available.jpg") + } storyImageElement.className = "story-image" const descriptionElement = document.createElement("p") @@ -132,11 +142,17 @@ function createStoryPanel(article){ linkElement.setAttribute("href", article.url) linkElement.textContent = "See full story" - headerElement.appendChild(headlineElement) + publicationInfoElement.appendChild(publicationNameElement) + publicationInfoElement.appendChild(publicationDateElement) + + headerLeftElement.appendChild(headlineElement) + headerLeftElement.appendChild(publicationInfoElement) + + headerElement.appendChild(headerLeftElement) headerElement.appendChild(storyImageElement) + storyDivElement.appendChild(headerElement) - storyDivElement.appendChild(publicationNameElement) - storyDivElement.appendChild(publicationDateElement) + storyDivElement.appendChild(descriptionElement) storyDivElement.appendChild(linkElement) @@ -155,6 +171,13 @@ function formatDate(monthsAgo){ } } +//formats date for display + +function convertDateForDisplay(date){ + const inputDate = new Date(date) + return inputDate.toLocaleString() +} + function fetchNews(apiAddress){ fetch(apiAddress) diff --git a/styles/styles.css b/styles/styles.css index 3599fbd..a50edf2 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -21,10 +21,24 @@ header{ overflow-y: auto; } +.news-display{ + background-color: grey; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; + +} + .pagination{ display: none; } +.headline{ + margin-right: 1em; + +} .story-div-element{ @@ -32,12 +46,13 @@ header{ margin: 1em; border: black 1px solid; padding: 0.5em; - min-width: 90vw; + width: 90vw; } .story-header{ display: flex; flex-direction: row; + justify-content: space-between; } .story-image{ @@ -45,13 +60,21 @@ header{ } +.publication-info{ + display:flex; + flex-direction: row; + justify-content: space-between; + margin-right: 2em; +} + + /* Medium devices (landscape tablets, 768px and up) */ @media only screen and (min-width: 768px) { .story-image{ display: inline; width: 40vw; height: auto; - align-self: center + align-self: flex-end; } From 3f3150b94d0fdc04585668f9e81593cffe98a6b1 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sun, 16 Sep 2018 14:48:12 +0100 Subject: [PATCH 08/13] functionality in place, commit before attempted refactor --- index.html | 5 ++++- src/scripts.js | 57 +++++++++++++++++++++-------------------------- styles/styles.css | 13 +++++++---- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index c71ab31..8702e16 100644 --- a/index.html +++ b/index.html @@ -5,12 +5,15 @@ + + + Responsive News Reader
-

Responsive news reader

+

Fetch News

diff --git a/src/scripts.js b/src/scripts.js index 0e9c432..85e82f9 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -27,9 +27,14 @@ const apiRequests = { return currentURL.replace(pageRegex, `page=${inputPage}`) }, + currentSearchURL: null, - currentPage: 1 + currentPage: 1, + + blockList: [] + + } @@ -94,7 +99,7 @@ const pageHandlers = { this.checkPage() }) - } + }, @@ -102,45 +107,33 @@ const pageHandlers = { } +function assignElement(elementType, elementClassName, elementTextContent){ + const output = document.createElement(elementType) + output.className = elementClassName + output.textContent = elementTextContent + return output +} //creates each story panel from fetch response function createStoryPanel(article){ - const storyDivElement = document.createElement("div") - storyDivElement.className = "story-div-element" - - const headerElement = document.createElement("div") - headerElement.className = "story-header" - - const headerLeftElement = document.createElement("div") - headerLeftElement.className = "story-header-left" - - const publicationInfoElement = document.createElement("span") - publicationInfoElement.className = "publication-info" - - const headlineElement = document.createElement("h2") - headlineElement.className = "headline" - headlineElement.textContent = article.title - - const publicationNameElement = document.createElement("h4") - publicationNameElement.textContent = article.source.name - - const publicationDateElement = document.createElement("h4") - publicationDateElement.textContent = convertDateForDisplay(article.publishedAt) - - const storyImageElement = document.createElement("img") + const storyDivElement = assignElement("div", "story-div-element") + const headerElement = assignElement("div", "story-header") + const headerLeftElement = assignElement("div", "story-header-left") + const publicationInfoElement = assignElement("span", "publication-info") + const headlineElement = assignElement("h2", "headline", article.title) + const publicationNameElement = assignElement("h4", "publication-name", article.source.name) + const publicationDateElement = assignElement("h4", "publication-date", convertDateForDisplay(article.publishedAt)) + const storyImageElement = assignElement("img", "story-image") storyImageElement.setAttribute("src", article.urlToImage) if (storyImageElement.src === "http://127.0.0.1:3000/null"){ storyImageElement.setAttribute("src", "../images/No_Image_Available.jpg") } - storyImageElement.className = "story-image" - const descriptionElement = document.createElement("p") - descriptionElement.textContent = article.description - - const linkElement = document.createElement("a") + const descriptionElement = assignElement("p", "description-element", article.description) + const linkElement = assignElement("a", "full-story-link", "See full story") linkElement.setAttribute("href", article.url) - linkElement.textContent = "See full story" + publicationInfoElement.appendChild(publicationNameElement) publicationInfoElement.appendChild(publicationDateElement) @@ -151,6 +144,7 @@ function createStoryPanel(article){ headerElement.appendChild(headerLeftElement) headerElement.appendChild(storyImageElement) + storyDivElement.appendChild(headerElement) @@ -185,6 +179,7 @@ function fetchNews(apiAddress){ return response.json() }) .then(body => { + newsDisplayElement.innerHTML = "" body.articles.forEach(article => { createStoryPanel(article) }) diff --git a/styles/styles.css b/styles/styles.css index a50edf2..478c921 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -3,17 +3,20 @@ body { display: flex; flex-direction: column; height: 100vh; + } header{ - background-color: blue; + background-color: #e7eaef; height: 140px; + font-family: 'Source Serif Pro', serif; + border-bottom: 1px black solid } .content{ - background-color: grey; + background: #E9EEF2 url("../images/backdrop.png") repeat-x; height: 100%; display: flex; flex-direction: column; @@ -22,7 +25,8 @@ header{ } .news-display{ - background-color: grey; + background: #E9EEF2 url("../images/backdrop.png") repeat-x; + height: 100%; display: flex; flex-direction: column; @@ -37,12 +41,13 @@ header{ .headline{ margin-right: 1em; + font-family: 'Source Serif Pro', serif; } .story-div-element{ - background-color: white; + background-color: #e7eaef; margin: 1em; border: black 1px solid; padding: 0.5em; From 444bd878a1c45aa644309d2dffb4e94efec17895 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sun, 16 Sep 2018 16:15:12 +0100 Subject: [PATCH 09/13] refactored api request object and methods --- src/scripts.js | 78 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 85e82f9..1fa700b 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -8,32 +8,47 @@ const apiRequests = { ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', -//function takes search string, and if specified a date range - searchURL: function(userString, daterange, page){ - this.displayTop20 = false - if (daterange === null){ - this.currentSearchURL = `https://newsapi.org/v2/everything?q=${userString}&page=1&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` - return this.currentSearchURL - }else{ - this.currentSearchURL = `https://newsapi.org/v2/everything?q=${userString}${daterange}&page=1&sortBy=popularity&apiKey=9ed005ef4eb94baf913fce701c69972f` - return this.currentSearchURL - } + + customParameters : { + searchString: {val: null, + string: null}, + + dateRange: {val: null, + string: null}, + + excludedDomains: {val: null, + string: ""}, + + page: {val: 1, + string: ""} }, - pageChange: function(inputPage){ - const currentURL = this.currentSearchURL - const pageRegex = /page=(\d)/ - this.currentPage = inputPage - return currentURL.replace(pageRegex, `page=${inputPage}`) + getURL: function(){ + const customURL = `https://newsapi.org/v2/everything?q=${this.customParameters.searchString.string}${this.customParameters.dateRange.string}${this.customParameters.excludedDomains.string}${this.customParameters.page.string}&apiKey=9ed005ef4eb94baf913fce701c69972f` + this.currentSearchURL = customURL + return customURL }, + updateSearchURL: function(userString){ + this.customParameters.searchString.string = userString + }, - currentSearchURL: null, + updatePageURL: function(inputPage){ + this.customParameters.page.val = inputPage + this.customParameters.page.string = `&page=${inputPage}` + }, - currentPage: 1, + updateDateURL: function(daterange){ + this.customParameters.dateRange.val + this.customParameters.dateRange.string = `&from=${daterange}` + }, - blockList: [] + updateBlockURL: function(){ + const blockedString = this.blockList.join(",") + this.customParameters.excludedDomains.string = `&excludeDomains=${blockedString}` + }, + blockList: [] } @@ -63,18 +78,20 @@ const pageHandlers = { return } const dateRange = formatDate(dateRangeElement.value) - const searchString = apiRequests.searchURL(searchTextElement.value, dateRange) newsDisplayElement.innerHTML = "" - searchTextElement.value = "" paginationElement.style.display = "inline" + apiRequests.updateSearchURL(searchTextElement.value) + apiRequests.updateDateURL(dateRange) + const searchString = apiRequests.getURL() fetchNews(searchString) + searchTextElement.value = "" this.checkPage() }) }, checkPage: function(){ - apiRequests.currentPage === 1 + apiRequests.customParameters.page.val === 1 ? prevPageElement.disabled = true : prevPageElement.disabled = false }, @@ -82,28 +99,27 @@ const pageHandlers = { paginationControl: function(){ nextPageElement.addEventListener("click", event => { - let currentPage = apiRequests.currentPage + let currentPage = apiRequests.customParameters.page.val currentPage ++ - const requestedPage = apiRequests.pageChange(currentPage) + apiRequests.updatePageURL(currentPage) + const requestedPage = apiRequests.getURL() newsDisplayElement.innerHTML = "" fetchNews(requestedPage) this.checkPage() }) prevPageElement.addEventListener("click", event => { - let currentPage = apiRequests.currentPage + let currentPage = apiRequests.customParameters.page.val currentPage -- - const requestedPage = apiRequests.pageChange(currentPage) + apiRequests.updatePageURL(currentPage) + const requestedPage = apiRequests.getURL() newsDisplayElement.innerHTML = "" fetchNews(requestedPage) this.checkPage() - }) - - }, - - + }) +} } @@ -159,7 +175,7 @@ function formatDate(monthsAgo){ const newDate = new Date newDate.setMonth(newDate.getMonth() - monthsAgo); const isoDate = newDate.toISOString().slice(0,10) - return `&from=${isoDate}` + return `${isoDate}` }else{ return null } From 3a00ce296c902cf2d1c6b548c86fa0cab4fa1f9c Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sun, 16 Sep 2018 16:43:16 +0100 Subject: [PATCH 10/13] added language choice functionality --- images/No_Image_Available.jpg | Bin 0 -> 10962 bytes images/backdrop.png | Bin 0 -> 370 bytes src/scripts.js | 24 +++++++++++++----------- 3 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 images/No_Image_Available.jpg create mode 100644 images/backdrop.png diff --git a/images/No_Image_Available.jpg b/images/No_Image_Available.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1caf419e5c10a352544f9beb350436413bd441ef GIT binary patch literal 10962 zcmd6MXH=8hy6zVedJP>x3{40<5PFBuix5D%(gH?$06`E%KspMcNR!^1bWjih=}n5D zpeP+d1f(d6%89PM_Ezt@XN)_}k8|IVGT&!DZ<+Ng^W??JBEYH{h;;z~U0p$d4ET?n zYynV|zmwZl00ck?urUCfEQ0MW`T2Rvi-~#qiaI!ZIbuYeygbAL9lXU5qT*tJqDr8* zgOeM^59Ww*#d<1n@3cMUhGCtRxGkg%#SOhRFqg18K{$+Qkdc{Fkeid7Gq;K|OfgVC z(8JpULDe8rD6+_6$$^GylAt6Fwi1=Rh^m7Ol@$}{S+XD*Y>x9F4`(eF2VLv=NIC}Z} zDRC1r{i_Kc-iC(%cKnaM<>B$8T|e2rerU{p()dTVuh~^^j2If@>*bGg!Vu^@e;X6} z?!OQ8gGk6m{u~ZV7!(J0l$Vpg2gcJ+7p254qpm5Vsji`}CXP~<(p1;dl$Ozwl9WTK zAyFCkeccUISm9tQ(8?9C83GZ5|={BN@z$*X#Q=h z>*?#~;OT_<5$}gB_CL0$|JGJs1BY?&^TL^VdAa{R^2V3E{JeZGd3nP$Or>EKSWjoK z0N)>j@>d&C7##Kr##syJ6COhWuqNJvOY z$w)~_$jK=v$jPaG7Z4Z>CWa7`laP>8Q<76s)6x)xmi8y48X}{b3TRZ6npkyF9 zP&XI^1&E*^Fcfss11u4C3nDNG1p3cLLQDdNkP?B&egl72gXn%V1Aq{NL1f^c2pB>{ z41kQG^bB+`MkW$22`L_N`_Nj1B$C;in-29pc;%1;T zR&%&nCxOQC5X17jCe$6nBpJm&6qttYF5>IECwY~lB7%aU1m3rzpC10d{Q=w0 zAz0)26aUWyLBhV0Y=U}tmk%pF4v5e{2}(IMW(Mp%h@v3g7_?<7@12OiKPZZ<1Ni7G z_0FeI2rBi&h^r}ET6Gb>bEF1vyty#F#V?SL0C40(#Ie=)VC6RoH4$q9(3-vVLLr(k z%Zc1hk4OGiPgH~jK-Xkv{pAM$;8Jd`?vom*{cjA@QDabgV|K)5sVV?al=o6T7^kND zjloT^0Hi2ok8hVOj?pw@h@IC<7S-hQ9i=*dqwS$b?3uai(PL%441?3ug*k~Xix{}J zk5Uf7@h?ILff4tt_FSDAGPx+FO57O6O*?@iTpWKD2Y6KHMI#yqeTvzbedlh~)TI}= zqKpe$n!l0=<*FnX^!D}Z0D$4wC$BJx>zYpZgK-LjI=GU0nga5?;O7JumP6tF=YpJ6Sa#AeWkRy@*!s{UU6Kh@UzaI(#e$!yP} z3pz~3#(kVxIe53%C6(`j)6;wlfAbC+HKgZFmoGP0X20cLm`qwf)BiT z-D;thUA*XFs|nTLnE$9SIoaP4RTFs6@q=g}? z(w^L7zZH59Ng=0b`5C(#*7{1 zCwh&>aABwnNxF3{Ip|q^=vsz^rJe!(^{`xZ>!H$Pp{YZ;zw^uxMg2I_4+W;zsyqOAn0Aun(^Eg=O}DW@1^rcbh1+-EFO)>7DTd!M+u|S3xpti+eEk8xI-53)s|<-J z$MTAi;!|H`)uEdo$FYaW6JnN0`LcLrs+VV*C9llZPX(W{(xlP9yR*>tT**j@{)4)T z&4Ybqt5#=+N82_-+W9YB4t;vioMahhwG2t+0}XDv}?{x^;o};NPd?ic6o2&%ph&mnE}(B0D-JQ zlOj8Y4FV?-Zq$J&wF1&LgqYeXn z$(A8kl<&`cBNDMIommQI;G>iuoKc}l;ivxmT~=jM>`nJMny^3$5ic%yKhphGzmic$ z>x*-DN`?9RsjK*;LVsj<`7VA?|6K>Y{o99=xOE`@x@YiA0RO%B>sJ&8D{j_G4TPEI zG~NHKzd|Cep^w>&+T+QVb38BxQd(-`6I>0{@O-CJiXm{r7TDw>%qV`uN`F*8GMnP$2ibY!@*wpHR@}8+s4N^qx&9> zUqdb~617~MSAGu;Gj?O=>1dJxt>z-J9N{coz&Q!G=t~htx^Sk)+ z@_9?o&cK&Ylc1M(E;uFElU-~yq&NW%tKQ59-cnx3ah<4SpIK*gx4QI-Vb7xc#=7m- zTOnKaIEYp>&LM7aF!Bs%#g_2(rh~^ZN6$Y>9MvO)H7fe%Ul-jntbZ%IEZ*j{azm5p z1Yq9zkox>`S?2lSjteBm%1L_THmEDyO}7tU)@e^Cl5GDP3IDv;rUFVCagZW%Ys)^Tz;#$r) zSB=6-(mv{qTxjBR{ffNtbMqkjxp`=7|5U)gDnvviDnvAQ{;K$;3<44GZ-NqJjlEP> zOzfLxm2?^D5>{B{Ayb{tJs&Giy)U*ZKlQ$xGw^fy=?dSTao0X7<37uV;La$e4Sw&m zPIBhz^O|%VTe-G{?HKGb56*s|uX1zszM>nS(7txyQ1Yzgp{8wHPdzGE=Kj{UiW zGxw$tm)sMbp~^YsZzHlpS^Y~jJAp$?eJB&+j={q*g?2R#J!qx>NdI$ztoUkJFuLSk zXQSZetw{EODxn;j12-YOLY=52gGsh*jSl%He-3@p<@g9l96hgc*MSTQtd@PwC*rta z%98(Tbvur%ByVXC^p4(Pc}HK9hbBAr(Q(r;OZK~}By!az6g9#KWVj|Zy})UlTN{(k zJLk~*-CA*di_^C(Oe>*}L?c+!NqJwu+xx13ktr=l!FHyn@{V1=4ZrJeYQ3*JkRN=J zIqh2(gFVipUZY$ze9)e9+!Q(S{G#+Sn}rmo>FLeGR(2*cE?uM1l#1%zGM{w4Nte`^ zqV;+1@6#bDi>DBoZx5ATr={<%k!MEF$tgZAf8{^+aJ4|v3qkUPm_K~L$2M^)1a|_A*lQD?9RAMpP<#hOyqK=xTm>AiWq|eyASD5=FmQdfl zL`cJPUmE%DPdn$yUwf}}?eWh@Mtz$KK#AMFC1tpQd`Ens4Cw?xObtwG-wuVpyM0*P zGDp8>9C%9iV&N2P@d@xkbp#Gj8bTm(bQv^;Z_&7(784bW)UB%H%lt+Q8eWFvbre+r zt$t$ldLcgiHa_jm0-E}ga={I6<3{9*R+1>7^NLZDo4E#V4k>|C)uXIidOgk9)WC=l zgE=Rv-0QB3Rj#kIUQw>UQV;4OyDG2&Z-T7fy^9pcTO~26j5T@x&bL2s%F`v&fZ2H5 zfpTNUdEXO$BV~3H3wY^ra2I+*FU6krWbE=06t1>|n{n!F&#Ui`XnGG>xY}g$HZpQV z=x-rJ4^tQlcj8|@!<|Z)6E5=UtG}NkTj8k3z($tfu5g3qKC-aQCSh+x+do?UShe)| z8SbN@FsguRk&ba5{~}@C%b7EhT?*5Qaa3*s`mq8+DWA;{?q-@Ox7t}b3{QzzW4HRP z*bU$QGsmS-!VjBctTNPi!egar&upJ!&b@?*=j>f=3dRO4#kx)mvg=;(F~hPMkiPB{ zqDq}6V_+QNBl{Aie4nfVp80t+l5UA=d?C{)u&0_r0Bxd4!Rp`pu(%bB_r@E_F5WK- z>1PXQlX<376X?HsU}LaM+t?$IURpB=oS&fZanV&3G+ClUtUg!H^%A+a93V355>b5? zYngctddoo(`O4$8%s0tFcCBlgM)E@5sTKy{cvt7QCHk*$3-RhEOEgXOib58&!d%+D z%z0#dGIuX3?>n@)W{Q7@M@(DO<9FE}UTEF@l%(;R6q>l%2N7F6AB6gZV0rZN!4BDz zr?1o8`Vb+}!IJIc$K@M~IgfYe8RBV}8e~2|Jo;JlCf!(>8Jw`H`>a&q_hTfEH0uts zP#)^iX?HTbwxTjgJD%|A8aYZi(TB7xeZ-q#OkZ1PZk>-$|%jR+kKpk;4mKo;}^R9)ldU)18Z1H0d0YFF(f#H|hOOh37A-;O>Ij->(sMn7Q|PU1=QGtKsM{x# zLxzggO<7QirSw+c^$_s-UsO|eVm_c&Nj&*_;l4}3`fe1GHIL3f58 z#|5T&yP^`_%lwqR_9o3w9!y<2Z;OtLKMHE@7oJ{AQQYP+_Zn^+6t0U#dy6VG$uSD& zGIH^E&mAV`ropUOZd)PR z{EB1DP#^@JDpha(a-eFRR!Qh3FFe4PyyxZa(n39!_XH5;tGd8s>GpbJVT_C}3LI?n zt_?mM#*RbJ@d{e?C`6MzZb++6ON7BWS&NHaB1()|%U6`x(7;u^&i9cq7)$4IC8Z+RXBb_r|qona3Xv zf`m@rGhK_fVrDiMq5B>nSIF>^<7N6qTDPLju+(8xADDSydyxhUh7!;IRI zgNJ++W3jA78HuW_&LHb~@r_x#>{mF|=V{{0JdcN*s80Yq!O!ju)=2Md=?$BJ5;UZu z0N0&~rQy>x{N^ni1(FL$T7Q(sdwZgu@`$(O-N$kZ7fjBnJ|`dx1(D5aTx8aM5aXrx zEfS%8s{GB|Th8%GuIA}VADMfKSJH2s4%ZRVD>D}at9db=snBDbvRh1@okBX&8?{lx zn{X6Y^S^HUYAk-jPoTSiwXn20ax0<_U|7_LR%BSobcMMfC2_lPevBUDoYY9oSVke^ zto)ISt=g#Hd=x{B4fevbL>9a{>lcOM-HPfuK`jRCz8K}_?HN|RIvomqECi>;*LR*n ztETpSv;%GHxZj0#MxjYW09Es|l`75p*Q&3%SjMS3GniH)kaM2-M7jp>yU8I<*6GyZ zSqX6r5?7Zu&3az9GX-64^f5AS&Sp^WNf9pPW!`TC6X~-AsAUUYR;eQv(h;FtRw4o+)&xn zndR$JUlwF%IEdrO`D|A@wYVM?pj{vX_jzw596f&*9zlJ>vm$K`H#R$_()ZQvux~oj zQxtt~^%O35qV%sPAuvdV>jV%KmF%f5hfiMcOWQVECspzHSn?f6%jK83!hwG80B%$c zsN&mKc{t2Mrea=pn>Je@kU#c2R%Hks7%O+~Wk0i9^pd~VQb}q2B2=Wwjm{>4wMh!` zh6!1f*KOTwT6kxuHsGPq6HfT)PGz$eoq0|l11|RP4{G%H+vdh@wU2kY3LBQ6^VPsB zF`tL7-EghBW=HXBeXU;pcQ-YA4)ZMq!kT9}5@Dlu~1(BG%T;VNoD zTq^DDXg9aE{%_@Bhgg@vfwUKTZ&+)~ zsGCvNP)Lrm)`~D^nD$<)Fkkut<_x8`z3aMGsJeLq_#QvfD}MY~>fJ`K#!5>W`eknM z2ffVZyLX@6p;i_+R+^OjrV?>sXXDV+12_m@BV0|rb8m599SUVqOmwdzan&1JbxKcC+93yvM8veB*idEot?q= zk>-A*;xo5o*RZFt3AIX=h6b1S{5a41%-Qq+= zjYZ^lFYKL;l>>cU-mAupG*y)^GstZguQzc=HReX_o0e(S9lOOh>i^}-&`_=JQ<`;nhj%icD`UULhpwu5t!v@;nwrI`GZ##x1)=$ zg$L3jSxPPmh_56h1&wUR%JT6%D<&IG4@)$aiXZIpHU&Shrhe)QAAyupN&9@Co>2>L z|1K!j{di*nAVKE6_Ym!3d>%Z$-*lX_8IRx1NIU_QQ^^JNuP$A32-x1>nSNwtt>1Pa z^eDT@U{amEj_abGz!Ow|z^Ah%(6}^k;UlfJejh!|l^VwEGka1K4~-ca4IpP zWlaWR&|EA_0;Np!`cwSoU8T}Ct30f}#IhmDwI5RWYdJQ#A~`6Woydg-;BV3sZ3{-< zVg*EC>{75gvhJp={#5c8u~V-2$W-lAU^CyzZ0BeR`AD7dTXnT}iHc>!M{#Z&TLju<8)~ zs_T*56q`Usz7jm?9k*#?N~5&+n5D7yDTd8;$2ITwrmr5>!yL0sR$JU!UN@8!3^eO0 z$aL-TRqbrm&{hV_y|*BlDE_W61?Ar7t;rSC4AW_34^Cj)Yni)B=U?hoAnM9(9Xqhr z+0`C2NvB6Pm;1ou&?FYmDflU^zzgigc8*<1ke=K+E>?bmF>yv`D5XZ)p0US%l+^$* zIgWf|Wm<^-9N2VL8yE)1C#5dWaoNCsXilMaL zJ+H0XaP5#oRQl#vbwf)s)m^Ughqr27-cLTm7C15INA^w2)8q^~ryyk|j?^XY>Zx*Z zf#&MDo7U#F{K~U$T~lW-K3MIQGPyzVW%H>-4QqUH)oia0x;T80r9nOjH-5#5A2-=} z<}6);%lGU~sU{nmJg<#mIqR#D?vc66=l*(t|LdCfr0}l?^Ks$3@BQIbVsfmYzfhj_)VJ*}p0| z+m?@8>b@?uI_eldT|QOM&`~E04|B`obmI%Xxz3+@?o^UuBtv-Xrd&DM)7!+_-8u!x z$$+qH$7&5kiSv6bklbpfRujhn~FvV<9*&T^z^rlRkA#;{mEi;FgDw3@7w zU}w5T@DlzesEIt_;zYL^b>HH6?B1&vw3&QqruML4aY1)^h(n~somCnh`y0VhN<<;k zB5H8BJHwL$wpN>X?ejvJMUJ)~v#$tRIDP!`(G?jnI-}t9p=l4dN7}35&ALOsTbVnm z*8`X7^uLi$t$Rb_H2T5UXSF)|b&Kyc=ksa2IY%>`GQQF-OEXL?acXKBsJFPM6dKE< zBcsq}EDl?~uLf+{OG!vRZ|iJKB!*au(}(a||}hta%6@x-TXp6>jR1#m+r3?9N=ve{U0#1HBfjb`j zMyVETJ3adMN0g2I4hu#bN!#+K$vQb%OIs_17^;(QFw?_1vWWbcXD^((L7PcL1~xxP zNrognNHc3!To!t?SrWCtP>f2as=%dJmY?P{F$+s~IL!%OdonF;%tKZ zaw)u}iMKS3EoLAKIV{;^)G0`gI010WrK{@^xlD~&p#4lSyvk4*4-pYa_5`TNzPxdo zR!R|f*J#@&hB0su81cFBUYyL#9HyiDI*C1P?HONNTu77D_ul4Ah!I~oqtF`K8X1H1-Nu+9X!nSeDeMkK=?PMKm#z6zs*prA!})!UPkyPZ-E}19A!4c9Q7=&t@X6 z7R0l3Gz2c%k-g4V?&?}PsD_H+M@U@sIA{QF!IUuwR1MQDwzZERAV~zc5*up#%}-$i zl1g@`FZ1#01Te$ycBw+hfLao6yuZ{SLq!r6WCdeQw;G%O< zqEz%AlWG?5+jUp3IorM?>Z0PI^>}UHs3QW69(gq~4^M!Se4|B4ToMh-GdR+#El|p^ z9HioHl66>H0w#pM=SIslT1*ZoNMzM*je2RRMdaHT?qDC#C)Y~}?3oMQRNsBTV^v7i zK5j)$Oe$_gs#D-n5Sj?3hw{r|%7$6jnX~c)fOAqtk}g{ap^DXj66@$(zR=2{IM30K zFfOCCqGx5t5}NEO`mUT=hD3UG(dJdx{n=p=Mu#k9F8d{*a(44 zr_LI4e`Xqal6gA{F0AKUf+xIj(XmX|IWO!M%p6f>yhv|V#w^HofQuc4 zE!~YI|4uel0d?09mMClL9zSwK!wVE|ko$H?a=M2`MznC1s#?+YXJ0-}Q9|IYZ#$`l z^hpvGV6eJXLCz*NV3c`2qi8Cq4R|wS^C{Nn{Z_x^S*%b;-!7v;f)bu6nZ@pmrTXqE z!v+csMSH$c!zilSVn5KWnYnSTLAo}`f!&b7CYP1)wZ+Ww@Ai;Wo6dL+in~EcWm>#R zx0{mfK@V?|*JYB$&b@XUN;F#D5YZUPCxg3MpPPwv(C2d0Ex%JX$m5_hB{Ql6pA=XZ z7=(=p6x@90zen76d;UerCG*SlPl{(`5X2EhvRQeS1}M9P>2oO0p+)x?L+-g0vK%H) zSJqd2a!K9Qg(R9uYS?qm`fH4Ikm{Q*(L^i8#`LKH=j|@NnlDF)=S53n>s8i_Iv2ed z7$>#qpR%JV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz1W80eRCwC# zo68Y|FbqR&4LxlwG(!E`LJoo0^2?c-AX}0@4EejCSU8Hcv-`O#GAqB|GLB3+;5f&F z$m03+;AwHaRgW|AYs-7p&Rf8H`~aQ9m$&>ylkisOi_6@DE}QbtxtuBA0`*ywdg0O>DQ@|$F3~0R?aeqB_ZRdAUi!(t^EvY+I+~|9oBs@p&ok5fh3~81 Date: Sun, 16 Sep 2018 17:45:24 +0100 Subject: [PATCH 11/13] reduced all parameter update functions into one --- index.html | 2 +- src/scripts.js | 116 ++++++++++++++++++++++++++----------------------- 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/index.html b/index.html index 8702e16..05961c3 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

Fetch News

diff --git a/src/scripts.js b/src/scripts.js index 2c0417c..c051e17 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -8,47 +8,38 @@ const apiRequests = { ukTop20: 'https://newsapi.org/v2/top-headlines?country=gb&apiKey=9ed005ef4eb94baf913fce701c69972f', - customParameters : { - searchString: {val: null, string: ""}, - dateRange: {val: null, string: ""}, +//object contains stored parameters for searches + customParameters : { + q: {val: null, string: ""}, - excludedDomains: {val: null, string: ""}, + from: {val: null, string: ""}, - lang: {val: null, string: ""}, + excludeDomains: {val: null, string: ""}, - page: {val: 1, string: ""} - }, + language: {val: null, string: ""}, - getURL: function(){ - const customURL = `https://newsapi.org/v2/everything?q=${this.customParameters.searchString.string}${this.customParameters.dateRange.string}${this.customParameters.excludedDomains.string}${this.customParameters.page.string}${this.customParameters.lang.string}&apiKey=9ed005ef4eb94baf913fce701c69972f` - return customURL - }, + page: {val: 1, string: ""}, - updateSearchURL: function(userString){ - this.customParameters.searchString.string = userString + sortBy: {val: null, string: ""} }, - updatePageURL: function(inputPage){ - this.customParameters.page.val = inputPage - this.customParameters.page.string = `&page=${inputPage}` - }, - updateDateURL: function(daterange){ - this.customParameters.dateRange.val - this.customParameters.dateRange.string = `&from=${daterange}` +//getURL provides a url for API with specified parameters above + getURL: function(){ + const customURL = `https://newsapi.org/v2/everything?${this.customParameters.q.string}${this.customParameters.from.string}${this.customParameters.excludeDomains.string}${this.customParameters.page.string}${this.customParameters.language.string}${this.customParameters.sortBy.string}&apiKey=9ed005ef4eb94baf913fce701c69972f` + return customURL }, - updateBlockURL: function(){ - const blockedString = this.blockList.join(",") - this.customParameters.excludedDomains.string = `&excludeDomains=${blockedString}` + updateURL: function(parameter, update){ + this.customParameters[parameter].val = update + if (parameter === "q"){ + this.customParameters[parameter].string = `${parameter}=${update}` + }else{ + this.customParameters[parameter].string = `&${parameter}=${update}` + } }, - updateLangURL: function(language){ - this.customParameters.lang.string = `&language=${language}` - - - }, blockList: [] @@ -82,12 +73,14 @@ const pageHandlers = { const dateRange = formatDate(dateRangeElement.value) newsDisplayElement.innerHTML = "" paginationElement.style.display = "inline" - apiRequests.updateSearchURL(searchTextElement.value) - apiRequests.updateDateURL(dateRange) + + apiRequests.updateURL("q", searchTextElement.value) + apiRequests.updateURL("from", dateRange) const searchString = apiRequests.getURL() fetchNews(searchString) + searchTextElement.value = "" - this.checkPage() + pageHandlers.checkPage() }) }, @@ -99,27 +92,42 @@ const pageHandlers = { }, - paginationControl: function(){ - nextPageElement.addEventListener("click", event => { - let currentPage = apiRequests.customParameters.page.val + paginationControl: function(event){ + let currentPage = apiRequests.customParameters.page.val + if (event.target.value === "next"){ currentPage ++ - apiRequests.updatePageURL(currentPage) - const requestedPage = apiRequests.getURL() - newsDisplayElement.innerHTML = "" - fetchNews(requestedPage) - this.checkPage() - }) - - prevPageElement.addEventListener("click", event => { - let currentPage = apiRequests.customParameters.page.val + }else{ currentPage -- - apiRequests.updatePageURL(currentPage) - const requestedPage = apiRequests.getURL() - newsDisplayElement.innerHTML = "" - fetchNews(requestedPage) - this.checkPage() - - }) + } + apiRequests.updateURL("page", currentPage) + const requestedPage = apiRequests.getURL() + newsDisplayElement.innerHTML = "" + fetchNews(requestedPage) + pageHandlers.checkPage() + // nextPageElement.addEventListener("click", event => { + // let currentPage = apiRequests.customParameters.page.val + // if (event.target.value === "next"){ + // currentPage ++ + // }else{ + // currentPage -- + // } + // apiRequests.updatePageURL(currentPage) + // const requestedPage = apiRequests.getURL() + // newsDisplayElement.innerHTML = "" + // fetchNews(requestedPage) + // this.checkPage() + // }) + // + // prevPageElement.addEventListener("click", event => { + // let currentPage = apiRequests.customParameters.page.val + // currentPage -- + // apiRequests.updatePageURL(currentPage) + // const requestedPage = apiRequests.getURL() + // newsDisplayElement.innerHTML = "" + // fetchNews(requestedPage) + // this.checkPage() + // + // }) } @@ -162,15 +170,14 @@ function createStoryPanel(article){ headerElement.appendChild(headerLeftElement) headerElement.appendChild(storyImageElement) - storyDivElement.appendChild(headerElement) - - storyDivElement.appendChild(descriptionElement) storyDivElement.appendChild(linkElement) newsDisplayElement.appendChild(storyDivElement) } + + //formats date for search function formatDate(monthsAgo){ if ( monthsAgo != "all-time") { @@ -210,8 +217,9 @@ const newsDisplayElement = document.querySelector(".news-display") const paginationElement = document.querySelector(".pagination") const nextPageElement = document.querySelector(".next-page") const prevPageElement = document.querySelector(".back-page") +prevPageElement.addEventListener("click", pageHandlers.paginationControl) +nextPageElement.addEventListener("click", pageHandlers.paginationControl) fetchNews(apiRequests.usTop20) pageHandlers.changeCountry() pageHandlers.search() -pageHandlers.paginationControl() From 849c0e57c24b2bb18b668c966d2c6880e2e3d5e3 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Sun, 16 Sep 2018 19:15:39 +0100 Subject: [PATCH 12/13] hastily written form for language options and sortBy options --- index.html | 23 ++++++++++++++ src/scripts.js | 80 ++++++++++++++++++++--------------------------- styles/styles.css | 12 +++++++ 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/index.html b/index.html index 05961c3..74c39f7 100644 --- a/index.html +++ b/index.html @@ -26,9 +26,32 @@

Fetch News

+
+
+
+ +
Sort results by:
+ + + + + + + +
+
diff --git a/src/scripts.js b/src/scripts.js index c051e17..44a1e3b 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -48,11 +48,11 @@ const apiRequests = { //Object contains functions attached to buttons and page features const pageHandlers = { + changeCountry: function(){ const countryButtonElement = document.querySelector(".country-button") countryButtonElement.addEventListener("click", event => { paginationElement.style.display = "none"; - newsDisplayElement.innerHTML = "" countryButtonElement.textContent === "Top UK Stories" ? ( countryButtonElement.textContent = "Top US Stories", fetchNews(apiRequests.ukTop20)) @@ -61,29 +61,20 @@ const pageHandlers = { }) }, - search: function(){ - const searchFormElement = document.querySelector(".search-form") - const searchTextElement = document.querySelector(".search-text") - const dateRangeElement = document.querySelector(".date-range") - searchFormElement.addEventListener("submit", event => { + search: function(event){ event.preventDefault(); if (searchTextElement.value === ""){ return } const dateRange = formatDate(dateRangeElement.value) - newsDisplayElement.innerHTML = "" paginationElement.style.display = "inline" - apiRequests.updateURL("q", searchTextElement.value) apiRequests.updateURL("from", dateRange) - const searchString = apiRequests.getURL() - fetchNews(searchString) - + fetchNews(apiRequests.getURL()) searchTextElement.value = "" pageHandlers.checkPage() + }, - }) - }, checkPage: function(){ apiRequests.customParameters.page.val === 1 @@ -94,40 +85,13 @@ const pageHandlers = { paginationControl: function(event){ let currentPage = apiRequests.customParameters.page.val - if (event.target.value === "next"){ - currentPage ++ - }else{ - currentPage -- - } + event.target.value === "next" + ? currentPage ++ + : currentPage -- apiRequests.updateURL("page", currentPage) - const requestedPage = apiRequests.getURL() - newsDisplayElement.innerHTML = "" - fetchNews(requestedPage) + fetchNews(apiRequests.getURL()) pageHandlers.checkPage() - // nextPageElement.addEventListener("click", event => { - // let currentPage = apiRequests.customParameters.page.val - // if (event.target.value === "next"){ - // currentPage ++ - // }else{ - // currentPage -- - // } - // apiRequests.updatePageURL(currentPage) - // const requestedPage = apiRequests.getURL() - // newsDisplayElement.innerHTML = "" - // fetchNews(requestedPage) - // this.checkPage() - // }) - // - // prevPageElement.addEventListener("click", event => { - // let currentPage = apiRequests.customParameters.page.val - // currentPage -- - // apiRequests.updatePageURL(currentPage) - // const requestedPage = apiRequests.getURL() - // newsDisplayElement.innerHTML = "" - // fetchNews(requestedPage) - // this.checkPage() - // - // }) + } @@ -217,9 +181,33 @@ const newsDisplayElement = document.querySelector(".news-display") const paginationElement = document.querySelector(".pagination") const nextPageElement = document.querySelector(".next-page") const prevPageElement = document.querySelector(".back-page") +const searchFormElement = document.querySelector(".search-form") +const searchTextElement = document.querySelector(".search-text") +const dateRangeElement = document.querySelector(".date-range") +const advancedSearchElement = document.querySelector(".advanced-search") +const advancedSearchMenu = document.querySelector(".advanced-search-options") +const advancedSearchForm = document.querySelector(".advanced-search-form") +const languageSelector = document.querySelector(".language-select") +const sortBySelector = document.querySelector(".sort-by-select") +searchFormElement.addEventListener("submit", pageHandlers.search) prevPageElement.addEventListener("click", pageHandlers.paginationControl) nextPageElement.addEventListener("click", pageHandlers.paginationControl) +advancedSearchElement.addEventListener("click", event => { + console.log("click") + advancedSearchMenu.style.display === "none" + ? advancedSearchMenu.style.display = "block" + : advancedSearchMenu.style.display = "none" +}) + +advancedSearchForm.addEventListener("submit", event => { + event.preventDefault() + apiRequests.updateURL("language", languageSelector.value) + apiRequests.updateURL("sortBy", sortBySelector.value ) +}) + + + + fetchNews(apiRequests.usTop20) pageHandlers.changeCountry() -pageHandlers.search() diff --git a/styles/styles.css b/styles/styles.css index 478c921..d646d4f 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -24,6 +24,18 @@ header{ overflow-y: auto; } +.advanced-search-options{ + display: none; + width: 100vw; + height:80px; + background-color: white; +} + +.advanced-search-form{ + display: flex; + flex-direction: row; +} + .news-display{ background: #E9EEF2 url("../images/backdrop.png") repeat-x; From 9c3437e03504184c3d4aab406a4e717376f57279 Mon Sep 17 00:00:00 2001 From: DanGRT Date: Mon, 17 Sep 2018 09:40:52 +0100 Subject: [PATCH 13/13] added basic block function --- src/scripts.js | 52 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 44a1e3b..049c548 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -12,15 +12,10 @@ const apiRequests = { //object contains stored parameters for searches customParameters : { q: {val: null, string: ""}, - from: {val: null, string: ""}, - excludeDomains: {val: null, string: ""}, - language: {val: null, string: ""}, - page: {val: 1, string: ""}, - sortBy: {val: null, string: ""} }, @@ -93,7 +88,25 @@ const pageHandlers = { pageHandlers.checkPage() -} +}, + + updateAdvancedOptions: event => { + event.preventDefault() + apiRequests.updateURL("language", languageSelector.value) + apiRequests.updateURL("sortBy", sortBySelector.value ) + pageHandlers.search(event) +}, + + openCloseAdvanced: event => { + advancedSearchMenu.style.display === "none" + ? advancedSearchMenu.style.display = "block" + : advancedSearchMenu.style.display = "none" +}, + + blockSource: event => { + const host = linkElement.hostname + console.log(host) + } } @@ -114,22 +127,30 @@ function createStoryPanel(article){ const headlineElement = assignElement("h2", "headline", article.title) const publicationNameElement = assignElement("h4", "publication-name", article.source.name) const publicationDateElement = assignElement("h4", "publication-date", convertDateForDisplay(article.publishedAt)) + const blockButtonElement = assignElement("button", "block-button", "Block") const storyImageElement = assignElement("img", "story-image") storyImageElement.setAttribute("src", article.urlToImage) if (storyImageElement.src === "http://127.0.0.1:3000/null"){ storyImageElement.setAttribute("src", "../images/No_Image_Available.jpg") } - const descriptionElement = assignElement("p", "description-element", article.description) const linkElement = assignElement("a", "full-story-link", "See full story") linkElement.setAttribute("href", article.url) - + blockButtonElement.addEventListener("click", event => { + let host = linkElement.hostname + host = host.replace("www.", "") + apiRequests.blockList.push(host) + const blockedDomains = apiRequests.blockList.join(",") + apiRequests.updateURL("excludeDomains", blockedDomains) + fetchNews(apiRequests.getURL()) + }) publicationInfoElement.appendChild(publicationNameElement) publicationInfoElement.appendChild(publicationDateElement) headerLeftElement.appendChild(headlineElement) headerLeftElement.appendChild(publicationInfoElement) + headerLeftElement.appendChild(blockButtonElement) headerElement.appendChild(headerLeftElement) headerElement.appendChild(storyImageElement) @@ -192,19 +213,10 @@ const sortBySelector = document.querySelector(".sort-by-select") searchFormElement.addEventListener("submit", pageHandlers.search) prevPageElement.addEventListener("click", pageHandlers.paginationControl) nextPageElement.addEventListener("click", pageHandlers.paginationControl) +advancedSearchElement.addEventListener("click", pageHandlers.openCloseAdvanced) +advancedSearchForm.addEventListener("submit", pageHandlers.updateAdvancedOptions) + -advancedSearchElement.addEventListener("click", event => { - console.log("click") - advancedSearchMenu.style.display === "none" - ? advancedSearchMenu.style.display = "block" - : advancedSearchMenu.style.display = "none" -}) - -advancedSearchForm.addEventListener("submit", event => { - event.preventDefault() - apiRequests.updateURL("language", languageSelector.value) - apiRequests.updateURL("sortBy", sortBySelector.value ) -})