Why is classList.remove not removing the class

When the user focus out of the project-name field, I want to disable the field and remove a class on it.
The thing is, event is triggering, console logs are working but the class remains in the list.

document.getElementById("project-name").addEventListener("focusout", (event) => {
    console.log(event.target.classList);
    event.target.disabled = true;
    event.target.classList.remove("field__input--error");
    console.log(event.target.classList);
})

console output

I have tried replacing all “event.target.” with “document.getElementById(‘project-name’).”
I have reasearched the problem but on similar questions, it always seem they don’t isolate the removing and it’s another part of the logic that fails.

Here that’s all there is in the event listenner.

So I really don’t see why the class remains, it’s the first time I’ve ever had an issue with this function.

Chrome Extension – Manifest V3 URL Capture

I’m having issues using regexFilter to capture URL and redirect it to the extension page. On Chrome I end up with broken URL and endless redirection loop. On brave I get ERR_BLOCKED_BY_CLIENT. I’m trying to capture any MPEG-DASH or HLS streaming URL to play it inside the extension.
Service worker looks like this:

var enabled = true;

var extension_page = chrome.runtime.getURL('/index.html');
var substitution = extension_page + "#\0"

var rules = [{
  id: 1,
  action: {
    type: 'redirect',
    redirect: { regexSubstitution: substitution },
  },
  condition: {
    regexFilter: '^https?://.*/(.*\.m3u8?|.*\.mpd|Manifest).*',
    resourceTypes: ['main_frame', 'sub_frame'],
  },
}];

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request == "getState") {
        sendResponse(enabled);
        return;
    }
      
    enabled = request == "ENABLE";
    enabled ? chrome.action.setIcon({path: "assets/icon128.png" }) : chrome.action.setIcon({ path:"assets/icon128grey.png" });

    if(true === enabled) {
        chrome.declarativeNetRequest.updateDynamicRules({
            removeRuleIds: rules.map(r => r.id),
            addRules: rules,
        });
    } else {
        chrome.declarativeNetRequest.updateDynamicRules(chrome.declarativeNetRequest.updateDynamicRules({
            removeRuleIds: rules.map(r => r.id)
        }));
    }
});

chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: rules.map(r => r.id),
    addRules: rules,
});

manifest.json looks like this

{
    "name": "Native MPEG-Dash + HLS Playback",
    "version": "5.0.0",
    "description": "Allow the browser to play HLS (m3u8) or MPEG-Dash (mpd) video urls 'natively'",
    "manifest_version": 3,
    "icons": { "128": "assets/icon128.png" },
    "background": { 
        "service_worker": "new_service_worker.js",
        "type": "module"
    },
    "permissions": [
        "tabs",
        "declarativeNetRequest",
        "storage"
    ],
    "host_permissions": [
        "<all_urls>"
    ],
    "options_ui": {
        "page": "options.html"
    },
    "action": {
        "default_title": "Native MPEG-Dash + HLS Playback",
        "default_icon": "assets/icon128.png",
        "default_popup": "popup.html"
    }
}

Using an example I end up with extremely wrong redirect loop:

https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fpschrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#chrome-extension://iepdffliopgmnnmohpmdhclhdhkoonea/index.html#.mpd

On Brave I end up with ERR_BLOCKED_BY_CLIENT. Furthermore, pasting streaming URL directly into Brave address bar works.

This solution was found at Get original URL when redirecting via declarativeNetRequest + extensionPath

I tried different variations of regex which didn’t work.

Content Overflow Issue in Fixed-Height Banner Layout Using Flexbox on a Responsive Web Page

Hello Stack Overflow Community,

I’m facing an issue with a web page design where I have a fixed-height banner (400px) that needs to contain several elements including a video, a title, and a button. I’m using Flexbox for layout, but I’m encountering a problem where part of the content overflows or is clipped off the screen, particularly at the top of the banner.

index.html (will become banner.html as a part of main page)

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>expressingourselvesfreely</title>
  <link rel="stylesheet" href="./style.css">

</head>
<body>
  <div class="banner-container">
<!-- partial:index.partial.html -->
<section id="background">
  <div id="blob"></div>
  <div id="blur"></div>
</section>

<main>

  <div id="video-container">
    <video src="https://cdn.shopify.com/videos/c/o/v/aece5414e94f4e6a9b4d435c11a7172e.mp4" muted autoplay loop playsinline></video>
  </div>

  <div id="title">
    <span class="word">
      <span class="char">E</span>
      <span class="char">x</span>
      <span class="char">p</span>
      <span class="char">r</span>
      <span class="char">e</span>
      <span class="char">s</span>
      <span class="char">s</span>
      <span class="char">i</span>
      <span class="char">n</span>
      <span class="char">g</span>
    </span>
    <span class="word">
      <span class="char">o</span>
      <span class="char">u</span>
      <span class="char">r</span>
      <span class="char">s</span>
      <span class="char">e</span>
      <span class="char">l</span>
      <span class="char">v</span>
      <span class="char">e</span>
      <span class="char">s</span>
    </span>
    <span class="word">
      <span class="char">f</span>
      <span class="char">r</span>
      <span class="char">e</span>
      <span class="char">e</span>
      <span class="char">l</span>
      <span class="char">y</span>
    </span>
  </div>

  <button id="replay">
    <span id="purple"></span>
    <span id="turquois"></span>
    <span id="yellow"></span>
    <span class="text" id="text-static">Shop</span>
    <span class="text" id="text-reveal">Shop</span>
  </button>

</main>
<!-- partial -->
  <script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script><script  src="./script.js"></script>
</div>
</body>
</html>

Style.css

@import url("https://fonts.cdnfonts.com/css/antique-olive-std");



