How do I get multiple Modal instances to properly function in one page?

I’m creating a team page with modal popups for bio.

I’m using Hugo with Babel JS as the framework. There is no bootstrap on this project.

HTML

<div class="team-ui">
{{ with .Params.executive_team }}
   {{ range . }}
      {{ partial "components/modalTeammate.html" . }}
   {{ end }}
{{ end }}
</div>

{{ with .Params.executive_team }}
   {{ range . }}
      {{ partial "components/modalTeammateBio.html" . }}
   {{ end }}
{{ end }}

modalTeammate.html

<div class="teammate-card trigger" data-id="#myBio-{{ .modal_id }}" data-toggle="modal" data-target="myBio-{{ .modal_id }}" id="trigger">
    <img src="{{ if .img_overwrite }}/uploads/headshot-{{ .img_overwrite }}.png{{ else }}/uploads/headshot-{{ .name }}.png{{ end }}" alt="{{ .name }} | {{ .job_title }}" loading="lazy" class="teammate-img">
    <p class="teammate-name">{{ .name }}</p>
    <p class="teammate-jobtitle">{{ .job_title }}</p>
</div>

modalTeammateBio.html

<div class="modal myBio-{{ .modal_id }}" tabindex="-1" role="dialog" aria-hidden="true" id="myBio-{{ .modal_id }}">
    <div class="modal-content">
        <div class="modal-body">
            <div class="bio-box">
                <div class="bio-box-sidebar">
                    <img src="{{ if .img_overwrite }}/uploads/headshot-{{ .img_overwrite }}.png{{ else }}/uploads/headshot-{{ .name }}.png{{ end }}" alt="{{ .name }} | {{ .job_title }}" loading="lazy" class="teammate-img">
                    <p class="teammate-name">{{ .name }}</p>
                    <p class="teammate-jobtitle">{{ if .job_title_long }}{{ .job_title_long }}{{ else }}{{ .job_title }}{{ end }}</p>
                </div>
                <div class="bio-box-content">
                {{ with .bio }}
                    {{ range . }}
                    <p class="has-margin-bottom-half">{{ .p }}</p>
                    {{ end }}
                {{ end }}
                </div>
                <button class="modal-close is-large" aria-label="close"></button>
            </div>
        </div>
    </div>
</div> 

Current JS

var modal = document.querySelector(".modal");
var trigger = document.querySelector(".trigger");
var videoID = trigger.getAttribute('data-id');
var closeButton = document.querySelector(".modal-close");

// YouTube Player API Reference
var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        height: '390',
        width: '640',
        videoId: videoID
    });
}

function toggleModal(e) {
    if (!modal.classList.contains("is-active")) {
        modal.classList.add("is-active");
        player.playVideo()
    }
    else {
        modal.classList.remove("is-active");
        player.pauseVideo()
    }
}

function windowOnClick(e) {
    if (e.target === modal) {
        toggleModal();
    }
}

trigger.addEventListener("click", toggleModal);
closeButton.addEventListener("click", toggleModal);
window.addEventListener("click", windowOnClick);

I know I’m missing something, but I’m not sure what else I can do.

I’m using this oringal code as an example and a base.

<a href="#" data-id="{{.Get "youtube"}}" class="button is-warning trigger" data-toggle="modal" id="trigger">Watch the Video</a>
<div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-content">
        <div class="modal-body" id="player">
            Content
        </div>
    </div>
    <button class="modal-close is-large" aria-label="close"></button>
</div>

<script src="/js/modal.js"></script>

Make div disappear when clicking anywhere outside of it?

I am trying to make my div element disappear when clicking anywhere out side of it. The div is created when clicking a path from my SVG element and is supposed to close and open a new one when clicking the another path in the SVG. I think I may have set this up wrong and have been trying to figure out the most effective way to get it working. The div that has been created will hold an X button that will close the div and reload the page to bring back the styling options. Would that be the best way to go about this because I am thinking that may not be the most efficient way to do this.

