How to create a JavaScript object dynamically whose value is a function

I need a method that creates a Quasar Table column definition dynamically. The method below works, however, I believe that using a for loop in place of the long switch statement is a better solution.

How do I write a for loop that produces the same result as the following:

const createTableColumns = (numberOfColumns: number) => {
  const tableCols: QTableProps["columns"] = [];
  const numberOfColumnsStr = numberOfColumns.toString();

  switch (numberOfColumnsStr) {
    case "15":
      tableCols.push({
        name: "15",
        align: "center",
        label: "15",
        field: (row) => row.fifteen.value,
        format: (val, row) =>
          row.fifteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "14":
      tableCols.push({
        name: "14",
        align: "center",
        label: "14",
        field: (row) => row.fourteen.value,
        format: (val, row) =>
          row.fourteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "13":
      tableCols.push({
        name: "13",
        align: "center",
        label: "13",
        field: (row) => row.thirteen.value,
        format: (val, row) =>
          row.thirteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "12":
      tableCols.push({
        name: "12",
        align: "center",
        label: "12",
        field: (row) => row.twelve.value,
        format: (val, row) =>
          row.twelve.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "11":
      tableCols.push({
        name: "11",
        align: "center",
        label: "11",
        field: (row) => row.eleven.value,
        format: (val, row) =>
          row.eleven.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "10":
      tableCols.push({
        name: "10",
        align: "center",
        label: "10",
        field: (row) => row.ten.value,
        format: (val, row) => (row.ten.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "9":
      tableCols.push({
        name: "9",
        align: "center",
        label: "9",
        field: (row) => row.nine.value,
        format: (val, row) => (row.nine.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "8":
      tableCols.push({
        name: "8",
        align: "center",
        label: "8",
        field: (row) => row.eight.value,
        format: (val, row) => (row.eight.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "7":
      tableCols.push({
        name: "7",
        align: "center",
        label: "7",
        field: (row) => row.seven.value,
        format: (val, row) => (row.seven.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "6":
      tableCols.push({
        name: "6",
        align: "center",
        label: "6",
        field: (row) => row.six.value,
        format: (val, row) => (row.six.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "5":
      tableCols.push({
        name: "5",
        align: "center",
        label: "5",
        field: (row) => row.five.value,
        format: (val, row) => (row.five.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "4":
      tableCols.push({
        name: "4",
        align: "center",
        label: "4",
        field: (row) => row.four.value,
        format: (val, row) => (row.four.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "3":
      tableCols.push({
        name: "3",
        align: "center",
        label: "3",
        field: (row) => row.three.value,
        format: (val, row) => (row.three.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });

    case "2":
      tableCols.push({
        name: "2",
        align: "center",
        label: "2",
        field: (row) => row.two.value,
        format: (val, row) => (row.two.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });

    case "1":
      tableCols.push({
        name: "1",
        align: "center",
        label: "1",
        field: (row) => row.name,
        format: (val, row) => `${val}`,
        sortable: false,
      });

      break;
    default:
      console.error(`Game: createTableColumns DEFAULT!!!`);
  }

  tableCols.sort((a, b) => parseInt(a.name) - parseInt(b.name));
  return tableCols;
};

I’ve tried this:

const tableCols2: QTableProps["columns"] = [];
for (let colIndex = 0; colIndex < numberOfColumns; colIndex++) {
  const rowKeyArray = [
    "NotUsed",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "fifteen",
  ];
  const colNumber: number = colIndex + 1;
  const rowKey: string = rowKeyArray[colIndex];
  const myObj = {
    name: colNumber.toString(),
    align: "center",
    label: colNumber.toString(),
    field: (row) => row[rowKey].value,
    format: (val, row) => (row[rowKey].isSlected ? `** ${val} **` : `${val}`),
    sortable: false,
  };

  tableCols2.push(myObj);
}

The curtain fails to rise when the ‘X’ button is clicked

I was told this:

In your showContainer function, you are trying to add the slide class
to the container element when the animation of the spinner ends.
However, the slide class is supposed to transition the container
upwards, but it seems it’s not being applied correctly.

It should work the same way as:

How this one works:

window.onload = function() {
  const container = document.querySelector(".video-containerA");
  const spinner = document.querySelector(".spinner");
  const exitButton = document.querySelector(".exitA");

  spinner.addEventListener("animationend", function() {
    container.classList.add("slide");
  });

  container.addEventListener("transitionend", function() {
    exitButton.classList.add("visible");
  });
};

After clicking the exit button the curtain should go up.

After it is up, exit button should be visible

**How do I fix this?

I am confused here.

The curtain is not going up.

I don’t understand, it should be working.

/*global YT */
/*jslint browser:true */
/*jslint devel: true */
window.onload = function() {
  const container = document.querySelector(".video-containerA");
  const spinner = document.querySelector(".spinner");
  const exitButton = document.querySelector(".exitA");

  spinner.addEventListener("animationend", function() {
    container.classList.add("slide");
  });

  container.addEventListener("transitionend", function() {
    exitButton.classList.add("visible");
  });
};

const videoPlayer = (function makeVideoPlayer() {
  const players = [];
  const tag = document.createElement("script");
  tag.src = "https://www.youtube.com/player_api";
  const firstScriptTag = document.getElementsByTagName("script")[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  function shufflePlaylist(player, shuffle) {
    player.setShuffle(shuffle);
    player.playVideoAt(0);
    player.stopVideo();
  }

  function onPlayerReady(event) {
    const player = event.target;
    player.setVolume(100);
    const isShuffle = player.getIframe().dataset.shuffle === "true";
    shufflePlaylist(player, isShuffle);
  }

  function addPlayer(video, playerOptions) {
    playerOptions.playerVars = playerOptions.playerVars || {};
    video.dataset.shuffle = playerOptions.shuffle;
    playerOptions.events = playerOptions.events || {};
    playerOptions.events.onReady = onPlayerReady;
    players.push(new YT.Player(video, playerOptions));
  }

  function destroyPlayers() {
    players.forEach(function(player) { // Use player array here
      const playerElement = player.getIframe();
      if (playerElement) {
        const playerClass = playerElement.className;
        console.log("Destroying player with class: " + playerClass);
        player.destroy();
      }
    });
    console.log("playerRemoved");
  }

  return {
    addPlayer,
    destroyPlayers
  };
}());

const managePlayer = (function makeManagePlayer() {
  const playerVars = {
    autoplay: 0,
    controls: 0,
    disablekb: 1,
    fs: 0,
    iv_load_policy: 3
  };
  const defaults = {
    height: 360,
    host: "https://www.youtube-nocookie.com",
    playerVars,
    width: 640
  };

  function combinePlayerOptions(opts1 = {}, opts2 = {}) {
    const combined = Object.assign({}, opts1, opts2);
    Object.keys(opts1).forEach(function checkObjects(prop) {
      if (typeof opts1[prop] === "object") {
        combined[prop] = Object.assign({}, opts1[prop], opts2[prop]);
      }
    });
    return combined;
  }

  function createPlayer(videoWrapper, playerOptions = {}) {
    const video = videoWrapper.querySelector(".video");
    const options = combinePlayerOptions(defaults, playerOptions);
    return videoPlayer.addPlayer(video, options);
  }

  function playerAdder(wrapper, playerOptions) {
    return function addPlayerCallback() {
      initPlayer(wrapper, playerOptions);
    };
  }

  function initPlayer(wrapper, playerOptions) {
    createPlayer(wrapper, playerOptions);
  }
  return {
    adder: playerAdder
  };
}());

const players = (function uiLoadPlayer() {
  function addPlayer(playerSelector, playerOptions) {
    const parent = document.querySelector(playerSelector).parentElement;
    const callback = managePlayer.adder(parent, playerOptions);
    callback();
  }

  return {
    add: addPlayer
  };
}());

function onYouTubeIframeAPIReady() {
  // Initialize the first player
  players.add(".playA", {
    playerVars: {
      list: "PL2pth5aaj4xrQ3dTg3tbTKnO4LtCOuf3l",
      listType: "playlist"
    },
    shuffle: true
  });
}

(function manageExitA() {
  function hideContainer(containerSelector) {
    const container = document.querySelector(containerSelector);
    container.classList.add("hide");
  }

  function showContainer(containerSelector, spinnerSelector, exitSelector) {
    const container = document.querySelector(containerSelector);
    const exitButton = document.querySelector(exitSelector);

    container.classList.remove("hide");

    const spinner = document.querySelector(spinnerSelector);
    spinner.addEventListener("animationend", function() {
      container.classList.add("slide");
    });

    container.addEventListener("animationend", function() {
      exitButton.classList.add("visible");
    });
  }

  function removePlayer() {
    videoPlayer.destroyPlayers();
  }

  function resetPage() {
    hideContainer(".video-containerA");
    showContainer(".video-containerB", ".spinner", ".exitB");
    removePlayer();
  }

  function exitClickHandler() {
    resetPage();
    players.add(".playB", {
      playerVars: {
        list: "PL2pth5aaj4xrQ3dTg3tbTKnO4LtCOuf3l",
        listType: "playlist",
        loop: 0
      }
    });
  }
  const exit = document.querySelector(".exitA");
  exit.addEventListener("click", exitClickHandler);
}());

(function manageExitB() {
  function hideContainer(containerSelector) {
    const container = document.querySelector(containerSelector);
    container.classList.add("hide");
  }

  function showContainer(containerSelector, exitSelector) {
    const container = document.querySelector(containerSelector);
    const exitButton = document.querySelector(exitSelector);
    container.classList.remove("hide");
    container.classList.add("slide");
    container.addEventListener("animationend", function() {
      exitButton.classList.add("visible");
    });
  }

  function removePlayer() {
    videoPlayer.destroyPlayers();
  }

  function resetPage() {
    hideContainer(".video-containerB");
    showContainer(".video-containerC", ".exitC");
    removePlayer();
  }

  function exitClickHandler() {
    resetPage();
    players.add(".playC", {
      playerVars: {
        list: "PL2pth5aaj4xrQ3dTg3tbTKnO4LtCOuf3l",
        listType: "playlist"
      },
      shuffle: true
    });
  }

  const exit = document.querySelector(".exitB");
  exit.addEventListener("click", exitClickHandler);
}());
html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: #121212;
  padding: 0 8px 0;
}

body:has(.modal.active) {
  overflow: hidden;
}

button,
a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

.outer-containerA {
  background: #15202b;
}

.outer-containerA,
.outer-containerB,
.modal {
  display: flex;
  position: fixed;
  inset: 0;
  overflow: auto;
  /* Enable scroll if needed */
}

.video-containerA,
.video-containerB,
.video-containerC {
  flex: 1 0 0;
  margin: auto;
  max-width: 640px;
  position: relative;
}

.ratio-keeper {
  height: 0;
  padding-top: 56.25%;
  overflow: hidden;
  position: relative;
  background: #000;
}

.ratio-keeper iframe {
  /*position: absolute;
  top: 0;
  left: 0;*/
  width: 100%;
  height: 100%;
}

.ratio-keeper iframe,
.curtain {
  position: absolute;
  inset: 0;
}



.curtain {
  /*position: absolute;
  height: 100%;
  width: 100%;
  inset:0;*/
  --wide: 8.8%;
  --angle1: 0;
  --angle2: -90;
  background: repeating-linear-gradient(calc(var(--angle1) * 1deg),
      #ffffff00 0,
      #ffffff00 var(--wide),
      #ffffff1a calc(var(--wide) + 1px),
      #0000004d calc(var(--wide) + 2px),
      #ffffff00 calc(var(--wide) + 5px)),
    repeating-linear-gradient(calc(calc(var(--angle2) + 90) * 1deg),
      #ffffff00 0,
      #ffffff00 var(--wide),
      #ffffff1a calc(var(--wide) + 1px),
      #0000004d calc(var(--wide) + 2px),
      #ffffff00 calc(var(--wide) + 5px));
  background-color: #222;
  border-bottom: 2px solid #191919;
  background-repeat: no-repeat;
  overflow: hidden;
}

.spinner {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  inset: 0;
  margin: auto;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  cursor: pointer;
  border: 9px solid;
  background: transparent;
  filter: drop-shadow(3px 3px 3px #000000b3);
  pointer-events: none;
}

.spinner {
  animation: rotate 2s linear forwards, fadeOut 1s 2s forwards;
  border-color: red transparent red transparent;
}

@keyframes rotate {
  50% {
    transform: rotate(360deg);
    border-color: red transparent red transparent;
  }

  100% {
    transform: rotate(720deg);
    border-color: red transparent red transparent;
  }
}

@keyframes fadeOut {
  to {
    opacity: 0;
  }
}

.video-containerA.slide .curtain {
  transition: 8s ease-in-out;
  transition-delay:1s;
  transform: translateY(-100%);
}

@keyframes slide {
  to {
    transform: translateY(-100%);
  }
}

.video-containerB.slide .curtain,
.video-containerC.slide .curtain {
  animation: slide 8s ease-in-out forwards;
  
}

.outer-containerB {
  display: flex;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow: auto;
}

.containerB,
.containerC {
  margin: auto;
}

.buttonContainerA,
.buttonContainerB {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 569px;
  gap: 10px;
}

.playButton,
.linkButton {
  flex-basis: 183px;

  /* 
  width of each button */
  margin: 0;

  /* 
  spacing between buttons */
  cursor: pointer;
}

.modal {
  display: flex;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow: auto;
  /*background: rgba(0, 0, 0, 0.4);*/
  transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;
  transform: translate(0, -25%);
  opacity: 0;
  pointer-events: none;
  z-index: -99;
  border-radius: 50%;
  --units: 8px;
  --brick1: #222;
  --brick2: #222;
  --lines: #121212;
  --gp-ln: 50%/calc(var(--units) * 10) calc(var(--units) * 5);
  --gp-cn: 50%/calc(var(--units) * 5) calc(var(--units) * 5);
  background:
    repeating-conic-gradient(from 90deg at 95% 55%, var(--lines) 0% 25%, #fff0 0% 100%) var(--gp-cn),
    repeating-linear-gradient(180deg, var(--lines) 0 5%, #fff0 0 50%, var(--lines) 0 55%, var(--brick2) 0 100%) var(--gp-ln),
    repeating-linear-gradient(90deg, var(--brick1) 0 47.5%, var(--lines) 0 50%, var(--brick1) 0 97.5%, var(--lines) 0 100%) var(--gp-ln);
}

.modal.active {
  opacity: 1;
  transform: scale(1);
  z-index: 1000;
  pointer-events: initial;
  border-radius: 0;
  overflow: auto;
  padding: 8px 8px;
}

.inner-modal {
  position: relative;
  margin: auto;
}

.btnA-primary {
  color: #fff;
  background-color: #0d6efd;
  border-color: #0d6efd;
}

.btnA,
.btnB {
  display: inline-block;
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  background-color: #0d6efd;
  border: 1px solid transparent;
  box-sizing: border-box;
  padding: 6px 12px;
  font-size: 16px;
  border-radius: 4px;
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
  font-family: "Poppins", sans-serif;
  font-weight: 500;
  font-style: normal;
}

.btnA:hover {
  background-color: #0056b3;
  border-color: #0a58ca;
  color: #ffffff;
}

.played {
  border-color: #0a58ca;
  background-color: #0056b3;
  box-shadow: 0 0 0 2px rgb(255 0 0);
}

.btnB-primary {
  color: #2fdcfe;
  background-color: #000000;
  border-color: #2fdcfe;
}

.btnB {
  border: 1px solid #2fdcfe;
}

.btnB:hover {
  background-color: #121212;
}

/*.btnA:focus,*/
.btnB:focus {
  outline: 0;
  box-shadow: 0 0 0 2px rgba(47 254 185 / 100%);
}

.exitA,
.exitB,
.exitC {
  transform: translateY(100%);
  position: absolute;
  inset: auto 0 -6px 0;
  /*top: auto;
  bottom: -6px;*/
  margin: auto;
  /*8right: 0;
  left: 0;*/
  width: 47px;
  height: 47px;
  background: black;
  border-radius: 50%;
  border: 5px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 2s ease-in;
  transition-delay: 1s;
  pointer-events: none;
}

.exitA::before,
.exitA::after,
.exitB::before,
.exitB::after,
.exitC::before,
.exitC::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 5px;
  background: red;
  transform: rotate(45deg);
}

.exitA::after,
.exitB::after,
.exitC::after {
  transform: rotate(-45deg);
}

.exitA.visible,
.exitB.visible,
.exitC.visible {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

.exitD,
.close {
  position: absolute;
  margin: 6px auto 0;
  left: 0;
  right: 0;
  width: 47px;
  height: 47px;
  background: black;
  border-radius: 50%;
  border: 5px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.exitD::before,
.exitD::after,
.close::before,
.close::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 5px;
  background: red;
  transform: rotate(45deg);
}

.exitD::after,
.close::after {
  transform: rotate(-45deg);
}

.containerC {
  margin: auto;
  background: none;

  /*
  teal */
}

.flex {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: none;
}

.blue-margin-bottom {
  margin-bottom: 16px;
  background: none;
}

.orange-margin {
  margin-left: 12px;
  margin-right: 12px;
  background: none;
}

.title-text {
  margin: 0;
  color: #0059dd;
  font-size: 20px;
  line-height: 1.5;
  text-overflow: ellipsis;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  font-family: "Karla", sans-serif;
  font-weight: 700;
  font-style: normal;
}

.yellow-padding-margin {
  margin-top: 4px;
  padding-left: 40px;
  padding-right: 40px;
  background: none;
}

.center-text {
  padding: 0;
  margin: 0;
  text-align: center;
  color: #0059dd;
  font-size: 16px;
  line-height: 1.5;
  overflow-wrap: normal;
  font-family: "Karla", sans-serif;
  font-weight: 500;
  font-style: normal;
  background: none;
}

.exitE {
  position: relative;
  margin: 7px auto 0;
  inset: 0 0 0 0;
  width: 47px;
  height: 47px;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  background: black;
  border-radius: 50%;
  border: 5px solid #0059dd;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.exitE::before,
.exitE::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 5px;
  background: #0059dd;
  transform: rotate(45deg);
}

.exitE::after {
  transform: rotate(-45deg);
}

.my-footer {
  box-sizing: border-box;
  border-top: 1px solid #1155cc;
  background: #121212;
  text-align: center;
  word-wrap: break-word;
  padding: 22px 8px 0;
  font-family: Verdana, Arial, sans-serif;
  font-size: 13.33px;
  line-height: 1.5;
  vertical-align: baseline;
  margin-top: auto;
}

.margin-top {
  margin-top: 10px;
}

.my-footer a {
  text-decoration: none;
}

.divider::before,
.divider::after {
  content: "";
  position: relative;
  top: 4px;
  margin: 0 7.4px;
  border: none;
  height: 12px;
  border-left: 1px solid #f6b26b;
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 0 13px;
  padding: 0;
  list-style: none;
}

.footer-top li {
  display: flex;
}

.footer-top a {
  color: #0059dd;
  font-weight: 700;
}

.my-footer .green-text {
  color: #38761d;
  font-weight: 400;
}

.orange-text {
  color: #b45f06;
  font-weight: 700;
}

.footer-mid {
  margin-bottom: 49px;
  color: #0059dd;
  font-family: Arial, sans-serif;
  font-size: 24px;
  font-weight: 700;
}

.footer-base {
  color: #0059dd;
  padding: 0;
}

.outer-containerA.hide,
.video-containerA.hide,
.video-containerB.hide,
.video-containerC.hide,
.outer-containerB.hide,
.containerB.hide,
.containerC.hide {
  display: none;
}
<div class="outer-containerA">
  <div class="video-containerA">
    <button class="exitA" type="button" title="Exit" aria-label="Exit"></button>
    <div class="ratio-keeper ">
      <div class="video playA"></div>
      <div class="curtain "></div>
       
    </div>
    <div class="playA"></div>
   <div class="spinner"></div>
  </div>
  <div class="video-containerB hide">
    <button class="exitB" type="button" title="Exit" aria-label="Exit"></button>
    <div class="ratio-keeper">
      <div class="video playB"></div>
      <div class="curtain"></div>
    </div>
    <div class="playB"></div>
     <div class="spinner"></div>
  </div>
  <div class="video-containerC hide">
    <button class="exitC" type="button" title="Exit" aria-label="Exit"></button>
    <div class="ratio-keeper">
      <div class="video playC"></div>
      <div class="curtain"></div>
    </div>
    <div class="playC"></div>
    <div class="spinner"></div>
  </div>
</div>

Is there a way to create vertical fixed sections like this in CSS/JS? [closed]

I’m trying to create a similar layout where each section shows up with scroll. Is there a way to create this with CSS/JS?

https://www.youtube.com/watch?v=LF7K2zuh-H8

I tried using position fixed and sticky for sections to make this work, but it doesn’t seem to be working.

A wavelike design appears to be flowing across the canvas from left to right. At its heart lies another small cloud, indicating some kind of technological feature or product.

.scroll_container {
  margin-top: 2800px;
  height: 1200px;
  margin-left: 20%;
  position: relative;
  overflow: hidden;
}

.scroll_container div {
  position: sticky;
  position: -webkit-sticky;
  width: 800px;
  height: 400px;
}

.scroll_1 {
  background: orange;
  top: 0px;
}

.scroll_2 {
  top: 400px;
  background: turquoise;
  z-index: 10;
}

.scroll_3 {
  top: 800px;
  background: teal;
  z-index: 20;
}
<div class="scroll_container">
  <div class="scroll_1">
    A wavelike design appears to be flowing across the canvas from left to right. At its heart lies another small cloud, indicating some kind of technological feature or product. -
  </div>

  <div class="scroll_2">
    A wavelike design appears to be flowing across the canvas from left to right. At its heart lies another small cloud, indicating some kind of technological feature or product. -
  </div>

  <div class="scroll_3">
    A wavelike design appears to be flowing across the canvas from left to right. At its heart lies another small cloud, indicating some kind of technological feature or product. -
  </div>
</div>

Vitest giving syntaxerror

I am using vitest to run my ReactComponent tests.

import { render, screen } from '@testing-library/react';
import { Calc } from '../features/explore/Calc';

describe('calc tests', () => {


   it('should render calculator screen', () => {
     const { getByTestId } = render(<Calc />);

     expect(getByTestId('calc-title').textContent).toBe('Calculator');
   });

});

This is the vite.config.ts

import * as path from 'node:path';
import { defineConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
   plugins: [tsconfigPaths()],

   test: {
      globals: true,
      environment: 'jsdom',
      setupFiles: [
        require.resolve('dotenv-mono/load'),
        path.resolve(__dirname, '__tests__/setupTests.ts'),
      ],
   include: ['**/*.test.{ts,tsx}'],},
});

How to resolve this issue ?

it gives error as :
FAIL tests/ExplorePage.test.tsx [ tests/ExplorePage.test.tsx ]
app:test:unit: SyntaxError: Named export ‘ScrollView’ not found. The requested module ‘react-native’ is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from ‘react-native’;
const { ScrollView: ScrollViewNative } = pkg;

I am not using ScrollView in my component directly.

How to make XAxis less crowded and not display all dates on spline chart using highcharts

I have a spline chart that is generated with Highcharts. How to make the x-axis less crowded? This is a month’s worth of data. Sometimes the data can be more than that. On the x-axis, sow only few dates rather than all of them.

My code:

Highcharts.chart('container', {
  "chart": {
    "backgroundColor": "#000",
    "type": "spline",
    "zoomType": "x"
  },
  "accessibility": {
    "enabled": false
  },
  "credits": {
    "enabled": false
  },
  "legend": {
    "enabled": true,
    "itemStyle": {
      "color": "#ffffff"
    }
  },
  "rangeSelector": {
    "enabled": false
  },
  "navigator": {
    "enabled": false
  },
  "scrollbar": {
    "enabled": false
  },
  "xAxis": {
    "categories": ["Apr 2, 2024", "Apr 3, 2024", "Apr 4, 2024", "Apr 5, 2024", "Apr 6, 2024", "Apr 7, 2024", "Apr 8, 2024", "Apr 9, 2024", "Apr 10, 2024", "Apr 11, 2024", "Apr 12, 2024", "Apr 13, 2024", "Apr 14, 2024", "Apr 15, 2024", "Apr 16, 2024", "Apr 22, 2024", "Apr 17, 2024", "Apr 26, 2024", "Apr 27, 2024", "Apr 29, 2024", "Apr 30, 2024"],
    "labels": {
      "style": {
        "color": "#ffffff"
      }
    },
    "lineColor": "#ffffff",
    "lineWidth": 3
  },
  "yAxis": [{
    "gridLineColor": "#000",
    "lineColor": "#fff",
    "lineWidth": 3,
    "labels": {
      "style": {
        "color": "#fff"
      }
    },
    "title": {
      "text": ""
    },
    "opposite": false
  }, {
    "title": {
      "text": "",
      "color": "#fff"
    },
    "opposite": true,
    "gridLineColor": "#000",
    "lineColor": "#fff",
    "lineWidth": 3,
    "labels": {
      "style": {
        "color": "#fff"
      }
    }
  }],
  "tooltip": {
    "backgroundColor": "#283347",
    "style": {
      "color": "#fff"
    },
    "shared": true,
    "useHTML": true
  },
  "plotOptions": {
    "series": {
      "fillOpacity": 0,
      "marker": {
        "enabled": false,
        "states": {
          "hover": {
            "enabled": true
          }
        }
      }
    }
  },
  "series": [{
    "name": "visits",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 2182294
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 2139585
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 2104361
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 2202831
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 2180398
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 2231004
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 2187912
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 2203672
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 2186452
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 2187167
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 2248419
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 2423452
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 2499690
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 2402717
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 2397309
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 2393551
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 3348
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 4419054
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 2278264
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 2229568
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 2293853
    }],
    "color": "#DA70D6",
    "yAxis": 0
  }, {
    "name": "return_visits",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 1720977
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 1698864
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 1677394
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 1749105
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 1718534
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 1752510
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 1743050
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 1738325
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 1721808
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 1733612
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 1762564
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 1907262
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 1916476
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 1882079
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 1846960
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 1827737
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 1831
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 3565753
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 1801874
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 1776895
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 1761887
    }],
    "color": "#FFD700",
    "yAxis": 0
  }, {
    "name": "unique_visitors",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 1578941
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 1544172
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 1517705
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 1603987
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 1588428
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 1615074
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 1573398
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 1612672
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 1590694
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 1576982
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 1598907
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 1698120
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 1793186
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 1702037
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 1721280
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 1735671
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 2691
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 3124829
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 1640897
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 1566275
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 1651959
    }],
    "color": "#6B8E23",
    "yAxis": 0
  }, {
    "name": "article_views",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 863219
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 834750
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 787435
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 857901
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 855943
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 871373
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 849347
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 874912
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 893765
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 878446
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 948741
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 938141
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 938447
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 971806
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 1005188
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 1062300
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 2583
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 1725505
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 937386
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 856214
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 969535
    }],
    "color": "#FF7F50",
    "yAxis": 0
  }, {
    "name": "audio_play",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 158735
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 166061
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 148663
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 133487
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 136010
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 160773
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 162092
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 153291
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 157931
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 145839
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 140483
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 170573
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 177091
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 180538
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 171497
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 180906
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 395
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 269944
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 141954
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 155965
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 153210
    }],
    "color": "#20B2AA",
    "yAxis": 0
  }, {
    "name": "video_play",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 479844
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 495244
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 553062
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 445209
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 406745
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 452514
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 447724
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 435157
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 482781
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 478997
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 529373
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 783667
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 808305
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 660943
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 620450
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 497454
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 13202
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 873312
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 514325
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 551823
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 532816
    }],
    "color": "#FF8C00",
    "yAxis": 0
  }, {
    "name": "time_spent_per_visit",
    "data": [{
      "name": "Apr 2, 2024 8:00 PM",
      "y": 298753508
    }, {
      "name": "Apr 3, 2024 8:00 PM",
      "y": 295428214
    }, {
      "name": "Apr 4, 2024 8:00 PM",
      "y": 289698259
    }, {
      "name": "Apr 5, 2024 8:00 PM",
      "y": 281628634
    }, {
      "name": "Apr 6, 2024 8:00 PM",
      "y": 276325393
    }, {
      "name": "Apr 7, 2024 8:00 PM",
      "y": 298815690
    }, {
      "name": "Apr 8, 2024 8:00 PM",
      "y": 300802278
    }, {
      "name": "Apr 9, 2024 8:00 PM",
      "y": 287960174
    }, {
      "name": "Apr 10, 2024 8:00 PM",
      "y": 299063477
    }, {
      "name": "Apr 11, 2024 8:00 PM",
      "y": 311131007
    }, {
      "name": "Apr 12, 2024 8:00 PM",
      "y": 310822626
    }, {
      "name": "Apr 13, 2024 8:00 PM",
      "y": 347487659
    }, {
      "name": "Apr 14, 2024 8:00 PM",
      "y": 356177362
    }, {
      "name": "Apr 15, 2024 8:00 PM",
      "y": 340235250
    }, {
      "name": "Apr 16, 2024 8:00 PM",
      "y": 330655491
    }, {
      "name": "Apr 22, 2024 8:00 PM",
      "y": 322284004
    }, {
      "name": "Apr 17, 2024 8:00 PM",
      "y": 767692
    }, {
      "name": "Apr 26, 2024 8:00 PM",
      "y": 590347951
    }, {
      "name": "Apr 27, 2024 8:00 PM",
      "y": 292822482
    }, {
      "name": "Apr 29, 2024 8:00 PM",
      "y": 311850281
    }, {
      "name": "Apr 30, 2024 8:00 PM",
      "y": 301374165
    }],
    "color": "#ff0000",
    "yAxis": 1
  }]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>

<figure class="highcharts-figure">
    <div id="container"></div>
   
</figure>

Here is the link to the fiddle: https://jsfiddle.net/nb_nb_nb/a6w2hntx/2/

PDF does not display on mobile device within a modal

On PC it works correctly, but when I try it on mobile I only get a button with the text “Open” but when I press it nothing happens.

I’ve already tried it in several browsers and they all give the same result.

This is the function I use:

async function frmMostrar(idPDF){
    $(cargador__).attr('style', 'display: flex;');
    await fetch(`/obtenerInformeFinalDrive`, {
        method: 'POST',
        body: JSON.stringify({ idPDF: idPDF }),
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": xcsrftoken_ },
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('No se pudo recuperar el PDF');
        }
        return response.blob();
    })
    .then(responseBlob => {
        const reader = new FileReader();
        reader.onload = () => {
            const byteArray = new Uint8Array(reader.result);
            const pdfBlob = new Blob([byteArray], { type: 'application/pdf' });
            const pdfUrl = URL.createObjectURL(pdfBlob);

            const iframe = document.createElement('iframe');
            iframe.src = pdfUrl;
            iframe.height = '100%';
            iframe.width = '100%';

            if (!alertify.modal_informe_final) {
                alertify.dialog("modal_informe_final", function() {
                    return {
                        main: function(message) {
                            this.message = message;
                        },
                        prepare: function() {
                            this.setContent(this.message);
                        }
                    };
                });
            }
            const modal = alertify.modal_informe_final(iframe).set({ onclosing:function(){}}).set({title: 'Informe final'}).maximize();
            const modalContainer = modal.elements.modal;
            modalContainer.classList.add('modal_informe_final');
        };
        reader.readAsArrayBuffer(responseBlob);
    })
    .catch(error => {
        console.error('Error al recuperar PDF:', error);
    });
    $(cargador__).attr('style', 'display: none;');
}

Movil :

enter image description here

PC:

enter image description here

Problems with flask and javascript

the idea is when you click in the button of an actuador , it will send a message to the microcontroller to activate or deactivate a switch. The thing is that when I click on the actuador to send the MQTT message the following error appears:

Enviando comando al actuador 3: 1
1:954 Body being sent: {"mensaje":"1"}
1:955 1
1:956 
        
        
       POST http://127.0.0.1:5001/enviar_comando_actuador/3 400 (BAD REQUEST)
toggleSwitch @ 1:956
onclick @ 1:370
1:963 Response status: 400
1:979 Error al enviar comando al actuador: Error: HTTP status 400
    at 1:965:19

I have this html code:

{% for actuador in actuadores %}
  <div class="elemento">
    {% if actuador.tipo == 'switch' %}
    <button class="switch-button" id="switch_{{ actuador.id }}" 
    data-actuador-id="{{ actuador.id }}" 
    data-state="{{ actuador.estado_actual }}" 
    onclick="toggleSwitch(this)"
    style="background-color: {{ 'green' if actuador.estado_actual == '1' else 'red' }}">
        <span>{{ actuador.nombre }}</span><br>
        <span>{{ actuador.tipo }}</span><br>
        <span>{{ actuador.ubicacion }}</span>
    </button>

    
    
    {% elif actuador.tipo == 'altavoz' %}
    <button class="switch-button" id="switch_{{ actuador.id }}" data-actuador-id="{{ actuador.id }}" data-state="" onclick="">
        <span>{{ actuador.nombre }}</span><br>
        <span>{{ actuador.tipo }}</span><br>
        <span>{{ actuador.ubicacion }}</span>
    </button>
    
    {% endif %}
    <div class="menu-button" onclick="showMenu({{ actuador.id }})">...</div>
  </div>
{% else %}
  <p>No hay actuadores agregados. Por favor, agregue uno.</p>
{% endfor %}

The Javascript:

function toggleSwitch(buttonElement) {
    const actuadorId = buttonElement.dataset.actuadorId;
    let currentState = buttonElement.dataset.state;
    const newState = currentState === '1' ? '0' : '1';

    console.log(`Enviando comando al actuador ${actuadorId}: ${newState}`);
    console.log(`Body being sent:`, JSON.stringify({ mensaje: newState }));
    console.log(newState)
    fetch(`/enviar_comando_actuador/${actuadorId}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ mensaje: newState })
        
    })
    .then(response => {
        console.log('Response status:', response.status);
        if (!response.ok) {
            throw new Error(`HTTP status ${response.status}`);
        }
        return response.json();
    })
    .then(data => {
        console.log('Respuesta del servidor:', data);
        if (data.success) {
            buttonElement.dataset.state = newState;
            buttonElement.style.backgroundColor = newState === '1' ? 'green' : 'red';
        } else {
            console.error('Error al procesar el comando:', data.message);
        }
    })
    .catch(error => {
        console.error('Error al enviar comando al actuador:', error);
    });
}

This is the flask route:

@main.route('/enviar_comando_actuador/<int:actuador_id>', methods=['POST'])
@login_required
def enviar_comando_actuador(actuador_id):
    if not request.is_json:
        print("Error: No JSON received")
        return jsonify({'success': False, 'message': 'Expected JSON content'}), 400

    data = request.get_json()
    comando = data.get('mensaje')
    print(f"Received JSON: {data}")  # Imprimir los datos JSON recibidos
    print(f"Received command for actuator {actuador_id}: {comando}")

    if comando not in ['0', '1']:
        print("Error: Invalid command value")
        return jsonify({'success': False, 'message': 'Invalid command value'}), 400

    try:
        actuador = Actuador.query.get(actuador_id)  # Use get() instead of get_or_404()
        if not actuador:
            print(f"Actuator with ID {actuador_id} not found")
            return jsonify({'success': False, 'message': 'Actuator not found'}), 404  # Return 404 for missing actuator
        print(f"Command {comando} will be sent to actuator {actuador_id}")
        # Simular el envío de comando al hardware aquí si es necesario
        return jsonify({'success': True, 'message': 'Comando enviado correctamente.', 'estado': comando})
    except Exception as e:
        print(f"Error while processing command: {str(e)}")
        return jsonify({'success': False, 'message': 'Error al enviar comando.', 'error': str(e)}), 500

I expect that when I click the button the MQTT message will be sent and the error disappears

I facing problem to create this slider, shown in this image please help me with that as soon as possible

enter image description heretext

Please help me to learn new features of web development, I facing problems for learing web development without any support.

One of the main challenges faced during the project was to identify the user’s learning needs accurately. However, after a few sessions, we were able to understand their requirements and customize the platform accordingly.

One of the significant challenges we faced during the project was accurately identifying the user’s learning needs. It took a few sessions, but eventually, we were able to understand their requirements and customize the platform accordingly

Help me to explore the web designing features with this platform

Type ‘string[]’ is not assignable to type ‘string’.ts(2322) when trying to create a form using Prisma

so I’m trying to create a submitForm using prisma, react-hook-form and zod and mysql as my database. But the problem I’m encountering right now is I get this error on form-submit.ts

Type 'string[]' is not assignable to type 'string'.ts(2322)

I know this comes from my schema.prisma, because upon reading the docs, on Scalar https://www.prisma.io/docs/orm/reference/prisma-schema-reference#-modifier

model AppoinmentSchedule {
  id String @id @default(cuid())
  doesHaveTCETAssitance String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt 
}

Since my zod accepts array.

export const formSchemaData = z.object({
    
    doesHaveDryRun:  z.enum(["yes", "no"], {
      required_error: "Please select if yes or not"
    }),
   
  })

form-submit.ts


export const submitForm = async (
    values: z.infer<typeof formSchemaData>
) => {
    const validatedFields = formSchemaData.safeParse(values)

    if(!validatedFields.success){
        return {error: "Form not submitted successfully!"}
    }

    const {
        doesHaveTCETAssitance,
    } = validatedFields.data

    try {
        await db.appoinmentSchedule.create({
            data: {
                doesHaveTCETAssitance,
            }
        })
    } catch (error) {
        return {error: "Something went wrong"}
    }
}

CSS and JS: How to prevent “event.target.innerText” from deleting inside tag

For example, I have a tag like:

<p><a href="mailto:[email protected]">[email protected]</a></p>

When it runs through this:

const repetitions = setInterval(x => {
      originalText = event.target.innerText;
      splitText = event.target.dataset.value.split("");
      event.target.innerText = splitText.map((character, index) => {
        
      if (index < i) {
        return event.target.dataset.value[index];
      } else {
        return codeSymbols[Math.floor(Math.random() * 26)]
      }

It deletes the inner a tag and leaves it with. <p>[email protected]</p>

The event is based off of observing:

const hiddenElements = document.querySelectorAll("h1, h2, p, a");
hiddenElements.forEach(ele => {
  observer.observe(ele);
})

I believe the observing event detects a p, then it targets the p tagname in event.target.tagname, deleting the inner a tag.

How would I prevent this from happening?

Load mixed content on page load with Javascipt

Modern browsers are constantly forcing https for all situations.

Issue: Need to load mixed content

Before the https requests were being force, I could use JS to force the page to reload as http for the camera part of the page. It’s no longer working in many browsers. I have tried all of the easy basic javascript tricks but they have all failed. I’m using squarespace so I can’t override the browser requests server side.

Currently, if the page loads as http: it does the following:

displays a Image from the camera over static IP: http://96.57.87.254:91/live/1/jpeg.jpg with the option to click on a button which goes to another page that loads the RTP video stream.

My only thoughts are to

  1. Force the page down to http, but the browser ignores the protocol
    and loads the page say http://google.com as https no matter what.

  2. Use a CORS proxy for the http content parts? I am not sure how to get that to work with a static IP

  3. Use some 3rd party webste to host it as https.

I’m hoping someone can help me solve one of these or suggest something else.

For example this fails:

<script> 
if (!(window.location.href.indexOf("squarespace") > -1) && (location.protocol == 'https:')) {
    alert("Cameras require that your browser use http connection, switching to it now");
    var URL = 'http://URL.org/'
    var httpAnchor = document.createElement('a');
    httpAnchor.href = URL;
    
    // Trigger a click on the anchor element
    httpAnchor.click();
}


</script>

This for example also fails:

    if (!(window.location.href.indexOf("squarespace") > -1) && (location.protocol == 'https:')) {
    alert("Cameras require that your browser use http connection, switching to it now");
    var URL = 'http://URL.org'
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    }
    xmlhttp.open("GET", URL, true);
    xmlhttp.send();
}

Long delay before completion of a simple firestore-reading script

Getting reoriented after a long time since my last firestore project. Why does this script take an extra 60-90s — after the output — to complete? It works properly except for the mysterious ending…

import { initializeApp } from "firebase/app";
import { getFirestore, collection, query, getDocs } from "firebase/firestore";


const firebaseConfig = {
  // my config
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

async function getSomeFirestoreData() {
  try {
    const ref = collection(db, "MyCollection");
    const q = query(ref);
    const querySnapshot = await getDocs(q);
    querySnapshot.forEach(doc => {
      console.log(doc.id, " => ", doc.data());
    });
    return "done"
  } catch (e) {
    console.log(e);  // we don't get here
  }
}

getSomeFirestoreData().then(r => {
  console.log(r);  // we get here fast (fast enough)
  process.exit();  // terminates fast with this, but I shouldn't need it
});

After a recent install, package.json:

    "node_modules/@firebase/firestore": {
      "version": "4.6.1",
      ...

I see my doc data after a very reasonable delay and I see “done” immediately. Without the explicit exit, node doesn’t terminate for another minute and a half. Why?

How do I pass a JavaScript variable to Flask?

I’m relatively new to JavaScript. I have a function in flask which I want to call, but it requires arguments which can only be defined in JavaScript.

var socket = io();
socket.connect('http://127.0.0.1:5000/');
socket.on('connect', function() {
    console.log('connected')
});

function createSpan() {
    var c = 1
    for (let i of document.getElementsByTagName('li')) {
        var span = document.createElement('span');
        span.id = 'outlineSpan'
        var clonedLI = i.cloneNode(true);
        span.appendChild(clonedLI);
        console.log(i.innerHTML)
        var genNotesBtn = document.createElement('button');
        genNotesBtn.className = 'genNotesBtn';
        genNotesBtn.id = 'genNotesBtn' + c;
        c++;
        genNotesBtn.innerHTML = 'Generate notes.';
        genNotesBtn.onclick = function() {
            socket.emit('notesGen')
        }
        span.appendChild(genNotesBtn);
        i.parentNode.replaceChild(span, i);
        var text = i.innerHTML;
    }
}

How can I use text as the variable for subheading in this SocketIO function:

@socketio.on('notesGen')
def notesGen():
    assistantID = notesGenAssistant()
    subheading = ?
    notesGenThread(subheading, detail)
    notesGenRun(notesGenAssistantID, threadid)

I tried to redeclare var text = i.innerHTML; to var text = '{{ subheading }}', but Flask didn’t recognise the variable.

Remove an element from HTML using Javascript [duplicate]

I am working from a backend system, which doesn’t allow me to edit the HTML but does allow me to add javascript or HTML And CSS in the top or bottom of the page.

I have the following code on the page:

<div class="ext_ui_section_items"><div class="ext_ui_dropdown_item ext_ui_dropdown_item--light"><a href="/user/approvals" tabindex="0" class="ext_ui_dropdown_item_anchor"><div class="ext_ui_dropdown_item_anchor_wrapper"><span class="ext_ui_dropdown_icon_wrapper"><!----></span> <span class="ext_ui_dropdown_item_text">
    Approvals
    </span> <span class="ext_ui_dropdown_item_suffix"><div data-v-2032d9d2="" data-ui-id="countValue" class="badge menu_style_light">
  0
</div></span></div></a></div> <div class="ext_ui_dropdown_item ext_ui_dropdown_item--light" data-ui-id="my-requests"><a href="/user/requests?reporter=ALL_REQUESTS" tabindex="0" class="ext_ui_dropdown_item_anchor"><div class="ext_ui_dropdown_item_anchor_wrapper"><span class="ext_ui_dropdown_icon_wrapper"><!----></span> <span class="ext_ui_dropdown_item_text">
    My requests
    </span> <span class="ext_ui_dropdown_item_suffix"><div data-v-2032d9d2="" data-ui-id="countValue" class="badge menu_style_light">
  0
</div></span></div></a></div></div>

Now the element I want to remove is the FIRST child element in that list named ‘ext_ui_dropdown_item ext_ui_dropdown_item–light’ by class, however, I do not want to remove the entire list, but just that first index. The issue I have is, that they are both named with the same class and removing one removes both of them. Can anyone help?

I have tried

 const parent = document.getElementsByClassName("ext_ui_section_items");
    const child = document.getElementsByClassName("ext_ui_dropdown_item ext_ui_dropdown_item--light");

setting the constants and then trying to remove them via the HTML collection, but it’s confusing me now.

Export data from Excel via an API

I’m currently working on a project that requires me to import data from various excel documents onto a webpage. I can easily import the data via an API, the problem is getting that data out of excel.

I’ve successfully created a script via the script lab addin that enables me to pull all required data out of excel and format it. I’m even able to send it into script lab’s paired html display page. The problem, though, is that I am unsure if it’s possible to send the data elsewhere. Script lab is cloud based so in theory I can send it to an api from there, but I don’t know if it’s possible to import the api library into script lab’s JavaScript text editor. Alternatively, I would have no problem running the script locally on my device and sending the api calls from my computer. However, then I don’t know how to access the data in my excel document. It would all be local at that point so I could in theory do so easily, but I don’t know for sure. Am I just missing something or is this not possible? Is there a different way I should go about this?