.banner-container {
  max-height: 400px; /* Maks høyde på banneret */
  overflow: hidden; /* Skjuler alt innhold som går over 400px */
  width: 100%; /* Full bredde */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Responsivitet for mindre skjermer */
@media (max-width: 768px) {
  .banner-container {
    max-height: 200px; /* Mindre høyde for mindre enheter */
  }
}

:root {
  --yellow: #40a4a8;
  --purple: #a374ff;
  --turquois: #15f0d1;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* -- Background -- */

body {
  width: 100vw;
  height: 100vh;
  background: #fffffc;
  overflow: hidden;
  font-family: "Antique Olive Std", sans-serif;
}

#background {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -1;
}


/* -- Blob -- */

#blob {
  position: absolute;
  background-color: white;
  height: 36vmax;
  aspect-ratio: 1;
  background: linear-gradient(to right, #3d85c6, #65c1c4);
  border-radius: 50%;
  opacity: 0.8;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
}

#blur {
  height: 100%;
  width: 100%;
  position: absolute;
  backdrop-filter: blur(8vmax);
  -webkit-backdrop-filter: blur(8vmax);
}

/* -- Video, Title, & Button -- */

main {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  perspective: 1000px;
  user-select: none;
}

/* -- Video -- */

#video-container {
  width: 50vw;
  height: 40vh;
  overflow: hidden;
  position: relative;
  pointer-events: none;
  border-radius: 40px;
  transform-style: preserve-3d;
  scale: 0;
}

#video-container > * {
  width: 115%;
  height: 115%;
  position: absolute;
  top: -7%;
  left: -7%;
  object-fit: cover;
}

/* -- Title Text -- */

#title {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  transform: translate3D(300px, 0, 0);
  pointer-events: none;
}

.word {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #1d1d1f;
  font-size: 5vw;
  font-weight: 900;
  line-height: 103px;
  letter-spacing: -7px;
}

.word:nth-child(2) {
  transform: translateX(-180px);
}

.word:nth-child(3) {
  transform: translateX(110px);
}

.char {
  opacity: 0;
}

/* -- Button -- */

#replay {
  position: absolute;
  overflow: hidden;
  transform: translate3D(220px, -5px, 0) scale(0);
  height: 50px;
  width: 180px;
  background: var(--yellow);
  border-radius: 30px;
  border: none;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

#replay > .text {
  font-weight: bold;
  font-size: 15px;
  pointer-events: none;
  transform: translateY(10px);
}

#replay > #text-reveal {
  opacity: 0;
}

#replay > #purple,
#replay > #turquois,
#replay > #yellow {
  position: absolute;
  width: 360px;
  top: 40px;
  aspect-ratio: 1;
  border-radius: 50%;
  z-index: -1;
  transform: translateY(-60px);
  pointer-events: none;
}

#replay > #purple {
  background: var(--purple);
}

#replay > #turquois {
  background: var(--turquois);
}

#replay > #yellow {
  background: var(--yellow);
}

/* -- Link -- */

a {
  position: absolute;
  bottom: 0;
  margin: 8px;
  color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.1);
  font-size: 14px;
  text-decoration: none;
  padding: 10px 20px 7px 20px;
  border-radius: 30px;
}

script.js

window.addEventListener('resize', function() {
  // Din logikk for å håndtere endringer i størrelse
});

// Blob and video react to mouse position

let allowRotation = true;
window.addEventListener("mousemove", (mouseEvent) => {
  const { clientX, clientY } = mouseEvent;

  blobFollowMouse(clientX, clientY); // Animation

  const videoContainer = document.querySelector("#video-container");

  const rect = videoContainer.getBoundingClientRect();
  const centerX = rect.left + rect.width / 2;
  const centerY = rect.top + rect.height / 2;
  const distanceX = (clientX - centerX) / rect.width;
  const distanceY = (clientY - centerY) / rect.height;

  if (allowRotation) {
    // To prevent conflicting animations
    rotateVideo3D(distanceX, distanceY); // Animation
  }
});

// Button Reactivity
let btnPlayed = false;
const button = document.querySelector("#replay");

button.addEventListener("mouseover", () => {
  buttonGrow(button); // Animation
  buttonTextIn();
  if (!btnPlayed) {
    buttonColorsWave();
    btnPlayed = true;
  }
});

button.addEventListener("mouseout", () => {
  buttonShrink(button); // Animation
  btnPlayed = false;
});

button.addEventListener("click", () => {
  titleSlideIn(); // Animation
  videoButtonPopIn(); // Animation
});

// initial animations
titleSlideIn();
videoButtonPopIn();

/* -- GSAP ANIMATIONS -- */

// Blob

function blobRotate() {
  const tl = gsap
    .timeline({ repeat: -1, ease: "none" })
    .to("#blob", { rotation: 180, scaleX: 1.6 })
    .to("#blob", { rotation: 360, scaleX: 1 })
    .totalDuration(17);
  tl.play();
}
blobRotate();

function blobFollowMouse(x, y) {
  gsap.to("#blob", {
    left: x,
    top: y,
    duration: 2
  });
}

// 3D Video

function rotateVideo3D(distanceX, distanceY) {
  gsap.to("#video-container", {
    rotateX: -20 * distanceY,
    rotateY: 20 * distanceX,
    duration: 0.5,
    ease: "power1.out"
  });
}

function videoButtonPopIn() {
  allowRotation = false;

  gsap.fromTo(
    "#replay, #video-container",
    { scale: 0 },
    {
      scale: 1,
      ease: "elastic.out(1, 0.8)",
      duration: 0.8,
      delay: 0.4,
      onComplete: () => {
        allowRotation = true;
      }
    }
  );
}

// Title Text

function titleSlideIn() {
  document.querySelectorAll(".word").forEach((word, wordIdx) => {
    Array.from(word.children).forEach((char, charIdx) => {
      gsap.fromTo(
        char,
        {
          opacity: 0,
          x: 0
        },
        {
          opacity: 1,
          x: -300,
          ease: "elastic.out(1.1, 0.7)",
          duration: 1.2,
          delay: wordIdx * 0.2 + charIdx * 0.03
        }
      );
    });
  });
}

// Button

function buttonColorsWave() {
  gsap.fromTo(
    "#purple",
    {
      scale: 0
    },
    {
      scale: 1
    }
  );
  gsap.fromTo(
    "#turquois",
    {
      scale: 0
    },
    {
      scale: 1,
      delay: 0.1
    }
  );
  gsap.fromTo(
    "#yellow",
    {
      scale: 0
    },
    {
      scale: 1,
      delay: 0.2
    }
  );
}

