Replacing modal with 4 modal buttons that open up to 4 videos

https://jsfiddle.net/hqoemz7k/3/

html:

<div id="ba" class="modal">
  <div class="inner-modal">
    <h2>Modal 1</h2>
    	<div class="ratio-keeper">
    <div class="video video-frame" data-id="AxLxnN6z0Og"></div>
    <div class="buttonA"></div></div>
    <button class="close">&times</button>
  </div>
</div>

javascript:

(function (d) {
  "use strict";

  const modalButtons = d.querySelectorAll(".playButton");
  const closeModalInfo = d.querySelectorAll(".modal");
  const closeModals = d.querySelectorAll(".close");

  modalButtons.forEach(function (button) {
    button.addEventListener("click", function () {
      var target = this.dataset.destination;
      openModal(target);
    });
  });

  function openModal(target) {
    d.querySelector(target).classList.add("active");
  }

  closeModals.forEach(function (modal) {
    modal.addEventListener("click", function () {
      this.closest(".modal").classList.remove("active");
    });
  });

  // Handle ESC key (key code 27)
  d.addEventListener("keyup", function (e) {
    if (e.keyCode === 27)
      closeModalInfo.forEach(function (modal) {
        modal.classList.remove("active");
      });
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    if (videoPlayer.players[0]) {
      videoPlayer.players[0].destroy();
    }
    resetPage();

    loadPlayer.add(".buttonA", {
      videoId: "CHahce95B1g"
    });
  }

})(document);

I hear my calling :slight_smile:
It is also unfortunate that I do not have the time to help Asasass here either.

I appreciate all the help, time, and dedication that you have given me, without it I would not know as much as I know now.

.buttonA now gives me a video: https://jsfiddle.net/uo1ry8np/

modalButtons.forEach(function (button) {
  button.addEventListener("click", function () {
    var target = this.dataset.destination;
    openModal(target);
    modalClickHandler(); // Call the function when a modal button is clicked
  });
});

At the code here: All videos launch: https://jsfiddle.net/Lt4asqn0/

Destroy player should occur after the close button is clicked, not button.

Each button needs to have its own javascript written for it.

Because, as soon as one button is clicked, each of the 3 videos launch, they don’t all play, but they all launch.

Currently, all the buttons are clickable, if I only want, .buttonA to be clickable, how do I do that here? https://jsfiddle.net/jedy1362/1/

forEach and All can be removed then.

I tried to do that here but I couldn’t figure it out.

(function (d) {
  "use strict";

  const modalButtons = d.querySelectorAll(".playButton");
  const closeModalInfo = d.querySelectorAll(".modal");
  const closeModals = d.querySelectorAll(".close");

modalButtons.forEach(function (button) {
  button.addEventListener("click", function () {
    var target = this.dataset.destination;
    openModal(target);
    modalClickHandler(); // Call the function when a modal button is clicked
  });
});

  function openModal(target) {
    d.querySelector(target).classList.add("active");
  }

  closeModals.forEach(function (modal) {
    modal.addEventListener("click", function () {
      this.closest(".modal").classList.remove("active");
    });
  });

  // Handle ESC key (key code 27)
  d.addEventListener("keyup", function (e) {
    if (e.keyCode === 27)
      closeModalInfo.forEach(function (modal) {
        modal.classList.remove("active");
      });
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    if (videoPlayer.players[0]) {
      videoPlayer.players[0].destroy();
    
       console.log("playerRemoved");
    }

    loadPlayer.add(".buttonA", {
      videoId: "CHahce95B1g"
    });
    
  }

})(document);

I need to have 2 separate functions, I think.

One for clicking on the button, another for clicking on the close button.
or, I’m confused here.

This here:

    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });

Should not occur after clicking on a button to play.

I did it here: Removed forEach and All https://jsfiddle.net/zber3wdh/

Next, the destroy player should occur after the close button is clicked, not after clicking button a 2nd time.

How do I fix that here?