$(document).ready(function(){
    $("#SVGGraphic").load("/src/Areas-of-Focus.svg", function(event){
        $("#SVGGraphic svg").css("height", "1000", "width", "1000px");

        console.log("loaded successfully")
        
        $("path").on("click", function(evt) {
            var parsedStringArray = evt.target.id.split('_');
            var pathID = ("#" + (evt.target.id))
            console.log(parsedStringArray);
            areaOfFocusBody(parsedStringArray[0]);
            colorChanger(pathID); 
        });
    })
})
function colorChanger(pathName){
    $("path").css("filter", "opacity(25%)")
    $("circle").css("filter", "opacity(25%)")
    $(pathName).css("fill", "#f1562c")
    $(pathName).css("filter", "opacity(100%)")
}

function areaOfFocusBody(areaOfFocus) {
    $("#DOM").append(`
    <div class="textbox" id="menucontainer">
        <span id="close" onclick="this.parentNode.remove(); location.reload(); return false;" class="btn btn-default large">
            <img src="/src/Esc X.svg" height="33" width="33"></img>
        </span>
        <h2>${focusCard[areaOfFocus]?.title ?? 'none'}</h2>
        <div class="card-body" id="card-div">
            <p class="card-body" style="padding: 1rem">${focusCard[areaOfFocus]?.body ?? 'none'}</p>
            <div class="container">
                <div class="row">
                    <div class="col text-center" style="padding-bottom: 1rem;">
                        <a target="_blank" rel="noopener noreferrer" href="${focusCard[areaOfFocus]?.url ?? 'none'}">
                            <button class="btn btn-primary" role="button">
                                Show Employees in this Section <img src="/src/opens-new-tab-arrow.svg" height="20">
                            </button>
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </div>`)
}

Before Click Event
After Click Event

How to not add to history entry within iFrame

Problem: So I have a iFrame page within my main page. Whenever I interact within the iFrame within the main page, im assuming its adding on more entrees to the history because whenever I click back “to go back to the last main page” I have to click it multiple times (2-3 times).

Solution: I just need to not log the entires when within the iFrame. So when I click the back button it will go back to the last main page and not within the iFrame.

Heres my current code

export function showPage(newUrl: string): void {
  const page1 = document.getElementById('showpage');

  page1.setAttribute('src', `${page1Href}#${newUrl}`);


  page.style.display = 'block';
}

What I think I need to do is this solution:

var frame = $('#myIFrame')[0];  
frame.contentWindow.location.replace(newUrl);

but when I do this, it just throws a Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'contentWindow') which is because the frame is null. How do I fix this?

And this solution also might cause a CORS/security risk as well. So im not sure of the best solution here either. I have tried a few things to just replace the history but I cant get it to work. Any help would be greatly appreciated.

Having trouble using howler

The music plays and then does not pause. Also, when I play the music instead of playing from start it plays double. Here is the screenshot of the page

below I am attaching the code, please can someone help me use howler correctly?

p.s ignore the backend code get request

import React, { useState } from "react";
import "./LikedSongs.css";
import Sidebar from "./Sidebar";
import { useEffect } from "react";
import axios from "axios";
import { Howl } from "howler";

function Song(props) {
  function handleSong(e) {
    e.preventDefault();
    props.handleSongClick(props.song);
  }

  return (
    <div>
      <li className="songItem" onClick={handleSong}>
        <span>{props.song.count}</span>
        <h5>
          {props.song.songname}
          <div className="subtitle">{props.song.artistname}</div>
        </h5>
        <div className="album">{props.song.Albumname}</div>
      </li>
    </div>
  );
}

const initialValueOfSongs = [
  {
    songname: "On my way",
    artistname: "Alan Walker",
    Albumname: "On my way",
    songlink:
      "https://dl.dropboxusercontent.com/s/rfz0s49idtk3rhl/Canon%20In%20D.mp3?dl=0",
  },
  {
    songname: "Aitebar",
    artistname: "Abdullah Qureshi",
    Albumname: "Aitebar",
  },
  {
    songname: "On my way",
    artistname: "Alan Walker",
    Albumname: "On my way",
  },
  {
    songname: "On my way",
    artistname: "Alan Walker",
    Albumname: "On my way",
  },
  {
    songname: "On my way",
    artistname: "Alan Walker",
    Albumname: "On my way",
  },
];