function buttonTextIn() {
  gsap.fromTo(
    ".text",
    {
      y: 9
    },
    {
      y: -8
    }
  );
  gsap.fromTo(
    "#text-static",
    {
      opacity: 1
    },
    {
      opacity: 0
    }
  );
  gsap.fromTo(
    "#text-reveal",
    {
      opacity: 0
    },
    {
      opacity: 1
    }
  );
}

function buttonGrow(button) {
  gsap.to(button, {
    width: 170,
    height: 46
  });
}

function buttonShrink(button) {
  gsap.to(button, {
    width: 180,
    height: 50
  });
}

/* 
Notes: 
  The use of fromTo tweens is for the replay button.
  Much of the animation (if not all of it) can be done with pure CSS.
  GSAP was chosen to make the code more concise and easier to read.
  This pen could have been smoother with a preloaded video.
*/

I hope to get a format that fits as a banner. I tried to change the content, but without success

Position custom tooltip relative to different SVG group with selected class

I’ve built an SVG map where you can either hover over a separate list of names on the left which will trigger a tooltip. Or hover over the numbered icon on the map itself which also triggers the tooltip.

However I can’t successfully get the tooltip to re-position itself relative to each numbered icon.

var iconPos = myicon.getBoundingClientRect();
  mypopup.style.left = (iconPos.right + 20) + "px";
  mypopup.style.top = (window.scrollY + iconPos.top - 60) + "px";
  mypopup.style.display = "block";

I was previously trying to use the code above but it was making the tooltip position top: 6451px; +.

I’d like the tooltip to appear central to the numbered icon (map__plot__item) which has the class selected.

Below is a demo I’ve created to show how it currently works with the tooltip positioned top right. JS Fiddle here too.

$( ".map__list__item" ).on( "mouseover", function() {
        var tooltipCopy = $(this).html();
        $(this).addClass('selected');
        $(this).siblings('li').removeClass('selected');
        $('#' + $(this).data('map')).addClass('selected');
        $('#' + $(this).data('map')).siblings('g').removeClass('selected');
        $("#mypopup").show().html(tooltipCopy);
    });

    $( ".map__list__item" ).on( "mouseout", function() {
        $(this).removeClass('selected');
        $(this).siblings('li').removeClass('selected');
        $('#' + $(this).data('map')).removeClass('selected');
        $('#' + $(this).data('map')).siblings('g').removeClass('selected');
        $("#mypopup").hide().empty();
    });

    $('.map__plot__item').on( "mouseover", function() {
        var tooltipCopy =  $(this).data('list');
        $(this).addClass('selected');
        $(this).siblings('g').removeClass('selected');
        $("#mypopup").show().html(tooltipCopy);
    });

    $('.map__plot__item').on( "mouseout", function() {
        $(this).removeClass('selected');
        $(this).siblings('g').removeClass('selected');
        $("#mypopup").hide().empty();
    });
body {
  margin: 0;
  padding: 0;
}
#top-section {
  height: 250px;
  background: red;
}

h1 {
  color: white;
  text-align: center;
  font-size: 40px;
  line-height: 40px;
  font-family: Arial;
}
#map-wrapper {
  position: relative;
  width: 100%;
}

#mapNavigation {
  width: 200px;  
  flex-shrink: 0
}

#mapNavigation li {
  line-height: 25px;
}

.d-flex {
  display: flex;
}

svg {
  width: 100%;
}

#mypopup {
  width: 200px;
  height: 20px;
  padding: 10px;
  font-family: Arial, sans-serif;
  font-size: 18px;
  color: $dark;
  background-color: white;
  border-radius: 6px;
  position: absolute;
  display: none;
  top: 0;
  right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="top-section">
  <h1>
    Heading here
  </h1>
</div>
<div class="d-flex">
  <div id="mapNavigation">
    <ol>
      <li id="restaurant-list-01" class="map__list__item" data-map="restaurant-01">
       Name here 01
      </li>
      <li id="restaurant-list-02" class="map__list__item" data-map="restaurant-02">
        Name here 02
      </li>
      <li id="restaurant-list-03" class="map__list__item" data-map="restaurant-03">
        Name here 03
      </li>
      <li id="restaurant-list-04" class="map__list__item" data-map="restaurant-04">
        Name here 04
      </li>
      <li id="restaurant-list-05" class="map__list__item" data-map="restaurant-05">
        Name here 05
      </li>
      <li id="restaurant-list-06" class="map__list__item" data-map="restaurant-06">
        Name here 06
      </li>
      <li id="restaurant-list-07" class="map__list__item" data-map="restaurant-07">
        Name here 07
      </li>
      <li id="restaurant-list-08" class="map__list__item" data-map="restaurant-08">
        Name here 08
      </li>
    </ol>
  </div>
  <div id="map-wrapper">
    
<svg width="100%"  viewBox="0 0 1336 942" fill="none">
<g id="Layer_2">
    <rect width="1336" height="942" fill="#D9D9D9"/>
