0

I'm encoutered a problem, where I select value from dropdown list and it displays Londom time, from mainCities array. And it doesn't matter if I select other countries from the list, just 1 second it display the correct time, and the second it's back again on that Londom time.



let updateInterval;

let mainCities = [
  "Europe/Paris",
  "America/New_York",
  "Europe/London",
  "Europe/Vilnius",
];

const formatDate = function (city) {
  const now = moment().tz(city).format("MMMM Do, YYYY");
  return now;
};

const formatTime = function (city) {
  const now = moment.tz(city);
  const currTime = now.format("HH:mm:ss [<small>]A[</small>]");
  return currTime;
};

const formatCityName = function (city) {
  const name = moment().tz(city);
  const nameExtracted = name.tz();
  const showCityName = nameExtracted.split("/").slice(-1).join(" ");

  if (showCityName.includes("_")) {
    return showCityName.split("_").join(" ");
  }
  return showCityName;
};

function displaySelectInputs() {
  const cityNames = moment.tz.names();

  cityNames.forEach((city) => {
    const updatedName = city
      .split("/")
      .slice(-1)
      .join(" ")
      .replaceAll("_", " ");
    if (updatedName === "") return;

    const html = `
        <option value="${city}">${updatedName}</option>
    `;
    selectCityElement.insertAdjacentHTML("beforeend", html);
  });
}
displaySelectInputs();

const updateTime = function (cityName) {
  const cityTimeEl = document.querySelectorAll(".current-time");
  cityTimeEl.forEach((el, i) => {
    const city = cityName[i];
    const currentTime = formatTime(city);
    el.innerHTML = currentTime;
  });
};

const renderCityTimeData = function (cityName) {
  cityName.forEach(function (city) {
    const html = `
    <div class="city-container">
            <div class="city">
            <h3 class="city-name">${formatCityName(city)}</h3>
            <p class="date">${formatDate(city)}</p>
            </div>
            <div class="city-time">
            <p class="current-time"> 
            ${formatTime(city)}
            </p>
            </div>
            </div>
            `;
    citiesContainer.insertAdjacentHTML("beforeend", html);
  });
  updateInterval = setInterval(updateTime, 1000, mainCities);
};

renderCityTimeData(mainCities);

const updateSelectElement = function (e) {
  const city = e.target.value;
  const cityRowContainer = document.querySelectorAll(".city-container");
  console.log(city);

  if (!city) return;

  cityRowContainer.forEach((el) => {
    if (city) el.style.display = "none";
  });
  const html = `
    <div class="city-container">
    <div class="city">
    <h3 class="city-name">${formatCityName(city)}</h3>
    <p class="date">${formatDate(city)}</p>
    </div>
    <div class="city-time">
    <p class="current-time">
    ${formatTime(city)}
    </p>
    </div>
   </div>`;

  clearInterval(updateInterval);

  updateInterval = setInterval(updateTime, 1000, [city]);
  citiesContainer.insertAdjacentHTML("beforeend", html);
};
selectCityElement.addEventListener("change", updateSelectElement);

I tried to set display: none, to a first 4 initial values after I select an element from the list, but I don't understand why the time doesn't update along with name or date data.

A-Renata
  • 1
  • 1

1 Answers1

0

const timeZoneToCityName = (timezone) => {
  return timezone
    .split("/")
    .slice(-1)
    .join(" ")
    .replaceAll("_", " ");
}



const updateSelectElement = function (e) {
  const momentTimeZone = document.getElementById('cities').value;

  if (!momentTimeZone) return;

  const citiesContainer = document.querySelector(".city-container");
  citiesContainer.innerHTML = "";


  clearInterval(updateInterval);
  insertCityTimeData(momentTimeZone, citiesContainer);
  updateInterval = setInterval(updateTime, 1000, [momentTimeZone]);
};



const updateTime = function (cityName) {
  const cityTimeEl = document.querySelectorAll(".current-time");
  cityTimeEl.forEach((el, i) => {
    const city = cityName[i];
    const currentTime = formatTime(city);
    el.innerHTML = currentTime;
  });
};



const formatDate = function (timezone) {
  const now = moment().tz(timezone).format("MMMM Do, YYYY");
  return now;
};

const formatTime = function (timezone) {
  const now = moment.tz(timezone);
  const currTime = now.format("HH:mm:ss [<small>]A[</small>]");
  return currTime;
};

const formatCityName = function (timezone) {
  const name = moment().tz(timezone);
  const nameExtracted = name.tz();
  const showCityName = timeZoneToCityName(nameExtracted);

  return showCityName;
};


const insertCityTimeData = (timeZone, citiesContainer) => {
  const html = `
      <div class="city">
        <h3 class="city-name">${formatCityName(timeZone)}</h3>
        <p class="date">${formatDate(timeZone)}</p>
        <p class="current-time">${formatTime(timeZone)}</p>
      </div>
    `;
  citiesContainer.insertAdjacentHTML("beforeend", html);
}


const renderCityTimeData = function (defaultTimeZones) {
  const citiesContainer = document.querySelector('.city-container')
  defaultTimeZones.forEach(function (timezone) {
    insertCityTimeData(timezone, citiesContainer)
  });
  updateInterval = setInterval(updateTime, 1000, defaultTimeZones);
};


function populateCityDropdown() {

  function getOptionElem(city, updatedName) {
    let option = document.createElement('option')
    option.value = city;
    option.text = updatedName

    return option;
  }

  const cityNames = moment.tz.names();
  cityNames.forEach((city) => {
    const updatedName = timeZoneToCityName(city)
    if (updatedName === "") return;

    let option = getOptionElem(city, updatedName)
    selectCityElement.appendChild(option);
  });
}

let selectCityElement = document.getElementById('cities');

let updateInterval;

let mainCities = [
  "Europe/Paris",
  "America/New_York",
  "Europe/London",
  "Europe/Vilnius",
];

populateCityDropdown();
renderCityTimeData(mainCities);

selectCityElement.addEventListener("change", updateSelectElement);
<!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" />
  <link rel="stylesheet" href="src/styles.css" />
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,400;0,600;1,400&display=swap" rel="stylesheet" />
  <script defer src="scripts.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

  <script src="https://momentjs.com/downloads/moment-timezone-with-data-1970-2030.min.js"></script>
  <title>World clock</title>
</head>

<body>
  <div class="container">
    <h1>World Clock</h1>
    <select name="cities" id="cities">
      <option value="">Select a city</option>
    </select>

    <div class="city-container">

    </div>
  </div>
</body>

</html>

There was a Lot of changes, but this code should work as intended

Balaji
  • 795
  • 1
  • 2
  • 10