(function(d) {
  "use strict";

  const modalButtons = d.querySelector(".ba");
  const closeModalInfo = d.querySelector(".modal");
  const closeModals = d.querySelector(".close");


  modalButtons.addEventListener("click", function() {
    var target = this.dataset.destination;
    openModal(target);
    modalClickHandler(); // Call the function when a modal button is clicked
  });

  function openModal(target) {
    d.querySelector(target).classList.add("active");
  }

  closeModals.addEventListener("click", function() {
    this.closest(".modal").classList.remove("active");
  });


  // Handle ESC key (key code 27)
  d.addEventListener("keyup", function(e) {
    if (e.keyCode === 27)

      closeModalInfo.classList.remove("active");
  });


  function modalClickHandler() {
    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });

    console.log("playerRemoved");

    loadPlayer.add(".buttonA", {
      videoId: "CHahce95B1g"
    });

  }

})(document);

First button working on its own: https://jsfiddle.net/gnhbcjf7/4/

(function manageButtonA() {

  const modalButtons = document.querySelector(".ba");
  const closeModalInfo = document.querySelector(".modal");
  const closeModals = document.querySelector(".close");

  modalButtons.addEventListener("click", function() {
    var target = this.dataset.destination;
    openModal(target);
    loadPlayer.add(".buttonA", {
      videoId: "CHahce95B1g"
    });
  });

  function openModal(target) {
    document.querySelector(target).classList.add("active");
  }

  closeModals.addEventListener("click", function() {
    this.closest(".modal").classList.remove("active");
    modalClickHandler(); // Moved the modalClickHandler() call to here
  });

  // Handle ESC key (key code 27)
  document.addEventListener("keyup", function(e) {
    if (e.keyCode === 27)
      closeModalInfo.classList.remove("active");
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });
    console.log("playerRemoved");
  }
}());

I don’t know how to add the below code to here: https://jsfiddle.net/gnhbcjf7/4/

My attempt: https://jsfiddle.net/Ldy07gk5/2/


I would want this to be what the modal opens to:

.modal-content {
  flex: 1 0 0;
  margin: auto;
  max-width: 640px;
  border: 21px solid;
  border-radius: 3.2px;
  border-color: #000 #101010 #000 #101010;
  position: relative;

  padding: 1px;
}

.modal-content::before {
  content: "";
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  background: #0a0a0a;
  border: 1px solid;
  border-color: #000 #101010 #000 #101010;
}

.modal-content:after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  border: 1px solid #0059dd;
  z-index: 2;
  pointer-events: none;
  /* just in case*/
}

:root {
  --wide: 8.8%;
  --angle1: 0;
  --angle2: -90;
}

.panel {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  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;
  z-index: 0;
  overflow: hidden;
  transform: translateY(0%);
  transition: 8s;
}

.panel.slide {
  transition-delay: 2s;
  transform: translateY(calc(-100% - 1px));
}

Last updated: https://jsfiddle.net/Lza4tke1/5/

Something isn’t right there.

That black horizontal block shouldn’t be there.

I think it has to do with this: transform: scale(0);

Can it be removed or something?

In addition to post #29

How come buttonA video is only showing?

How do I get the other ones to work?

    <button data-destination="#ba" class="playButton ba">ButtonA</button>
    <button data-destination="#bb" class="playButton bb">ButtonB</button>
    <button data-destination="#bc" class="playButton bc">ButtonC</button>

For me to have the javascript work with each button individually, what needs to be readjusted?

Only buttonA is working: https://jsfiddle.net/djxqetgk/1/

