Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions details.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</head>
<body>
<!-- Loader -->
<div class="loader">
<div class="loader" id="loader">
<div class="spinner">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need both class and id?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because I used get element by id in the js.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cant you get it via class? I mean you already have a class loader.

<i class="fa-regular fa-circle-notch fa-spin icon"></i>
</div>
Expand Down Expand Up @@ -71,10 +71,10 @@ <h1>Where in the world?</h1>
</div>
<main class="main">
<div class="container">
<section class="country-details"></section>
<section class="country-details"id="country-name"></section>
</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question in here

</main>
<script src="./js/common.js"></script>
<script src="./js/details.js"></script>
<script src="details.js"></script>

</body>
</html>
61 changes: 61 additions & 0 deletions details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

// Fetch the JSON data
fetch('./CountriesData.json')
.then(response => response.json())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded strings should be saved into a constants file

.then(countries => {
const urlParams = new URLSearchParams(window.location.search);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract thing into a separate function, huge functions are not readable

const countryName = urlParams.get('country');

const country = countries.find(c =>
c.name.toLowerCase() === countryName.toLowerCase()
);

// If the country is found, display its details
if (country) {
const countryContainer = document.createElement('div');
countryContainer.className = 'country-details';

const flagContainer = document.createElement('div');
flagContainer.className = 'country-flag';
const flagImage = document.createElement('img');
flagImage.src = country.flag;
flagImage.alt = `${country.name} Flag`;
flagContainer.appendChild(flagImage);

const infoContainer = document.createElement('div');
infoContainer.className = 'country-info';

const countryTitle = document.createElement('h1');
countryTitle.textContent = country.name;
infoContainer.appendChild(countryTitle);

const details = [
{ label: 'Population', value: country.population.toLocaleString() },
{ label: 'Region', value: country.region },
{ label: 'Capital', value: country.capital || 'N/A' }
];

details.forEach(detail => {
const detailElement = document.createElement('p');
detailElement.innerHTML = `<strong>${detail.label}:</strong> ${detail.value}`;
infoContainer.appendChild(detailElement);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use innerHTML it is a dangerous method

});

countryContainer.appendChild(flagContainer);
countryContainer.appendChild(infoContainer);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a tip - if you will need to add a lot of children's save the children into an array and loop the array to remove code duplication

For those 2 lines its ok

document.body.appendChild(countryContainer);

const loader = document.getElementById('loader');
if (loader) {
loader.style.display = 'none';
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not style your elements with js, use css classes

} else {
const errorMessage = document.createElement('p');
errorMessage.textContent = 'Country not found!';
document.body.appendChild(errorMessage);
}
})
.catch(error => {
console.error('Error loading the JSON data:', error);
});
73 changes: 7 additions & 66 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ <h1>Where in the world?</h1>
type="text"
class="search-input"
placeholder="Search for a country..."
id="country-filter"
/>
</div>
<div class="dropdown-wrapper">
<div class="dropdown-header flex flex-jc-sb flex-ai-c">
<div class="dropdown-wrapper" id="dropdown-wrapper">
<div class="dropdown-header flex flex-jc-sb flex-ai-c" id="dropdown-header">
<span>Filter by Region</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ids are unique - you should only have 1 of the same id in your page

<i class="fa-regular fa-chevron-down icon"></i>
</div>
Expand All @@ -87,72 +88,12 @@ <h1>Where in the world?</h1>
<!-- Countries -->
<main class="main">
<div class="container">
<section class="countries-grid">
<a
href="#"
class="country scale-effect"
data-country-name="Afghanistan"
>
<div class="country-flag">
<img
src="https://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_the_Taliban.svg"
alt="Afghanistan FLag"
/>
</div>
<div class="country-info">
<h2 class="country-title">Afghanistan</h2>
<ul class="country-brief">
<li><strong>population: </strong>40218234</li>
<li><strong>Region: </strong>Asia</li>
<li><strong>capital: </strong>Kabul</li>
</ul>
</div>
</a>
<a
href="#"
class="country scale-effect"
data-country-name="Åland Islands"
>
<div class="country-flag">
<img src="https://flagcdn.com/ax.svg" alt="Åland Islands FLag" />
</div>
<div class="country-info">
<h2 class="country-title">Åland Islands</h2>
<ul class="country-brief">
<li><strong>population: </strong>28875</li>
<li><strong>Region: </strong>Europe</li>
<li><strong>capital: </strong>Mariehamn</li>
</ul>
</div>
</a>
<a href="#" class="country scale-effect" data-country-name="Aruba">
<div class="country-flag">
<img src="https://flagcdn.com/aw.svg" alt="Aruba FLag" />
</div>
<div class="country-info">
<h2 class="country-title">Aruba</h2>
<ul class="country-brief">
<li><strong>population: </strong>106766</li>
<li><strong>Region: </strong>Americas</li>
<li><strong>capital: </strong>Oranjestad</li>
</ul>
</div>
</a>
<a href="#" class="country scale-effect" data-country-name="Belize">
<div class="country-flag">
<img src="https://flagcdn.com/bz.svg" alt="Belize FLag" />
</div>
<div class="country-info">
<h2 class="country-title">Belize</h2>
<ul class="country-brief">
<li><strong>population: </strong>397621</li>
<li><strong>Region: </strong>Americas</li>
<li><strong>capital: </strong>Belmopan</li>
</ul>
</div>
</a>
<section class="countries-grid" id="countries-g">

</section>
</div>
</main>
<script src="index.js"></script>

</body>
</html>
125 changes: 125 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
fetch('CountriesData.json')
.then((response) => response.json())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing in here about the hardcoded strings into constants

.then((countries) => {
const countriesContainer = document.getElementById('countries-g');
if (!countriesContainer) {
console.error('countries-g container not found in the DOM!');
return;
}

// global variable
let allCountries = countries;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is global vriable?

function displayCountries(countriesToDisplay) {
countriesContainer.innerHTML = ''; // Cleaning all the current HTML in the div
countriesToDisplay.forEach((country) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment in here do not use global variable

const countryDiv = document.createElement('div');
countryDiv.className = 'country';

const countryLink = document.createElement('a');
countryLink.href = `details.html?country=${country.name}`;
countryDiv.appendChild(countryLink);

const countryflagDiv = document.createElement('div');
countryflagDiv.className = 'country-flag';

const imgFlag = document.createElement('img');
imgFlag.src = `${country.flag}`;
imgFlag.alt = `${country.name}`;
countryflagDiv.appendChild(imgFlag);
countryLink.appendChild(countryflagDiv);

const countryInfo = document.createElement('div');
countryInfo.className = 'country-info';

const countryH = document.createElement('h2');
countryH.textContent = `${country.name}`;
countryInfo.appendChild(countryH);

const countryPopulation = document.createElement('p');
const strongP = document.createElement('strong');
strongP.textContent = 'Population: ';
countryPopulation.appendChild(strongP);
countryPopulation.appendChild(document.createTextNode(country.population));
countryInfo.appendChild(countryPopulation);

const countryRegion = document.createElement('p');
const strongR = document.createElement('strong');
strongR.textContent = 'Region: ';
countryRegion.appendChild(strongR);
countryRegion.appendChild(document.createTextNode(country.region));
countryInfo.appendChild(countryRegion);

const countryCapital = document.createElement('p');
const strongC = document.createElement('strong');
strongC.textContent = 'Capital: ';
countryCapital.appendChild(strongC);
countryCapital.appendChild(document.createTextNode(country.capital));
countryInfo.appendChild(countryCapital);

countryDiv.appendChild(countryInfo);
countriesContainer.appendChild(countryDiv);
});
}


displayCountries(allCountries);

// Filter by input
function filteredCountriesByInput() {
const filterText = document.getElementById('country-filter').value.toLowerCase();

// Filter the countries based on the input
const filteredCountries = allCountries.filter(country =>
Object.values(country).some(value =>
value.toString().toLowerCase().includes(filterText)
)
);

// Display the filtered results
displayCountries(filteredCountries);
}

// Add event listener to the input field
document.getElementById('country-filter').addEventListener('input', filteredCountriesByInput);

// filter by region
const filterItems = document.querySelectorAll('#dropdown-wrapper ul li');
filterItems.forEach((item) => {
item.addEventListener('click', () => {
const region = item.getAttribute('data-region');

let filteredCountries;
if (region === 'all') {
filteredCountries = allCountries;
} else {
filteredCountries = allCountries.filter((country) => {
return country.region.toLowerCase() === region;
});
}

// the output
if (filteredCountries.length === 0) {
countriesContainer.innerHTML = '<p>No countries found.</p>';
} else {
displayCountries(filteredCountries);
}

// close the menu after the choice
document.getElementById('dropdown-wrapper').classList.remove('open');
});
});
})
.catch((error) => {
console.error('Error loading the JSON data:', error);
});

// open the menu of the filter
document.addEventListener('DOMContentLoaded', function () {
const dropdownHeader = document.getElementById('dropdown-header');
const dropdownWrapper = document.getElementById('dropdown-wrapper');

dropdownHeader.addEventListener('click', function () {
dropdownWrapper.classList.toggle('open');
});
});