-3

let div = document.createElement('div');
let ul = document.createElement('ul');

const data = {};

const el = document.getElementById("name");

sortName = 0;
sortCapital = 0;
sortPopulation = 0;
sortArea = 0;


function sortByArea(data) {
  var child = container.lastElementChild;
  while (child) {
    container.removeChild(child);
    child = container.lastElementChild;
  }
  if(sortArea == 0){
    data.sort((a, b) => {
      if (a.area > b.area) return 1;
      else return -1
    });
    return data;
  }
  data.sort((a, b) => {
    if (a.area < b.area) return 1;
    else return -1
  });
  return data;
}

function sortByPopulation(data) {
  var child = container.lastElementChild;
  while (child) {
    container.removeChild(child);
    child = container.lastElementChild;
  }
  if(sortPopulation == 0){
    data.sort((a, b) => {
      if (a.population > b.population) return 1;
      else return -1
    });
    return data;
  }
  data.sort((a, b) => {
    if (a.population < b.population) return 1;
    else return -1
  });
  return data;
}

function sortByCapital(data) {
  var child = container.lastElementChild;
  while (child) {
    container.removeChild(child);
    child = container.lastElementChild;
  }
  if(sortCapital == 0){
    data.sort((a, b) => {
      if (a.capital > b.capital) return 1;
      else return -1
    });
    return data;
  }
  data.sort((a, b) => {
    if (a.capital < b.capital) return 1;
    else return -1
  });
  return data;
}

function sortByName(data) {
  var child = container.lastElementChild;
  while (child) {
    container.removeChild(child);
    child = container.lastElementChild;
  }
  if(sortName == 0){
    data.sort((a, b) => {
      if (a.name > b.name) return 1;
      else return -1
    });
    return data;
  }
  data.sort((a, b) => {
    if (a.name < b.name) return 1;
    else return -1
  });
  return data;
}
document.getElementById('area').addEventListener('click', () => f(4));
document.getElementById('population').addEventListener('click', () => f(3));
document.getElementById('capital').addEventListener('click', () => f(2));
document.getElementById('name').addEventListener('click', () => f(1));

div.appendChild(ul);
async function f(e) {
  //fetching and sorting data by regions and subregions
  const res = await fetch("https://restcountries.com/v3.1/all");
  var data = await res.json();

  const container = document.getElementById('container');
  const accordion = document.createElement('div');
  const olWrapper = document.getElementById('listWrapper');
  const subRegionWrapper = document.getElementById('subRegionWrapper');

  switch (e) {
    case 1:
      data = sortByName(data);
      sortName += 1;
      sortName %= 2;
    case 2:
      data = sortByCapital(data);
      sortCapital += 1;
      sortCapital %= 2;
    case 3:
      data = sortByPopulation(data);
      sortPopulation += 1;
      sortPopulation %= 2;
    case 4:
      data = sortByArea(data);
      sortArea += 1;
      sortArea %= 2;
  }

  data.sort((a, b) => {
    if (a.region > b.region) return 1;
    else if (a.region < b.region) return -1
    else {
      if (a.subregion > b.subregion) return 1;
      else return -1;
    }
  });

  const subRegions = data.reduce((r, a) => {
    r[a.subregion] = r[a.subregion] || [];
    r[a.subregion].push(a);
    return r;
  }, {});

  const dropdownValues = Object.entries(subRegions);
  dropdownValues.forEach(subRegion => {
    const accordionWrapper = document.createElement('div');
    const panel = document.createElement('div');
    panel.classList.add('panel');
    accordionWrapper.classList.add('accordion');

    const totalArea = subRegion[1].reduce((acc, curr) => acc + curr.area, 0);
    const totalPopulation = subRegion[1].reduce((acc, curr) => acc + curr.population, 0);
    const li = createSubregion(subRegion[0], totalPopulation, totalArea);

    accordionWrapper.appendChild(li);
    accordion.appendChild(accordionWrapper);
    subRegion[1].forEach(item => {
      const subLi = createCountry(item.name.common, item.capital, item.area, item.population);
      const subOl = document.createElement('ol');
      subOl.appendChild(subLi);
      panel.appendChild(subOl);
      accordion.appendChild(panel);
    });

    accordionWrapper.addEventListener('click', function () {
      this.classList.toggle("active");
      const panel = this.nextElementSibling;
      if (panel.style.display === "block") {
        panel.style.display = "none";
      } else {
        panel.style.display = "block";
      }
    });
  });

  container.appendChild(accordion);
}

function createSubregion(name, population, area) {
  var li = document.createElement("li");
  li.setAttribute("class", "subregion");

  var header = document.createElement("div");
  header.setAttribute("class", "subregion-header disp-flex");

  var nameDiv = document.createElement("div");

  var nameh2 = document.createElement("h2");
  nameh2.innerText = name;

  nameDiv.appendChild(nameh2);
  header.append(nameDiv);

  var emptyDiv = document.createElement("div");
  header.appendChild(emptyDiv);

  var populationDiv = document.createElement("div");
  var populationh2 = document.createElement("h3");
  populationh2.innerText = population;

  populationDiv.appendChild(populationh2);
  header.append(populationDiv);

  var areaDiv = document.createElement("div");
  var areah2 = document.createElement("h3");
  areah2.innerText = area;

  areaDiv.appendChild(areah2);
  header.append(areaDiv);

  li.appendChild(header);
  return li;
}