(function manageButtonA() {

  const modalButtons = document.querySelector(".ba");
  const closeModalInfo = document.querySelector(".modal");
  const closeModals = document.querySelector(".close");

  modalButtons.addEventListener("click", function() {
    var target = this.dataset.destination;
    openModal(target);
    loadPlayer.add(".buttonA", {
      videoId: "CHahce95B1g"
    });
  });

  function openModal(target) {
    document.querySelector(target).classList.add("active");
  }

  closeModals.addEventListener("click", function() {
    this.closest(".modal").classList.remove("active");
    modalClickHandler(); // Moved the modalClickHandler() call to here
  });

  // Handle ESC key (key code 27)
  document.addEventListener("keyup", function(e) {
    if (e.keyCode === 27)
      closeModalInfo.classList.remove("active");
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });

    console.log("playerRemoved");

  }
}());
(function manageButtonB() {

  const modalButtons = document.querySelector(".bb");
  const closeModalInfo = document.querySelector(".modal");
  const closeModals = document.querySelector(".close");

  modalButtons.addEventListener("click", function() {
    var target = this.dataset.destination;
    openModal(target);
    loadPlayer.add(".buttonB", {
      videoId: "CHahce95B1g"
    });
  });

  function openModal(target) {
    document.querySelector(target).classList.add("active");
  }

  closeModals.addEventListener("click", function() {
    this.closest(".modal").classList.remove("active");
    modalClickHandler(); // Moved the modalClickHandler() call to here
  });

  // Handle ESC key (key code 27)
  document.addEventListener("keyup", function(e) {
    if (e.keyCode === 27)
      closeModalInfo.classList.remove("active");
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });

    console.log("playerRemoved");

  }
}());
(function manageButtonC() {

  const modalButtons = document.querySelector(".bc");
  const closeModalInfo = document.querySelector(".modal");
  const closeModals = document.querySelector(".close");

  modalButtons.addEventListener("click", function() {
    var target = this.dataset.destination;
    openModal(target);
    loadPlayer.add(".buttonB", {
      videoId: "CHahce95B1g"
    });
  });

  function openModal(target) {
    document.querySelector(target).classList.add("active");
  }

  closeModals.addEventListener("click", function() {
    this.closest(".modal").classList.remove("active");
    modalClickHandler(); // Moved the modalClickHandler() call to here
  });

  // Handle ESC key (key code 27)
  document.addEventListener("keyup", function(e) {
    if (e.keyCode === 27)
      closeModalInfo.classList.remove("active");
  });

  function modalClickHandler() {
    // Destroy the first player if it exists
    videoPlayer.players.forEach(function(player) {
      player.destroy();
    });

    console.log("playerRemoved");

  }
}());

Last Updated code: https://jsfiddle.net/14qpmdrc/1/

Target removed

Trying to do this: https://jsfiddle.net/1cj07rsm/3/

I removed closest: targeting each class individually: .modalC

Will doing this work in the code?

  const modalButtons = document.querySelector(".bc");
  const closeModalInfo = document.querySelector(".modalC");
  const closeModal = document.querySelector(".closeC");

  modalButtons.addEventListener("click", function() {
    openModal();
    loadPlayer.add(".buttonC", {
      videoId: "CHahce95B1g"
    });
  });

  function openModal() {
    closeModalInfo.classList.add("active");
  }

closeModal.addEventListener("click", function() {
    closeModalInfo.classList.remove("active");
    modalClickHandler(); // Moved the modalClickHandler() call to here
});

Last Updated: https://jsfiddle.net/Lkymo8ej/4/

Panels and video loaded.

At the code here: https://jsfiddle.net/Lkymo8ej/9/

I am trying to have the close button fadein after after curtain is done.

Why is it not, I don’t understand.

The fadein of the close button would occur only when the curtain is visible on the screen.

Button is not fading in.

Why?

I was supposed to add foreach to close also, right?

const panels = document.querySelectorAll(".panel");

  panels.forEach(function(panel) {
    panel.classList.add("slide");

  const closeButtons = panel.querySelectorAll(".close");
  closeButtons.forEach(function (closeButton) {
    const makeVisible = function () {
      closeButton.classList.add("visible");
      panel.removeEventListener("transitionend", makeVisible);
    };

    panel.addEventListener("transitionend", makeVisible);
  });
});
}

css:

 opacity: 0;
  transition: opacity 3s ease-in;
  transition-delay: 1s;
  pointer-events: none;
}

