<template>
  <div class="card">
    <img>
    <p class="country-location"></p>
    <p></p>
    <p></p>
  </div>
</template>
<header>
  <label><input type="checkbox" checked id="maison">maison</label>
  <label><input type="checkbox" checked id="appartement">appartement</label>
</header>
<main>
</main>
<footer>
</footer>
header, section, footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
label {
  margin: 0 20px;
}
.card {
  flex: 0 1 400px;
  border: 2px solid red;
  margin: 10px;
  padding: 10px;
  text-align: center;
}
img {
  width: 60%;
  aspect-ratio: 1;
  object-fit: cover;
}
.country-location {
  text-transform: uppercase;
  font-weight: bold;
}
button {
  margin: 3px;
}
const cardsPerSection = 3;

const template = document.querySelector("template");
const main = document.querySelector("main");
const footer = document.querySelector("footer");
var tsv; //tab separated variables

// read file from Dropbox . . .
async function getData() {
  try {
    const response = await fetch(
      "https://dl.dropboxusercontent.com/scl/fi/ta0b5mzbtumb5j2v7qp4r/properties.csv?rlkey=upol759f9pei5yp4ljcfrmvck&dl=0"
    );
    if (!response.ok) {
      throw new Error(`Response status: ${response.status}`);
    }
    tsv = await response.text();
    display(tsv);
  } catch (error) {
    //    alert(error.message);
  }
}

// create sections containing cards . . .
function display() {
  main.innerHTML = '<section id="s1"></section>'; // clear any content
  footer.innerHTML = "";
  const rows = tsv.split("\n");   // split by new line characters
  
  // variables in forEach loop below . . .
  let cells, clone, image, paragraph, type, checkbox, section;

  // for each property (maison or appartement) . . .
  rows.forEach((r, index) => {
    // first row is heading, last row is empty (for some reason)
    if (index > 0 && index < r.length) {
      cells = r.split("\t");  // split by tab characters
      type = cells[4].toLowerCase(); // type: maison or appartement (not displayed)
      checkbox = document.getElementById(type);
      if (checkbox && checkbox.checked) {
        // create new card . . . 
        clone = template.content.cloneNode(true);
        image = clone.querySelector("img");
        image.src = cells[5];
        paragraphs = clone.querySelectorAll("p");
        paragraphs[0].textContent = cells[0] + " " + cells[1];
        paragraphs[1].textContent = cells[2];
        paragraphs[2].textContent = cells[3] + "€";
        
        // determine if new section is needed . . .
        let numberInSection = main.lastElementChild.children.length;
        if (numberInSection > 0 && numberInSection%cardsPerSection == 0) {
          let section = document.createElement("section");
          section.style.display = "none";
          section.id = "s" + (main.children.length+1);
          main.appendChild(section);
        }

        main.lastElementChild.appendChild(clone);
      }
    }
  });

  // create buttons . . .
  let numberOfSections = main.children.length;
  // no buttons if only one section . . .
  if (numberOfSections > 1) {   
    for (let z = 0; z < numberOfSections; z++) {
      let b = document.createElement("button");
      b.innerText = (z + 1).toString();
      b.addEventListener("click", showSection);
      footer.appendChild(b);
    }
  }
}

// on button click . . .
function showSection() {
  let sections = document.querySelectorAll("section");
  sections.forEach((s) => {
    s.style.display = "none";
  });
  document.getElementById("s" + event.target.innerText).style.display = "flex";
}

//execute on page load . . .
getData();
document.querySelectorAll("input").forEach((c) => {
  c.addEventListener("click", display);
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.