</g>
<g id="Layer_1">
    <g id="restaurant-05" data-list="Name here 05" class="map__plot__item">
        <circle cx="554" cy="336" r="36" fill="#B93333"/>
        <path d="M547.5,340.8l3.8-0.4c0.1,0.9,0.4,1.6,1,2.1c0.5,0.5,1.2,0.8,1.9,0.8c0.8,0,1.5-0.3,2-1
            c0.6-0.7,0.8-1.6,0.8-3c0-1.2-0.3-2.2-0.8-2.8c-0.5-0.6-1.3-0.9-2.1-0.9c-1.1,0-2.1,0.5-3,1.5l-3.1-0.5l2-10.4H560v3.6h-7.2
            l-0.6,3.4c0.9-0.4,1.7-0.6,2.6-0.6c1.7,0,3.1,0.6,4.3,1.9c1.2,1.2,1.8,2.8,1.8,4.8c0,1.6-0.5,3.1-1.4,4.4
            c-1.3,1.8-3.1,2.7-5.4,2.7c-1.8,0-3.4-0.5-4.5-1.5C548.4,343.9,547.7,342.5,547.5,340.8z" fill="white" />
    </g>
    <g id="restaurant-03" data-list="Name here 03" class="map__plot__item">
        <circle cx="732" cy="320" r="36" fill="#B93333"/>
        <path d="M725.3,324.7l3.7-0.5c0.1,0.9,0.4,1.7,1,2.2c0.5,0.5,1.1,0.8,1.9,0.8c0.8,0,1.5-0.3,2-0.9
            c0.5-0.6,0.8-1.4,0.8-2.4c0-1-0.3-1.7-0.8-2.3c-0.5-0.6-1.2-0.8-1.9-0.8c-0.5,0-1.1,0.1-1.8,0.3l0.4-3.1c1,0,1.8-0.2,2.4-0.7
            c0.5-0.5,0.8-1.1,0.8-1.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.6-0.6c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1.1-0.8,2l-3.5-0.6
            c0.2-1.2,0.6-2.2,1.1-2.9c0.5-0.7,1.2-1.3,2.1-1.7c0.9-0.4,1.9-0.6,3-0.6c1.9,0,3.4,0.6,4.5,1.8c0.9,1,1.4,2.1,1.4,3.3
            c0,1.8-1,3.2-2.9,4.2c1.1,0.2,2.1,0.8,2.7,1.7c0.7,0.9,1,1.9,1,3.1c0,1.8-0.6,3.3-1.9,4.5c-1.3,1.2-2.9,1.9-4.8,1.9
            c-1.8,0-3.3-0.5-4.5-1.6C726.1,327.7,725.5,326.4,725.3,324.7z" fill="white"/>
    </g>
    <g id="restaurant-02" data-list="Name here 02" class="map__plot__item">
        <circle cx="988" cy="240" r="36" fill="#B93333"/>
        <path d="M994.4,246.4v3.6h-13.5c0.1-1.3,0.6-2.6,1.3-3.8c0.7-1.2,2.2-2.8,4.3-4.8c1.7-1.6,2.8-2.7,3.2-3.3
            c0.5-0.8,0.8-1.6,0.8-2.4c0-0.9-0.2-1.5-0.7-2c-0.5-0.5-1.1-0.7-1.9-0.7c-0.8,0-1.4,0.2-1.9,0.7s-0.7,1.3-0.8,2.4l-3.8-0.4
            c0.2-2.1,0.9-3.6,2.1-4.6c1.2-0.9,2.7-1.4,4.5-1.4c2,0,3.5,0.5,4.7,1.6c1.1,1.1,1.7,2.4,1.7,4c0,0.9-0.2,1.8-0.5,2.6
            c-0.3,0.8-0.8,1.7-1.5,2.6c-0.5,0.6-1.3,1.4-2.5,2.6c-1.2,1.1-2,1.9-2.3,2.2c-0.3,0.4-0.6,0.7-0.8,1.1H994.4z" fill="white"/>
    </g>
    <g id="restaurant-04" data-list="Name here 04" class="map__plot__item">
        <circle cx="1094" cy="494" r="36" fill="#B93333"/>
        <path d="M1094.9,504v-4h-8.2v-3.4l8.7-12.7h3.2v12.7h2.5v3.4h-2.5v4H1094.9z M1094.9,496.6v-6.9l-4.6,6.9H1094.9z" fill="white"/>
    </g>
    <g id="restaurant-01" data-list="Name here 01" class="map__plot__item">
        <circle cx="916" cy="664" r="36" fill="#B93333"/>
        <path d="M919.2,674h-3.8v-14.5c-1.4,1.3-3.1,2.3-5,2.9v-3.5c1-0.3,2.1-0.9,3.3-1.9c1.2-0.9,2-2,2.4-3.2h3.1V674z" fill="white"/>
    </g>
    <g id="restaurant-06" data-list="Name here 06" class="map__plot__item">
        <circle cx="416" cy="748" r="36" fill="#B93333"/>
        <path d="M422.4,742.9l-3.7,0.4c-0.1-0.8-0.3-1.3-0.7-1.7c-0.4-0.4-0.9-0.5-1.5-0.5c-0.8,0-1.5,0.4-2.1,1.1
            c-0.6,0.7-0.9,2.2-1.1,4.6c1-1.1,2.1-1.7,3.6-1.7c1.6,0,3,0.6,4.1,1.8c1.1,1.2,1.7,2.8,1.7,4.7c0,2.1-0.6,3.7-1.8,4.9
            c-1.2,1.2-2.7,1.9-4.6,1.9c-2,0-3.7-0.8-5-2.4c-1.3-1.6-2-4.2-2-7.7c0-3.7,0.7-6.3,2-7.9c1.4-1.6,3.1-2.4,5.3-2.4
            c1.5,0,2.8,0.4,3.8,1.3C421.5,740,422.1,741.2,422.4,742.9z M413.7,751.2c0,1.2,0.3,2.2,0.9,2.9c0.6,0.7,1.2,1,2,1
            c0.7,0,1.3-0.3,1.8-0.8c0.5-0.6,0.7-1.5,0.7-2.7c0-1.3-0.3-2.3-0.8-2.9c-0.5-0.6-1.1-0.9-1.9-0.9c-0.7,0-1.4,0.3-1.9,0.9
            C414,749.3,413.7,750.1,413.7,751.2z" fill="white"/>
    </g>
    <g id="restaurant-07" data-list="Name here 07" class="map__plot__item">
        <circle cx="260" cy="220" r="36" fill="#B93333"/>
        <path d="M253.4,213.8v-3.6h13.1v2.8c-1.1,1.1-2.2,2.6-3.3,4.6c-1.1,2-2,4.1-2.6,6.4c-0.6,2.2-0.9,4.2-0.9,6h-3.7
            c0.1-2.8,0.6-5.6,1.7-8.5c1.1-2.9,2.5-5.5,4.3-7.7H253.4z" fill="white"/>
    </g>
    <g id="restaurant-08" data-list="Name here 08" class="map__plot__item">
        <circle cx="490" cy="548" r="36" fill="#B93333"/>
        <path d="M486.7,547.2c-1-0.4-1.7-1-2.2-1.7c-0.4-0.7-0.7-1.5-0.7-2.4c0-1.5,0.5-2.7,1.6-3.7c1-1,2.5-1.5,4.5-1.5
            c1.9,0,3.4,0.5,4.4,1.5c1.1,1,1.6,2.2,1.6,3.7c0,0.9-0.2,1.8-0.7,2.5c-0.5,0.7-1.2,1.3-2,1.7c1.1,0.4,2,1.1,2.5,2
            c0.6,0.9,0.9,1.8,0.9,3c0,1.9-0.6,3.4-1.8,4.5c-1.2,1.2-2.7,1.7-4.7,1.7c-1.8,0-3.3-0.5-4.6-1.4c-1.4-1.1-2.1-2.7-2.1-4.6
            c0-1.1,0.3-2.1,0.8-3C484.7,548.4,485.5,547.7,486.7,547.2z M487.5,543.3c0,0.8,0.2,1.4,0.6,1.8c0.4,0.4,1,0.6,1.7,0.6
            c0.7,0,1.3-0.2,1.8-0.6c0.4-0.4,0.7-1,0.7-1.8c0-0.7-0.2-1.3-0.7-1.7c-0.4-0.4-1-0.7-1.7-0.7c-0.7,0-1.3,0.2-1.8,0.7
            C487.7,542,487.5,542.6,487.5,543.3z M487.1,551.9c0,1.1,0.3,1.9,0.8,2.5c0.5,0.6,1.2,0.9,2,0.9c0.8,0,1.4-0.3,2-0.8
            c0.5-0.6,0.8-1.4,0.8-2.5c0-0.9-0.3-1.7-0.8-2.3c-0.5-0.6-1.2-0.9-2-0.9c-0.9,0-1.6,0.3-2.1,1
            C487.4,550.4,487.1,551.1,487.1,551.9z" fill="white"/>
    </g>