.close.visible {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

Still haven’t been able to figure out how to remove black rectangle square from video.

I don’t know how many times I can keep saying it but why do you keep duplicating the code when I have given you a function to do all of them in one go?

Here are all the videos opening with just the one function.

You can add more videos by simply adding a couple of lines to the switch statement, You don’t need to keep adding 50 lines of code for each.

Do things one step at a time. Get the videos working first and then move onto your other features afterwards,

2 Likes

That is much better.

How do I have the curtain be there when the button is clicked on a 2nd time?

Now. the close button fades in. https://jsfiddle.net/mL1n64ra/3/

And would it be possible to have the curtain come down after clicking the close button?

const panels = document.querySelectorAll(".panel");
const closeButtons = document.querySelectorAll(".close");

panels.forEach(function(panel) {
  panel.addEventListener("transitionend", function () {
    closeButtons.forEach(function(closeButton) {
      closeButton.classList.add("visible");
    });
  });
});

It is there isn’t it. I removed the slide class when you closed the modal so the black curtain should be covering the video. Or did you mean something else?

Do you mean you want the black curtain so slide down before it goes back to the three buttons again?

Click on buttonA a 2nd time.

It doesn’t go back to its reset state.

curtain down, button fades in.

If that’s what you mean then you would need to look at delaying the removal of the active class until the animation is finished.

It would need to go in this routine.

closeModals.forEach(function (modal) {
    modal.addEventListener("click", function () {
      var currentModal = this.closest(".modal");
      //currentModal.classList.remove("active");
      currentModal.querySelector(".panel").classList.remove("slide");
      modalClickHandler();
    });
  });

I have just commented out the removal of the active class and you can see that the curtain does slide down.

What you would need to do is delay the removal of the active class and also delay the modalClickHandler() from running.

You could put the calls to these two inside an transitionend event for that curtain and when finished remove the active class and then call modalclickhandler. You have done this before. The code could be inserted at the same place or in another function.

e.g. In pseudo code - this is not real,…

closeModals.forEach(function (modal) {
    modal.addEventListener("click", function () {
      var currentModal = this.closest(".modal");
      currentModal.querySelector(".panel").classList.remove("slide");
     // check here for animation end event on this panel then  
     //  currentModal.classList.remove("active");    
    // modalClickHandler();
 });
  });

That should result in something like this (this is real).


closeModals.forEach(function(modal) {
    modal.addEventListener("click", function() {
      var currentModal = this.closest(".modal");
      const animated = currentModal.querySelector(".panel");
      currentModal.querySelector(".panel").classList.remove("slide");

      animated.addEventListener("transitionend", () => {
        console.log("Animation ended");
        currentModal.classList.remove("active");
        modalClickHandler();
      });

    });
  });

You could offload that into another little function if you wanted it neater but best to get it working first.

If you still want to handle the escape key to close the modal then you’d need to replicate that transitionend function but of course with the correct targets as the escape function travels from the top down and not from a button up.

Yes it does, Its on its way, It takes the transition time you set for it to close. You could remove the transition dele=ay from the normal state and only have it on the slide class,

However that doesn’t matter now that you want the curtain to close before you leave which means it will be closed when you visit it again and open as usual. Try the last code I posted before you make any changes again.

The close button doesn’t fade in after clicking on a button a 2nd time: https://jsfiddle.net/28nhsx16/

I thought you could work that out yourself. :slight_smile: You have to remove the visible class just like the slide class etc.

I would do this now:

  function openModal(target) {
    d.querySelector(target).classList.add("active");
    d.querySelector(target + " .panel").classList.add("slide");
    d.querySelector(target + " .close").classList.add("visible");
  }

  closeModals.forEach(function(modal) {
    modal.addEventListener("click", function() {
      var currentModal = this.closest(".modal");
      const animated = currentModal.querySelector(".panel");
      currentModal.querySelector(".panel").classList.remove("slide");

      animated.addEventListener("transitionend", () => {
        console.log("Animation ended");
        currentModal.classList.remove("active");
        currentModal.querySelector(".close").classList.remove("visible");
        modalClickHandler();
      }, {once : true});

    });
  });

Then you can remove all this;

/*
const panels = document.querySelectorAll(".panel");
const closeButtons = document.querySelectorAll(".close");

panels.forEach(function(panel) {
  panel.addEventListener("transitionend", function() {
    closeButtons.forEach(function(closeButton) {
      closeButton.classList.add("visible");
    });
  });
});
*/

You may need to adjust the timing in the css so that the button fades out quickly when you close or it will still be half way through if you click again quickly.

Like this:

.close {
  transform: translatey(100%);
  position: absolute;
  inset: 0 0 0 0;

  /*margin: auto auto 0;*/
  top: auto;
  bottom: -1px;
  margin: auto;
  right: 0;
  left: 0;
  /*margin: 10px auto 0;*/
  width: 47px;
  height: 47px;
  background: blue;
  border-radius: 50%;
  border: 5px solid red;
  display: flex;
  align-items: center;
  justify-content: center;

  opacity: 0;
  transition: opacity .5s ease-in;
  transition-delay: 0s;
  pointer-events: none;
}

.close.visible {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
  transition: opacity 3s ease-in;
  transition-delay: 6s;
}
1 Like