export default function LikedSongs() {
  const [selectedSong, setSelectedSong] = useState(initialValueOfSongs[0]);
  const [songs, setSongs] = useState(initialValueOfSongs);
  const [play, setPlay] = useState(require("./playbutton.png"));
  
  var src = selectedSong.songlink;
  var sound = new Howl({
    src,
    html5: true,
    preload: true,
    loop: true,
  });
  
  useEffect(() => {
    fetchdata();
  }, []);

  const callMySound = () => {
    sound.play();
    setPlay(require("./pause.png"));
  };

  const handleplay= ()=>{
    if(play===require("./pause.png")){
      sound.pause()
      setPlay(require("./playbutton.png"))
    }
    else{
      sound.play()
      setPlay(require("./pause.png"))
    }
  }

  async function fetchdata() {
    const response = await axios.get("http://localhost:5000/songs");
    const songs = response.data;
    var count = 1;
    songs.forEach((song) => {
      song["count"] = count;
      count++;
    });
    setSongs(songs);
  }

  const handleSongClick = (song) => {
    setSelectedSong(song);
    callMySound();
    console.log(sound);
  };

  return (
    <div className="songsbody">
      <Sidebar />
      <div className="listsongs">
        <li className="songItem top">
          <span>#</span>
          <h5>Song name</h5>
          <div className="album">Album name</div>
        </li>
        {songs &&
          songs.map((song) => (
            <Song
              key={song.count}
              song={song}
              handleSongClick={handleSongClick}
            />
          ))}
      </div>
      <div className="footer">
        <div className="footer_left">
          <img
            className="footer_albumLogo"
            src="https://i1.sndcdn.com/artworks-aHWeKTP05eBf-0-t500x500.jpg"
            alt=""
          />

          <div className="footer_songInfo">
            <h6>{selectedSong.songname}</h6>
            <p>{selectedSong.artistname}</p>
          </div>
        </div>

        <div className="footer_center">
          <img className="shuffle" src={require("./shuffle.png")} alt="" />
          <img className="back" src={require("./back.png")} alt="" />
          <img className="playbutton" src={play} alt="" onClick={handleplay}/>
          {/* <img className="pause" src={require("./pause.png")} alt=""/> */}
          <img className="next" src={require("./next.png")} alt="" />
          <img className="repeat" src={require("./repeat.png")} alt="" />
        </div>

        <div className="footer_right">
          <img className="volume" src={require("./volume.png")} alt="" />
        </div>
      </div>
    </div>
  );
}

I tried a bunch of functions and methods, making the new howl global etc, but doesnt work correctly. Also, I am new to reactjs, hence may not know the correct way to do this.

Trying to compare two simple strings and its not working

I have an array:

let ids = ["d0","d1","d2","d3","d4","d5","m0","m1","m2","m3","m4","m5"];

I have a bunch of html elements with the same id’s

<button id="d0" onclick="showMe(this);"> //etc etc... all the way to m5

I compare them with

function showMe(element){
var whoWasClicked = element;
   let ids = ["d0","d1","d2","d3","d4","d5","m0","m1","m2","m3","m4","m5"];

    for (let i = 0; i < ids.length; i++) {
        if (whoWasClicked.id != document.querySelector(ids[i])) {
           //document.querySelector(ids[0]).style.border = "none";
            console.log(ids[i] + " : " + whoWasClicked.id);
        }
    }
}

I then get the following output:

d0 : d1
d1 : d1
d2 : d1
d3 : d1
d4 : d1
d5 : d1
m0 : d1
m1 : d1
m2 : d1
m3 : d1
m4 : d1
m5 : d1

They are both of type “string”, so how is it possible to see

d1 : d1

as an output? shouldnt d1 not be shown and all the others be shown?

How to refactor my code so it’s not repeating the same thing

I have 3 different buttons on my page, and when you click on one it checks the corresponding radio button.

Currently I have each button with it’s own onclick function:
onclick="radioChecked1()"
onclick="radioChecked2()"
onclick="radioChecked2()"