</g>
</svg>

  <div id="mypopup"></div>
  </div>
</div>

“Type Error”:”Failed to fetch error”, after sending form data to googlesheet

After form submit the data was sent to googlesheet. But same time it throws typeerror:”failed to fetch”. I am getting the same error even after I used axios.so the next line after fetch is not running. The code stops working after fetch call.

Below one is the code pasted in googlesheet appscript.

const sheetName = 'Sheet1'
const scriptProp = PropertiesService.getScriptProperties()

function initialSetup () {
  const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  scriptProp.setProperty('key', activeSpreadsheet.getId())
}

function doPost (e) {
  const lock = LockService.getScriptLock()
  lock.tryLock(10000)

  try {
    const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    const sheet = doc.getSheetByName(sheetName)

    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    const nextRow = sheet.getLastRow() + 1

    const newRow = headers.map(function(header) {
      return header === 'Date' ? new Date() : e.parameter[header]
    })

    sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  catch (e) {
    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  finally {
    lock.releaseLock()
  }
}    

below code is formsubmit function

 try {
                let inputValue = {
                    Name: create.Name,
                    Phone: create.Phone,
                    Email: create.Email,
                    Date: currentDate.toDateString(),
                };
                let form_data = new FormData();
                for (let key in inputValue) {
                    form_data.append(key, inputValue[key]);
                }
                const response = await fetch(
                    "https://script.google.com/macros/s/AKfycbyvB7lH3htoX4NkyzqQ4zC_lqBCXWSso_g7P6_nZ55FtMgCXKlInz0AQIbP2IBF9abqpA/exec", 
                    {
                      method: "POST",
                      body: form_data,
                    }
                  );
                  console.log("rese",response)

            } catch (error) {
                setLoading(false)
                console.error("Error writing to Google Sheets:", error);
            }

How to control the list of elements throw keyboard events

UI imageafter user searches, when user tries to use keyoard eveents throw arrows need to move down.

<div>
            
              
              <input onChange={handleSearchChange}/>
            
            <div css={countryDataCss}>
              {countryList?.map((country) => (
                <div key={country.countryCode}>
                  <span css={countryCss}>{country.countryName}</span>
                  <span css={countryDialCodeCss}>
                    {country.countryDialNo}
                  </span>
                </div>
              ))}
            </div>
          </div>

Javascript Webcam video record saved file error

The problem would be that after I downloaded the finished file, the video does not have the length, so it is not possible to wrap it during playback only after we have already watched the video once.

I would like to save the video in mp4 and upload it to the server, because the html5 video player can handle mp4 videos easily.

And the created mp4 video file cannot be played on your IOS device with the safari browser in the html5 video tag.

startCamera() {
        this.previewVideoBoxVisible = true;
        this.videoBoxVisible = false;
        const constraints = {
          audio: false,
          video: {
            width: 1280,
            height: 720,
          },
        };
        navigator.mediaDevices
          .getUserMedia(constraints)
          .then((stream) => {
            this.$refs.previewVideo.srcObject = stream;
            this.recordButtonVisible = true;
          })
          .catch((error) => {
            console.error("Error accessing media devices:", error);
            this.errorMsg = `Error accessing media devices: ${error.toString()}`;
          });
      },
      startRecording() {
        this.videoBoxVisible = false;
        this.recordedBlobs = [];
        navigator.mediaDevices
          .getUserMedia({ audio: false, video: true })
          .then((stream) => {
            this.mediaRecorder = new MediaRecorder(stream);
            this.mediaRecorder.ondataavailable = this.handleDataAvailable;
            this.mediaRecorder.onstop = () => {
                console.log("Recorder stopped");
                this.recording = false;
                this.stopTimer();
                this.videoBoxVisible = true;
                this.playRecordedVideo();
            };
            this.mediaRecorder.start();
            this.recording = true;
            this.startTimer();
            this.videoBoxVisible = false;
          })
          .catch((error) => {
            console.error("Error starting recording:", error);
            this.errorMsg = `Error starting recording: ${error.toString()}`;
          });
      },
      stopRecording() {
        this.mediaRecorder.stop();

      },
      handleDataAvailable(event) {
        if (event.data && event.data.size > 0) {
          this.recordedBlobs.push(event.data);
        }
      },
      playRecordedVideo() {
        const superBuffer = new Blob(this.recordedBlobs, { type: "video/mp4" });
        this.$refs.recordedVideo.src = window.URL.createObjectURL(superBuffer);
        this.$refs.recordedVideo.controls = true;
        this.$refs.recordedVideo.play();
      },
      saveAndUploadVideo() {
        const blob = new Blob(this.recordedBlobs, { type: "video/mp4" });
        var url = window.URL.createObjectURL(blob);

        const a = document.createElement("a");
        a.style.display = "none";
        a.href = url;
        a.download = `${this.number}-${Math.floor(Math.random() * 9000) + 1000}.mp4`;
        document.body.appendChild(a);
        this.formData.append('_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
        this.formData.append("video", blob);
        this.formData.append("stock_id",this.stock.id)
        this.formData.append("stock_number",this.stock.number)

        this.savingInProcess = true;

        console.log("Upload started....");
        axios
          .post("/admin/api/uploadStockConditionVideo", this.formData, {
            headers: { "Content-Type": "multipart/form-data" },
          })
          .then((response) => {
            console.log("Upload finsihed....");
            this.savingInProcess = false;
            if (response.data.success) {
                this.uploaded = 1;
                this.$emit("videoUploadFinish",this.daily_id);
                this.$swal.fire('Siker!',"Sikeres videó feltöltés",'success')

                this.countdown = 3;

                const timer = setInterval(() => {
                    this.countdown--;
                    if (this.countdown <= 0) {
                        clearInterval(timer);
                        window.close();
                    }
                }, 1000);
            }else{
                this.$swal.fire('Hiba!',"Hiba a videó feltöltés közben1",'danger')
            }
          })
          .catch((error) => {
            this.$swal.fire('Hiba!',"Hiba a videó feltöltés közben2",'danger')
            console.error("Error uploading video:", error);
            this.errorMsg = `Error uploading video: ${error.toString()}`;
            this.savingInProcess = false;
          });


      },
      startTimer() {
        console.log("start timer");
        this.mins = 0;
        this.secs = 0;
        this.timer = setInterval(() => {
          this.secs++;
          if (this.secs >= 60) {
            this.mins++;
            this.secs = 0;
          }
        }, 1000);
      },
      stopTimer() {
        clearInterval(this.timer);
      },

React State in the course details page is setting values wrongly but the logged values after creating the course is correct

So I have a form that is used to create a course/attendance:

<form onSubmit={handleSubmit} className="w-full mt-[65px] flex flex-col gap-[30px]">
                        <div className="flex flex-wrap flex-col gap-[40px]">
                            <FormField 
                                labelName="Course Code *" 
                                placeholder="Enter the course code"
                                inputType="text"
                                value={form.courseCode}
                                handleChange={(e) => handleFormFieldChange('courseCode', e)}
                            />
                            <FormField 
                                labelName="Course Name"
                                placeholder="Provide the title of the Attendance"
                                inputType="text"
                                value={form.courseName}
                                handleChange={(e) => handleFormFieldChange('courseName', e)}
                            />
                            <FormField 
                                labelName="Lecturer"
                                placeholder="Provide lecturer's name"
                                inputType="text"
                                value={form.lecturer}
                                handleChange={(e) => handleFormFieldChange('lecturer', e)}
                            />
                            <FormField 
                                labelName="Attendance Description *"
                                placeholder="Provide a description of the Attendance"
                                isTextArea
                                value={form.description}
                                handleChange={(e) => handleFormFieldChange('description', e)}
                            />
                            <label className="font-epilogue font-medium text-[16px] text-white" htmlFor="department">Department *</label>
                                <select
                                    id="department"
                                    className="w-[300px] p-[8px] rounded-[5px] bg-[#3a3a43] text-white"
                                    value={form.department}
                                    onChange={(e) => handleFormFieldChange('department', e)}
                                >
                                    <option value="" disabled>Select Department</option>
                                    {departmentOptions.map((option) => (
                                        <option key={option} value={option}>
                                            {option}
                                        </option>
                                    ))}
                                </select>
                                <label className="font-epilogue font-medium text-[16px] text-white" htmlFor="department">Program Level *</label>
                                <select
                                    id="programLevel"
                                    className="w-[300px] p-[8px] rounded-[5px] bg-[#3a3a43] text-white"
                                    value={form.programLevel}
                                    onChange={(e) => handleFormFieldChange('programLevel', e)}
                                >
                                    <option value="" disabled>Select Program Level</option>
                                    {programOptions.map((option) => (
                                        <option key={option} value={option}>
                                            {option}
                                        </option>
                                    ))}
                                </select>

The handleFormFieldChange will then set the form using react state:

const[ form, setForm ] = useState({
        courseCode: '',
        lecturer: '',
        courseName:'',
        description:'',
        department:'',
        programLevel:'',
    });

const handleFormFieldChange =(fieldName, e) =>{
        let value = e.target.value;
        if (fieldName === 'courseName') {
            value = value.replace(///g, ''); 
        }
        setForm(({ ...form, [fieldName]: value }));
        console.log({ ...form, [fieldName]: value });
    }

Then call the createCourse from AttendanceContext:

import   { useStateContext } from '../../context/AttendanceContext.jsx';

const { createCourse } = useStateContext();

const handleSubmit = async (e) => {
        e.preventDefault();
        try{
            setIsLoading(true);
            console.log({...form});
            await createCourse({...form});
            setIsLoading(false);
            //navigate('/attendance');
        } catch (error) {
            console.error("There was an error creating the course", error);
        }
    }

In AttendanceContext, createCourse would communicate with the solidity code. When I console.log the form after creating the course in the blockchain the console.log has the right values

const createCourse = async (form) => {
      const provider = new ethers.providers.Web3Provider(ethereum);
      const contract = new ethers.Contract(contractAddress, contractABI, provider);
      const address = window.ethereum.selectedAddress 
      try {
        if (!address) {
          await connect();
        }
    
        const signer = provider.getSigner();
        const contractWithSigner = contract.connect(signer);
        const data = await contractWithSigner.createCourse(
          form.courseCode,
          form.lecturer,
          form.courseName,
          form.description, 
          form.department,
          form.programLevel
          //startTime,
          //endTime,
        );
        console.log(form);
        console.log('Contract call success', data);

      } catch (error) {
        console.error('Contract call failure', error);
      }
    };

But when I open up the course details here:

import React, {useState, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import user from '../../images/user.png';
import { CountBox, CustomButton, Loading, Navbar, Footer } from '../../components/index.js';
import { useStateContext } from '../../context/AttendanceContext.jsx';
//import { daysLeft, convert } from '../../utils';
import AdminChecker from '../../utils/adminChecker.js';

const AdminCloseAttendanceDetails = () => {

    const { state } = useLocation();
    const navigate = useNavigate();
    const { contract, address, closeCourse, getAttendees, getAttendeesCount, getLecturer } = useStateContext(); 
    const [ isLoading, setIsLoading ] = useState(false);
    const [ lecturer, setLecturer ] = useState('');
    //const[amount, setAmount]= useState('');
    const [ attendees, setAttendees ] = useState([]);
    const [ currentAttendeeCount, setCurrentAttendeeCount ] = useState([]);
    //const remainingTime = convert(state.endTime);
    const [ isLoadingAttendees, setIsLoadingAttendees ] = useState(true);
    

    const fetchAttendees = async () => {
      setIsLoadingAttendees(true);
      try{
        const lecturer = await getLecturer(state.pId);
        const data = await getAttendees(state.pId);
        console.log("State before setting lecturer:", state);
      console.log("Lecturer fetched:", lecturer);
        setAttendees(data);
        setLecturer(lecturer);
        const attendeeCount = await getAttendeesCount(state.pId);
        setCurrentAttendeeCount(attendeeCount);
      } finally {
        setIsLoadingAttendees(false);
      }
    }

The logs are giving me field entries in different fields and the programLevel field is just gone. the image field was should also be removed since I no longer use it but is still in the state

The console log after creating the course

The console log of the created the course at the details page

The expected outcome should be this:

The console log after creating the course

But instead I am getting this:

The console log of the created the course at the details page

Since the form is passed and used to create the course in the blockchain and I do get the logs of what I sent, why does it log wrongly in the details? And this results in me not being able to use the fields.

Zod validation schema that has 2 options

If i have a the following schemas, how can i create final schema so that i get the results when instanceB is invalid if parsed because it does not hold all values for SchemaB.

const SchemaA = z.object({
  propA: z.string({ required_error: REQUIRED }),
  propB: z.number({ required_error: REQUIRED }),
});

const SchemaB = z.object({
  propA: z.string({ required_error: REQUIRED }),
  propB: z.number({ required_error: REQUIRED }),
  propC: z.boolean({ required_error: REQUIRED }),
  propD: z.string({ required_error: REQUIRED }),
  propE: z.string({ required_error: REQUIRED }),
});

const FinalSchema = ...

const instanceA = { propA: 'valueA', propB: 42 };
const instanceB = { propA: 'valueA', propB: 42, propC: true };
const instanceC = { propA: 'valueA', propB: 42, propC: true, propD: 'test', propE: 'test' };

const resultA = FinalSchema.parse(instanceA); // Valid
const resultB = FinalSchema.parse(instanceB); // Invalid
const resultC = FinalSchema.parse(instanceC); // Valid

I was originally using z.union([SchemaA, SchemaB])

However instanceB is valid because it hold all values for SchemaA. How can i solve this?

Text width affecting the the elements

I have this text with animation that is sliding from left to right and is now cycling through three messages, the problem is when the text when the text gets too long it affects the elements on it’s left side? What can I do to fix this?

And other one while the text animation is cycling through it always shows the first message first briefly before showing the next.

const messages = [
  "Celebrating 35 years of quality gear and expert support. Watch the video»",
  "FLASH SALE! Save and EXTRA $20 on ABC USB-C ABC ABC  4k Display Adapter»",
  "Free Shipping available on most orders $149.00 & up. Get Details»"
];

let currentMessageIndex = 0;
const rotatingTextElement = document.getElementById("animated-text");
rotatingTextElement.style.display = 'none'; // Hide the text initially

function rotateMessages() {
  rotatingTextElement.textContent = messages[currentMessageIndex];
  currentMessageIndex = (currentMessageIndex + 1) % messages.length;
  rotatingTextElement.style.display = 'block'; // Show the text after setting new content
}

window.addEventListener('DOMContentLoaded', (event) => {
  setInterval(rotateMessages, 10000);
  rotateMessages(); // Show the first message immediately
});
.news-bar {
    &__wrapper {
        background-color: #005ea4;
    }

    &__container {
        display: grid;
        grid-gap: 32px;
        grid-template-columns: repeat(12, 1fr);
        box-sizing: border-box;
        width: 100%;
        font-family: Exo;
        font-size: 13px;
        letter-spacing: 0.09px;
        line-height: 20px;
        color: #fff;

        .news-section {
            grid-column: span 5;
            width: max-content;
            overflow: hidden;
            white-space: nowrap;
            
            .text-container {
                animation: slide-in-out 10s linear infinite;
                white-space: nowrap;
                display: flex;
                justify-content: center;

                #animated-text {
                    display: inline-block;
                }
            }
            @keyframes slide-in-out {
                0% {
                  transform: translateX(0);
                }
                50% {
                  transform: translateX(0);
                }
                100% {
                  transform: translateX(-100%);
                }
              }

              @media (max-width: 425px) {
                  font-size: 10px;
              }
        }

        .details-section {
            grid-column: 9 /span 11;
            display: flex;
            align-items: center;
            justify-content: space-around;
            margin-left: 40px ;
            gap:  10px;

            @media (max-width: 1440px) {
                grid-column: 7 /span 6;
            }
            @media (max-width: 425px) {
                display: none;
            }

            .contacts-section {
                display: flex;

                @media (max-width: 768px) {
                        display: none;
                }
            }
            .region-section {
                margin: 0 25;
            }
            .contact-item {
                display: flex;
                align-items: center;
            }

            a {
                text-decoration: none;
                color: #fff;
                margin-left: 10px;
            }
            
            #selected-region {
                margin-left: 5px;
            }

            .links-section a {
                text-transform: capitalize;
            }

        }

        
      }
}

.menu {
    display: none;
    position: absolute;
    background-color: #fff;
    border: 1px solid #ccc;
    width: 207px;
    border-radius: 8px;
    box-shadow: 0 4px 12px 0 rgba(12, 62, 91, 0.16);
    z-index: 6;

    & hr {
        margin: 0;
        background-color: rgba(0, 92, 159, 0.24);
    }

    & .menu-section {
        padding: 16px;
        font-size: 13px;
        font-family: Exo;

        &.menu-section:last-of-type {
            background-color: #eff4f6;
        }
    }

    & a {
        display: block;
        text-decoration: none;
        color: #333; 
        padding: 5px 0; 

        & img {
            width: 24px;
            margin-right: 7px;
        }
    }
  }
<div class="news-bar__wrapper">
    <div class="news-bar__container container-new">
        <div class="news-section" >
            <div class="text-container">
                <p id="animated-text"></p>
            </div>
        </div>
        <div class="details-section">
            <div class="contacts-section">
                <a href="tel:1-800-275-4576" class="contact-item" id="contact1"><img src="imagelink" alt="Phone Icon">0-8000-000-4576</a>
                <a href="tel:1-815-338-8685" class="contact-item" id="contact2">Intl: 0-000-000-000</a>
            </div>
            <div class="region-section"> <p>Region:<span id="selected-region">USA/Intl</span> <img src="https://media.owcnow.com/image/upload/v1702916150/arrow_goxwmi.svg" alt="icon arrow" id="arrow"></p>
                
            </div>
            <div class="links-section">
                <a href="#">chat</a>
                <a href="#">support</a>
            </div>
        </div>
    </div>
</div>

I ran odoo community on docker and i got this erorr can someone tell me what happped and give me solution

enter image description here
enter image description here
..
Traceback (most recent call last):
File “/usr/lib/python3/dist-packages/odoo/http.py”, line 1734, in _serve_db
return service_model.retrying(self._serve_ir_http, self.env)
File “/usr/lib/python3/dist-packages/odoo/service/model.py”, line 133, in retrying
result = func()

I couldn’t find a way to solve it

log the id of an inner div on click [duplicate]

I am dynamically appending divs to a parent wrapper by looping through an array. After appending the inner div I attach an onclick event listener to each inner div that prints out the id of each innerDiv. Why is the below code only printing the id of the last appended innerDiv?

let arr = ['a', 'b', 'c']

const wrapper = document.querySelector('.wrapper')

for (var i = 0; i < arr.length; i++) {
  wrapper.innerHTML += `<div class="container" id="${arr[i]}"></div>`
  
  let container = document.querySelector(`#${arr[i]}`)
  
  container.onclick = (e) => {
    console.log(e.target.id)
  }
}
.wrapper {
  display: flex;
  flex-direction: column;
  row-gap: 15px;
  width: 500px;
  border: 2px solid #000;
}

.container {
  width: 100%;
  height: 80px;
  cursor: pointer;
  background-color: blue;
}
<div class="wrapper"></div>

How to update request headers in MV3 extension like we used to do in MV2 (chrome.webRequest.onBeforeSendHeaders.addListener)

I’m in the process of transitioning my MV2 extension to MV3. However, I’ve encountered an issue with conditional header modifications in the chrome.webRequest.onBeforeSendHeaders event. I’ve already updated my manifest file and added the necessary permissions. Can you provide guidance or a solution specifically for this header modification challenge during the MV3 migration?

window.chrome.webRequest.onBeforeSendHeaders.addListener(
    function(params) {
        'use strict';
        var headers = params.requestHeaders,
            url = params.url;
        if (Tabs.indexOf(parms.tabId) > -1) {
            for (var i = 0; i < headers.length; i++) {
                var currentUserAgent = edit.userAgent; 
                var currentHeader = headers[i];
                // Headers are only sent in case of device modes
                if (currentHeader.name.toLowerCase() === 'user-agent'){
                    currentHeader.value = currentUserAgent;
                }
                if (edit.device === 'android-phone') {
                    if (currentHeader.name.toLowerCase() === 'sec-ch-ua') {
                        currentHeader.value = '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"';
                    } else if (currentHeader.name.toLowerCase() === 'sec-ch-ua-mobile') {
                        currentHeader.value = '?1';
                    } else if (currentHeader.name.toLowerCase() === 'sec-ch-ua-platform') {
                        currentHeader.value = '"Android"';
                    }
                }
            }
        }

        return {
            requestHeaders: headers
        };
    },

    {
        urls: [
            '<all_urls>'
        ]
    }, ['blocking', 'requestHeaders']
);

I’m working on migrating my extension from Manifest V2 to Manifest V3, and I’m facing an issue with the following code not functioning in MV3. I’m aware of the chrome.declarativeNetRequest API, but I’m struggling to understand how to adapt this code to work with it. Can someone provide guidance or an explanation on how to achieve the same functionality using chrome.declarativeNetRequest in MV3?

How to use window event in parent React JSX window with Child JSP window

In one of the scenario I am redirecting an external JSP in a new window, keeping the source window open.

An event is triggering from JSP Page side which I am not able to read in React screen. In this scenario React screen is Parent window and JSP screen is Child window. As per the documentation in https://developer.mozilla.org/en-US/docs/Web/API/Window/message_event , I would be able to communicate between the parent and child window.

This is working in case where the parent and child window are in JSP, but in this case where parent is react screen and child window is in JSP it seems not be capturing. Although I am using the same syntax in both the case.
Below is the snippet for the Parent React and Child JSP. Am I missing some syntax or should it work in this case ?

Could anyone suggest or guide me through this issue.

    //Calling the external url
    
    var w=window.open("","","location=no,menubar=no,width=800,height=600,resizable=yes,toolbar=no,status=yes,scrollbars=yes")
    w.location("jsp_Page_URL")

//capturing the event from jsp
 
    onmessage = (event) => {
        console.log("INSIDE event", event)        

    }