From 69bc51cbfd478fd3a523ca3030e56a2dec7b78fa Mon Sep 17 00:00:00 2001 From: haha1906 Date: Tue, 24 Sep 2019 17:51:34 +0200 Subject: [PATCH 1/5] JS3-Week2-Homework --- homework/index.js | 212 +++++++++++++++++++++++++++++++-------------- homework/style.css | 41 +++++++-- 2 files changed, 180 insertions(+), 73 deletions(-) diff --git a/homework/index.js b/homework/index.js index 23a60f971..6246715de 100644 --- a/homework/index.js +++ b/homework/index.js @@ -1,81 +1,163 @@ 'use strict'; -function fetchJSON(url, cb) { - const xhr = new XMLHttpRequest(); - xhr.open('GET', url); - xhr.responseType = 'json'; - xhr.onload = () => { - if (xhr.status >= 200 && xhr.status <= 299) { - cb(null, xhr.response); - } else { - cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); - } - }; - xhr.onerror = () => cb(new Error('Network request failed')); - xhr.send(); -} - -function createAndAppend(name, parent, options = {}) { - const elem = document.createElement(name); - parent.appendChild(elem); - Object.entries(options).forEach(([key, value]) => { - if (key === 'text') { - elem.textContent = value; - } else { - elem.setAttribute(key, value); - } - }); - return elem; -} +{ + function fetchJSON(url, cb) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status <= 299) { + cb(null, xhr.response); + } else { + cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => cb(new Error('Network request failed')); + xhr.send(); + } -function addRow(property, key, parent, link) { - const tr = createAndAppend('tr', parent); - createAndAppend('th', tr, { - text: `${property} :`, - }); + function createAndAppend(name, parent, options = {}) { + const elem = document.createElement(name); + parent.appendChild(elem); + Object.entries(options).forEach(([key, value]) => { + if (key === 'text') { + elem.textContent = value; + } else { + elem.setAttribute(key, value); + } + }); + return elem; + } - if (link) { - const td = createAndAppend('td', tr); - createAndAppend('a', td, { + function addCont(login, img, contributeNumber, parent, link) { + const tr = createAndAppend('tr', parent); + const imageColumn = createAndAppend('th', tr); + createAndAppend('img', imageColumn, { + src: img, + class: 'contributorImg', + }); + const name = createAndAppend('td', tr); + createAndAppend('a', name, { href: link, target: '_blank', - text: key, + text: login, + }); + const contributeNamePlace = createAndAppend('td', tr); + createAndAppend('span', contributeNamePlace, { + text: contributeNumber, + class: 'contributeNumber', + }); + } + + function addRow(property, key, parent) { + const tr = createAndAppend('tr', parent); + createAndAppend('th', tr, { + text: `${property} :`, }); - } else { createAndAppend('td', tr, { text: key }); + return tr; } -} -function renderRepoDetails(repo, div) { - const table = createAndAppend('table', div, { - class: 'container', - }); + let optionNumber = 0; + function madeOption(repo, selectButton) { + createAndAppend('option', selectButton, { + text: repo.name, + value: optionNumber, + }); + optionNumber++; + } - addRow('Repository', repo.name, table, repo.html_url); - addRow('Description', repo.description, table); - addRow('Forks', repo.forks, table); - addRow('Updated', repo.updated_at, table); -} + function renderContributorDetails(conts, contributorsContainer) { + const table = createAndAppend('table', contributorsContainer); + conts.forEach(cont => { + addCont( + cont.login, + cont.avatar_url, + cont.contributions, + table, + cont.html_url, + ); + }); + } -function main(url) { - fetchJSON(url, (err, repos) => { - const root = document.getElementById('root'); - if (err) { - createAndAppend('div', root, { - text: err.message, - class: 'alert-error', - }); - return; - } - createAndAppend('header', root, { text: 'HYF Repositories' }); - const div = createAndAppend('div', root); + function renderRepoDetails(repo, div) { + const table = createAndAppend('table', div); + const firstRow = addRow('Repository', '', table); + createAndAppend('a', firstRow.lastChild, { + href: repo.html_url, + target: '_blank', + text: repo.name, + }); + addRow('Description', repo.description, table); + addRow('Forks', repo.forks, table); + addRow('Updated', repo.updated_at, table); + } + + function fetchContributors(url, contributorsContainer) { + fetchJSON(url, (err, conts) => { + if (err) { + createAndAppend('div', contributorsContainer, { + text: err.message, + class: 'alert-error', + }); + return; + } + renderContributorDetails(conts, contributorsContainer); + }); + } + + function deleteContainers() { + document.getElementById('flexContainer').remove(); + } + + function makeFlexContainer(root, repos, selectButton) { + const flexContainer = createAndAppend('section', root, { + id: 'flexContainer', + }); + const repoContainer = createAndAppend('section', flexContainer, { + class: 'container', + }); + const contributorsContainer = createAndAppend('section', flexContainer, { + class: 'container', + }); + createAndAppend('h6', contributorsContainer, { text: 'Contributions' }); // eslint-disable-next-line func-names repos .sort((a, b) => a.name.localeCompare(b.name)) - .forEach(repo => renderRepoDetails(repo, div)); - }); -} + .forEach(repo => { + madeOption(repo, selectButton); + }); + renderRepoDetails(repos[selectButton.value], repoContainer); + fetchContributors( + repos[selectButton.value].contributors_url, + contributorsContainer, + ); + } + + function main(url) { + fetchJSON(url, (err, repos) => { + const root = document.getElementById('root'); + if (err) { + createAndAppend('div', root, { + text: err.message, + class: 'alert-error', + }); + return; + } + const header = createAndAppend('header', root, { + text: 'HYF Repositories', + }); -const HYF_REPOS_URL = - 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; -window.onload = () => main(HYF_REPOS_URL); + const selectButton = createAndAppend('select', header); + selectButton.addEventListener('change', () => { + deleteContainers(); + makeFlexContainer(root, repos, selectButton); + }); + makeFlexContainer(root, repos, selectButton); + }); + } + + const HYF_REPOS_URL = + 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + window.onload = () => main(HYF_REPOS_URL); +} diff --git a/homework/style.css b/homework/style.css index b1f439ece..0f234f8fe 100644 --- a/homework/style.css +++ b/homework/style.css @@ -14,15 +14,28 @@ header { background: rgb(25, 25, 25); border: black solid 3px; border-radius: 10px; - max-width: 700px; + max-width: 1100px; position: relative; margin: auto; } +select { + margin: 10px; +} + +#flexContainer { + display: flex; + flex-wrap: wrap; + border: solid black 2px; + max-width: 1100px; + position: relative; + margin: auto; + align-items: flex-start; +} .container { - margin-left: 4px; - padding: 8px; - padding-left: 12px; + margin: 2px; + padding: 6px; + padding-left: 8px; background: rgb(40, 40, 40); border-left: rgb(60, 60, 60) solid 2px; border-top: rgb(100, 100, 100) solid 2px; @@ -30,14 +43,13 @@ header { border-bottom: black solid 3px; border-radius: 5px; max-width: 700px; - align-content: center; - position: relative; - margin: auto; + min-width: 300px; + flex: 1; + vertical-align: top; } table { width: 100%; margin-left: 6px; - padding-left: 10px; } tr:hover { @@ -59,3 +71,16 @@ a { a:visited { color: lightgreen; } +.contributorImg { + width: 60px; +} +.contributeNumber { + background: rgb(50, 50, 50); + border-left: rgb(60, 60, 60) solid 2px; + border-top: rgb(100, 100, 100) solid 2px; + border-right: rgb(20, 20, 20) solid 3px; + border-bottom: black solid 3px; + border-radius: 5px; + position: relative; + text-align: right; +} From 0e92d37f13cde2c908868d2531f33d83560e97f1 Mon Sep 17 00:00:00 2001 From: haha1906 Date: Tue, 24 Sep 2019 18:05:03 +0200 Subject: [PATCH 2/5] JS3-Week2-Homework --- homework/index.js | 2 +- homework/style.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homework/index.js b/homework/index.js index 6246715de..fc3e0d1d9 100644 --- a/homework/index.js +++ b/homework/index.js @@ -120,7 +120,7 @@ const contributorsContainer = createAndAppend('section', flexContainer, { class: 'container', }); - createAndAppend('h6', contributorsContainer, { text: 'Contributions' }); + createAndAppend('h5', contributorsContainer, { text: 'Contributions' }); // eslint-disable-next-line func-names repos .sort((a, b) => a.name.localeCompare(b.name)) diff --git a/homework/style.css b/homework/style.css index 0f234f8fe..8bf714c2a 100644 --- a/homework/style.css +++ b/homework/style.css @@ -8,7 +8,7 @@ body { } header { - margin: 3px; + margin: 4px; padding: 10px; padding-left: 20px; background: rgb(25, 25, 25); From d2a83c9d0dc0d55068e85f2bf5dfd2f423a75e67 Mon Sep 17 00:00:00 2001 From: haha1906 Date: Wed, 25 Sep 2019 17:31:29 +0200 Subject: [PATCH 3/5] Week2 Homework promise added --- homework/index.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/homework/index.js b/homework/index.js index fc3e0d1d9..054805e31 100644 --- a/homework/index.js +++ b/homework/index.js @@ -1,19 +1,21 @@ 'use strict'; { - function fetchJSON(url, cb) { - const xhr = new XMLHttpRequest(); - xhr.open('GET', url); - xhr.responseType = 'json'; - xhr.onload = () => { - if (xhr.status >= 200 && xhr.status <= 299) { - cb(null, xhr.response); - } else { - cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); - } - }; - xhr.onerror = () => cb(new Error('Network request failed')); - xhr.send(); + function fetchJSON(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status <= 299) { + resolve(xhr.response); + } else { + reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => reject(new Error('Network request failed')); + xhr.send(); + }); } function createAndAppend(name, parent, options = {}) { @@ -94,7 +96,8 @@ } function fetchContributors(url, contributorsContainer) { - fetchJSON(url, (err, conts) => { + const promiseContributor = fetchJSON(url); + promiseContributor.then((conts, err) => { if (err) { createAndAppend('div', contributorsContainer, { text: err.message, @@ -135,7 +138,8 @@ } function main(url) { - fetchJSON(url, (err, repos) => { + const promise = fetchJSON(url); + promise.then((repos, err) => { const root = document.getElementById('root'); if (err) { createAndAppend('div', root, { From f523f30daf23758d0d5056bae55560363d61f7f3 Mon Sep 17 00:00:00 2001 From: haha1906 Date: Thu, 26 Sep 2019 18:27:09 +0200 Subject: [PATCH 4/5] mistakes with promise errors, kebab-cases, variables names are corrected. --- homework/index.js | 99 +++++++++++++++++++--------------------------- homework/style.css | 6 +-- 2 files changed, 44 insertions(+), 61 deletions(-) diff --git a/homework/index.js b/homework/index.js index 054805e31..4c0f6acec 100644 --- a/homework/index.js +++ b/homework/index.js @@ -31,23 +31,23 @@ return elem; } - function addCont(login, img, contributeNumber, parent, link) { + function addContributor(contributor, parent) { const tr = createAndAppend('tr', parent); const imageColumn = createAndAppend('th', tr); createAndAppend('img', imageColumn, { - src: img, - class: 'contributorImg', + src: contributor.avatar_url, + class: 'contributor-img', }); const name = createAndAppend('td', tr); createAndAppend('a', name, { - href: link, + href: contributor.html_url, target: '_blank', - text: login, + text: contributor.login, }); const contributeNamePlace = createAndAppend('td', tr); createAndAppend('span', contributeNamePlace, { - text: contributeNumber, - class: 'contributeNumber', + text: contributor.contributions, + class: 'contribute-number', }); } @@ -60,25 +60,10 @@ return tr; } - let optionNumber = 0; - function madeOption(repo, selectButton) { - createAndAppend('option', selectButton, { - text: repo.name, - value: optionNumber, - }); - optionNumber++; - } - - function renderContributorDetails(conts, contributorsContainer) { + function renderContributorDetails(contributors, contributorsContainer) { const table = createAndAppend('table', contributorsContainer); - conts.forEach(cont => { - addCont( - cont.login, - cont.avatar_url, - cont.contributions, - table, - cont.html_url, - ); + contributors.forEach(contributor => { + addContributor(contributor, table); }); } @@ -94,28 +79,29 @@ addRow('Forks', repo.forks, table); addRow('Updated', repo.updated_at, table); } + function renderError(error, contributorsContainer) { + createAndAppend('div', contributorsContainer, { + text: error.message, + class: 'alert-error', + }); + } function fetchContributors(url, contributorsContainer) { const promiseContributor = fetchJSON(url); - promiseContributor.then((conts, err) => { - if (err) { - createAndAppend('div', contributorsContainer, { - text: err.message, - class: 'alert-error', - }); - return; - } - renderContributorDetails(conts, contributorsContainer); - }); + promiseContributor + .then(contributors => { + renderContributorDetails(contributors, contributorsContainer); + }) + .catch(error => renderError(error, contributorsContainer)); } function deleteContainers() { - document.getElementById('flexContainer').remove(); + document.getElementById('flex-container').remove(); } function makeFlexContainer(root, repos, selectButton) { const flexContainer = createAndAppend('section', root, { - id: 'flexContainer', + id: 'flex-container', }); const repoContainer = createAndAppend('section', flexContainer, { class: 'container', @@ -124,11 +110,14 @@ class: 'container', }); createAndAppend('h5', contributorsContainer, { text: 'Contributions' }); - // eslint-disable-next-line func-names + repos .sort((a, b) => a.name.localeCompare(b.name)) - .forEach(repo => { - madeOption(repo, selectButton); + .forEach((repo, index) => { + createAndAppend('option', selectButton, { + text: repo.name, + value: index, + }); }); renderRepoDetails(repos[selectButton.value], repoContainer); fetchContributors( @@ -138,27 +127,21 @@ } function main(url) { + const root = document.getElementById('root'); + const header = createAndAppend('header', root, { + text: 'HYF Repositories', + }); const promise = fetchJSON(url); - promise.then((repos, err) => { - const root = document.getElementById('root'); - if (err) { - createAndAppend('div', root, { - text: err.message, - class: 'alert-error', + promise + .then(repos => { + const selectButton = createAndAppend('select', header); + selectButton.addEventListener('change', () => { + deleteContainers(); + makeFlexContainer(root, repos, selectButton); }); - return; - } - const header = createAndAppend('header', root, { - text: 'HYF Repositories', - }); - - const selectButton = createAndAppend('select', header); - selectButton.addEventListener('change', () => { - deleteContainers(); makeFlexContainer(root, repos, selectButton); - }); - makeFlexContainer(root, repos, selectButton); - }); + }) + .catch(error => renderError(error, root)); } const HYF_REPOS_URL = diff --git a/homework/style.css b/homework/style.css index 8bf714c2a..72318c342 100644 --- a/homework/style.css +++ b/homework/style.css @@ -22,7 +22,7 @@ select { margin: 10px; } -#flexContainer { +#flex-container { display: flex; flex-wrap: wrap; border: solid black 2px; @@ -71,10 +71,10 @@ a { a:visited { color: lightgreen; } -.contributorImg { +.contributor-img { width: 60px; } -.contributeNumber { +.contribute-number { background: rgb(50, 50, 50); border-left: rgb(60, 60, 60) solid 2px; border-top: rgb(100, 100, 100) solid 2px; From 5fcd491b04dc92d5e434daa569b98b032e8ee16d Mon Sep 17 00:00:00 2001 From: haha1906 Date: Sat, 28 Sep 2019 22:20:32 +0200 Subject: [PATCH 5/5] Option values aren't added each time, anymore. --- homework/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/homework/index.js b/homework/index.js index 4c0f6acec..0c0a06f4c 100644 --- a/homework/index.js +++ b/homework/index.js @@ -96,6 +96,12 @@ } function deleteContainers() { + const selectButton = document.getElementById('selectButton'); + let firstOption = selectButton.firstChild; + while (firstOption) { + selectButton.removeChild(firstOption); + firstOption = selectButton.firstChild; + } document.getElementById('flex-container').remove(); } @@ -134,7 +140,9 @@ const promise = fetchJSON(url); promise .then(repos => { - const selectButton = createAndAppend('select', header); + const selectButton = createAndAppend('select', header, { + id: 'selectButton', + }); selectButton.addEventListener('change', () => { deleteContainers(); makeFlexContainer(root, repos, selectButton);