And then here are the functions:
`

function radioChecked1() {
    var package1 = document.querySelector("#package1");
        package1.setAttribute("checked", 1);
    }
    function radioChecked2() {
        var package2 = document.querySelector("#package2");
        package2.setAttribute("checked", 1);
    }
    function radioChecked3() {
        var package3 = document.querySelector("#package3");
        package3.setAttribute("checked", 1);
}

`

These functions are doing the same thing, the only thing that changes is the number in the id of the input it’s selecting. I’m sure there’s a way to simplify this into one function instead of a separate one for each button, I just don’t know how to do it.

javascript push to object that contains key [closed]

How do I push the sample object below to this.tableData.columns.actions without looping since they are multiple objects inside the columns array ?

So basically I want it to push the object to actions array.

#object to push

let a = {icon:’insert_chart’, name: ‘Send’, class:’primary-color’, disabled : false},

#original object

this.tableData = {
      columns:[
    {id:'name',name:'Name'},
        {id:'description',name:'Deal Description'},
        {id:'action', name: 'Actions', actions:[
          {icon:'file_copy', name:'Copy', class:'primary-color' , },
          {icon:'delete', name: 'Delete', class:'mat-error ml-7px', disabled : false},
        ]}
   ],

#finalOutput

{
      columns:[
    {id:'name',name:'Name'},
        {id:'description',name:'Deal Description'},
        {id:'action', name: 'Actions', actions:[
          {icon:'file_copy', name:'Copy', class:'primary-color' , },
          {icon:'delete', name: 'Delete', class:'mat-error ml-7px', disabled : false},
          {icon:'insert_chart', name: 'Send', class:'primary-color', disabled : false},
        ]}
   ],

Add css linear-gradient background image to canvas background

So I have a background gradient style

background-image: linear-gradient(to top, #1c1d22, #28292e, #34353a, #404247, #4d4f54);

I also have a canvas element I wish too use that gradient as the background.

I know you can draw an image as a background on the canvas ::

var background = new Image();
background.src = "http://www.example.com/image.jpb";

^ similar above, but I don’t know how to set the linear-gradient style I have for my div background in css as the background for my canvas.

I’ve tried making the background of the canvas transparent and the div behind the style, but was unable too.

I tried Canvas background transparent and background div having the background.

populate an array from the @input array in angular

I have an array coming from @input like this:

export interface XXModel {
  id: number;
  category: string;
  serialNumber: string;
  description: string;
}
@Input() assets: XXModel[];

I created another array to get the Id and description from the previous array to use this array to provide data to a component in the html

public _assets:{key:number, value:string}[];

how can I fill the _assets array with id and description from the assets array to populate component in html receive data from _assets array .

I tried this approach but I get undefined and its not working:

@Input() assets: XXModel[];
public _assets:{key:number, value:string}[];
ngOnInit() {
this.assets.map(item => {
if(item){
const {id, description} = item;
this._assets.push({key:id, value:description});
}
});

console.log(this._assets)
}

also I tried this way :

@Input()
get assets(): MaintenanceAssetModel[] {
  return this._assets as any
}
set assets(value: MaintenanceAssetModel[]) {
  value.map(asset=>{
    this._assets.push({key:asset.id,value:asset.description})
  })
}
public _assets: {key:number, value:string}[];

Javascript – Prevent window refresh when use focus

I have to implement the next requirement: From a specified page I have to open a new page (new browser tab, lets call it Live tab) and focus on it. Only one Live tab can be opened at a time

What I’ve tried is

const win = this.window.open(url, 'New tab');
win?.focus();

This is working as expected but if the Live tab is already opened, the focus operation triggers a refresh of the Live tab every time.

Can we prevent this somehow ?

Creating a slidable event timeline in react

I want to create something like this.

enter image description here

It is an event timeline in which you can slide the middle bar left and right, where the different colors represent different events throughout the time period.

I have tried react-timeline-range-slider but I don’t really need a range, just a single bar.

Are there any terms for this type of component? If not, are there any good implementation tips to create this type of component.

Issue Uppercase in .liquid

I want to put a capital letter at the beginning of each word in the variable {{ article.author }} thanks to the script at the bottom of the page which works because I am fetching the variable with capital letters in the console.

enter image description here

But I don’t poorly understand the variable is displayed in uppercase on the site.

Name of author in uppercase

Do you have an idea ?

{%- if article and article != empty -%}
  {%- liquid
    assign ratio = 1
    if media_aspect_ratio != nil
      assign ratio = media_aspect_ratio
    endif
  -%}
  <div class="card-wrapper underline-links-hover">
    {% comment %} <article aria-labelledby="Article-{{ article.id }}"> {% endcomment %}
    <div class="card article-card
      card--{{ settings.card_style }}
      {% if media_height and media_height != 'adapt' %} article-card__image--{{ media_height }}{% endif %}
      {% if article.image and show_image %} card--media{% else %} card--text{% endif %}
      {% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
      {% if settings.card_style == 'card' and media_height == nil and article.image == empty or show_image == false %} ratio{% endif %}"
      style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
    >
      <div class="card__inner {% if settings.card_style == 'standard' %} color-{{ settings.card_color_scheme }} gradient{% endif %}{% if article.image and show_image or settings.card_style == 'standard' %} ratio{% endif %}" style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;">
        {%- if show_image == true and article.image -%}
          <div class="article-card__image-wrapper card__media">
            <div class="article-card__image media media--hover-effect" {% if section.settings.media_height == 'adapt' %} style="padding-bottom: {{ 1 | divided_by: article.image.aspect_ratio | times: 100 }}%;"{% endif %}>
              {% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
              <img
                srcset="{%- if article.image.src.width >= 165 -%}{{ article.image.src | image_url: width: 165 }} 165w,{%- endif -%}
                  {%- if article.image.src.width >= 360 -%}{{ article.image.src | image_url: width: 360 }} 360w,{%- endif -%}
                  {%- if article.image.src.width >= 533 -%}{{ article.image.src | image_url: width: 533 }} 533w,{%- endif -%}
                  {%- if article.image.src.width >= 720 -%}{{ article.image.src | image_url: width: 720 }} 720w,{%- endif -%}
                  {%- if article.image.src.width >= 1000 -%}{{ article.image.src | image_url: width: 1000 }} 1000w,{%- endif -%}
                  {%- if article.image.src.width >= 1500 -%}{{ article.image.src | image_url: width: 1500 }} 1500w,{%- endif -%}
                  {{ article.image.src | image_url }} {{ article.image.src.width }}w"
                src="{{ article.image.src | image_url: width: 533 }}"
                sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | divided_by: 2 }}px, (min-width: 750px) calc((100vw - 130px) / 2), calc((100vw - 50px) / 2)"
                alt="{{ article.image.src.alt | escape }}"
                class="motion-reduce"
                {% unless lazy_load == false %}loading="lazy"{% endunless %}
                width="{{ article.image.width }}"
                height="{{ article.image.height }}"
              >
              {% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
            </div>
          </div>
        {%- endif -%}
        <div class="card__content">        
          <div class="card__information">
            <h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
              <a href="{{ article.url }}" class="full-unstyled-link">
                {{ article.title | truncate: 50 | escape }}
              </a>
            </h3>
            <div class="article-card__info caption-with-letter-spacing h5">
              {%- if show_date -%}
                <span class="circle-divider">{{ article.published_at | time_tag: '%d/%m/%Y' }}</span>
              {%- endif -%}
              {%- if show_author -%}
                <span id="blog_author">{{ article.author }}</span>
              {%- endif -%}
            </div>
            {%- if show_excerpt -%}
              {%- if article.excerpt.size > 0 or article.content.size > 0 -%}
                <p class="article-card__excerpt rte-width">
                  {%- if article.excerpt.size > 0 -%}
                    {{ article.excerpt | strip_html | truncatewords: 30 }}
                  {%- else -%}
                    {{ article.content | strip_html | truncatewords: 30 }}
                  {%- endif -%}
                </p>
              {%- endif -%}
              <div class="article-card__footer">
                {%- if article.comments_count > 0 and blog.comments_enabled? -%}
                  <span>{{ 'blogs.article.comments' | t: count: article.comments_count }}</span>
                {%- endif -%}
              </div>
            {%- endif -%}
          </div>
          {%- if show_badge -%}
            <div class="card__badge {{ settings.badge_position }}">
              <span class="badge color-background-1">{{ 'blogs.article.blog' | t }}</span>
            </div>
          {%- endif -%}
        </div>
      </div>
      <div class="card__content">
        <div class="card__information">
          <h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
            <a href="{{ article.url }}" class="full-unstyled-link">
              {{ article.title | truncate: 50 | escape }}
            </a>
          </h3>
          <div class="article-card__info caption-with-letter-spacing h5">
            {%- if show_date -%}
              <span class="circle-divider">{{ article.published_at | time_tag: '%d/%m/%Y' }}</span>
            {%- endif -%}
            {%- if show_author -%}
              <span id="blog_author">{{ article.author }}</span>
            {%- endif -%}
          </div>
          {%- if show_excerpt -%}
            {%- if article.excerpt.size > 0 or article.content.size > 0 -%}
              <p class="article-card__excerpt rte-width">
                {%- if article.excerpt.size > 0 -%}
                  {{ article.excerpt | strip_html | truncatewords: 30 }}
                {%- else -%}
                  {{ article.content | strip_html | truncatewords: 30 }}
                {%- endif -%}
              </p>
            {%- endif -%}
            <div class="article-card__footer">
              {%- if article.comments_count > 0 and blog.comments_enabled? -%}
                <span>{{ 'blogs.article.comments' | t: count: article.comments_count }}</span>
              {%- endif -%}
            </div>
          {%- endif -%}
        </div>
        {%- if show_badge -%}
          <div class="card__badge {{ settings.badge_position }}">
            <span class="badge color-background-1">{{ 'blogs.article.blog' | t }}</span>
          </div>
        {%- endif -%}  
      </div>
    </div>
  </div>
{%- endif -%}


<script>
var span = document.getElementById("blog_author").innerText.toLowerCase().replace(/b(w)/g, x => x.toUpperCase());
  console.log(span);
</script>

is there a way to store my svelte store in local storage so it doesn’t reset on page refresh?

the content I fetch from my svelte store disappears on page refresh, is there a way to stop it from resetting so it can stay on the page even when i reload? sorry if the question is a little vague im not sure how to really phrase it.

svelte store

import { writable } from "svelte/store";

export const leagueTable = writable([]);

const fetchTable = async () => {
    const url = `https://soccer.sportmonks.com/api/v2.0/standings/season/19734?api_token=API_KEY`;
    const res = await fetch(url);
    const data = await res.json();
    leagueTable.set(data.data);
}
fetchTable();

component

<script>
    import { leagueTable } from "../stores/league-standings-stores"
    console.log($leagueTable)
    const tableMaps = $leagueTable.map($leagueTable => $leagueTable.standings.data).flat();
    console.log(tableMaps)
</script>

{#each tablePositions as tablePosition}
  <div class="standings-table flex gap-9 mb-2 pb-4 pt-3 border-b border-[#303041]">
       <div class="team-details flex gap-4 w-full" id="td">
        <p class="w-[18px]">{tablePosition.position}</p>
         <img src="{tablePosition.team.data.logo_path}" alt="" class="w-[1.5em] object-scale-down">
          <p class="">{tablePosition.team_name}</p>
      </div>

      <div class="team-stats flex gap-5 text-left child:w-5 child:text-center w-full">
        <p>{tablePosition.overall.games_played}</p>
        <p>{tablePosition.overall.won}</p>
        <p>{tablePosition.overall.draw}</p>
        <p>{tablePosition.overall.lost}</p>
        <p>{tablePosition.overall.goals_scored}</p>
        <p>{tablePosition.overall.goals_against}</p>
        <p>{tablePosition.total.goal_difference}</p>
        <p>{tablePosition.overall.points}</p>
        <p class="!w-[78px] !text-left">{tablePosition.recent_form}</p>
      </div>
 </div>
{/each}