function createCountry(name, capital, area, population) {
  var country = document.createElement("li");
  country.setAttribute("class", "country disp-flex")

  var namediv = document.createElement("div");
  var nameh4 = document.createElement("h4");
  nameh4.innerText = name;
  namediv.appendChild(nameh4);
  country.appendChild(namediv);

  var capitaldiv = document.createElement("div");
  var capitalh4 = document.createElement("h4");
  capitalh4.innerText = capital;
  capitaldiv.appendChild(capitalh4);
  country.appendChild(capitaldiv);

  var popdiv = document.createElement("div");
  var poph4 = document.createElement("h4");
  poph4.innerText = population;
  popdiv.appendChild(poph4);
  country.appendChild(popdiv);

  var areadiv = document.createElement("div");
  var areah4 = document.createElement("h4");
  areah4.innerText = area;
  areadiv.appendChild(areah4);
  country.appendChild(areadiv);


  return country;
}

f(0);
*{
  transition: 500ms;

}
body {
  margin: 0 15%;
  min-height: 100vh;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: aliceblue;
  font-family: 'Open Sans', Arial;
  font-size: 18px;
}

#name {
  padding: 0 20px;
  background-color: rgb(219, 219, 219);
}

#capital {
  padding: 0 20px;
  background-color: rgb(219, 219, 219);
}

#population {
  padding: 0 20px;
  background-color: rgb(219, 219, 219);
}

#area {
  padding: 0 20px;
  background-color: rgb(219, 219, 219);
}

header {
  margin: 0 10%;
  display: flex;
  justify-content: space-between;
  padding: 22px 0;
  color: rgb(5, 5, 5);
}

ul {
  list-style: none;
  list-style-type: none;
  outline: 2px solid #ddd;
  padding: 1rem 2rem;
  border-radius: 0.5rem;
  list-style-position: inside;
  color: blue;
}

ul ol {
  color: rgb(197, 105, 18);
  list-style: none;
  list-style-type: none;
  font-size: .9em;
  margin: 0.4rem 0;
}

.country {
  display: flex;
  justify-content: space-between;
}

.disp-flex {
  display: flex;
  justify-content: space-between;
}

.disp-flex>div {
  width: 23%;
  padding: 15px 0px;
}


.subregion-header>div:nth-child(1) {
  position: relative;
  left: 30px;
}

.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  margin: 15px 2px;
}

.accordion li {
  list-style-type: none;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.panel {
  margin-left: 5%;
  display: none;
  background-color: white;
  overflow: hidden;
}

#name:hover {
  background-color: rgb(114, 114, 114);
  cursor: pointer;
}
#capital:hover {
  background-color: rgb(114, 114, 114);
  cursor: pointer;
}
#population:hover {
  background-color: rgb(114, 114, 114);
  cursor: pointer;
}
#area:hover {
  background-color: rgb(114, 114, 114);
  cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <main class="container">
        <header>
            <div id="name">
                <h1>Name</h1>
            </div>
            <div id="capital">
                <h1>Capital</h1>
            </div>
            <div id="population">
                <h1>Population</h1>
            </div>
            <div id="area">
                <h1>Area</h1>
            </div>

        </header>

      
      <div id="container"></div>
      <div id="subRegionWrapper"> </div>
      <div id="listWrapper"></div>
      <script src="script.js"></script>
    </main>
</body>

</html>

I made a little data-list containing some information about countries (names, capitals, areas and population), all the countries are grouped by sub-regions. In the header section I have four positions describing each column (name, capital, area and population). I want to add functionality of sorting, so that after clicking on position in the header section, the data would sort by that position. For example after clicking once on name, data should sort by name(asc or desc) and then after clicking once more on name, data should sort inversely to previous sort. I would like to allow sorting by couple columns at same time, so for example after clicking on capital and area, the data should be sorted by capitals and area. Here is my code:

I tried to do that sorting in different ways (adding extra function, passing parameter to main function etc.) but unfortunately nothing worked.I am really struggling with that, I will be extremely grateful for any help.

2
  • Please update your question with what "nothing worked" means - does the data not sort, does the UI not update, etc. Also provide some example data Commented Nov 22, 2022 at 21:17
  • @ChrisSc exactly data didn't and UI was not updated. I did what becauseimbored told me in the answer, but I still does not run perfectly, I also think that snippet of my code is now available Commented Nov 23, 2022 at 12:50

1 Answer 1

0

Your code is actually working, but you are not removing the old table. So the new sorted entries are appended to the already existing ones. You should clear the table some way, for example:

const container = document.getElementById('container');

var child = container.lastElementChild; 
while (child) {
    container.removeChild(child);
    child = container.lastElementChild;
}

Put this where you get the container in your function f(e) and it should be working

Sign up to request clarification or add additional context in comments.

1 Comment

Ok, I think I implemented it, though I am not quite sure if it works fine, countries and capitals do not sort properly, I don't know why. I will put updated code in my question above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.