2

I have a multiple modal that loads on my home page. If the user accidentally closes the modal while he is in modal#2, for example, I want the modal to be displayed again where it left off in 12 hours, for example.

I understand this could be done with cookies or maybe localstorage, but I'm new to js and don't have any idea how to achieve this requirement. I appreciate any help, thanks.

This is the code I have at the moment

const openModal1 = () => {
  window.location.href = "#openModal1";
}

const openModal2 = () => {
  window.location.href = "#openModal2";
}

const openModal3 = () => {
  window.location.href = "#openModal3";
}

window.location.href = "#openModal1";

function start() {
  openModal2();
}

const btn_next = () => {;
  openModal3();
}
.modalDialog {
  position: fixed;
  font-family: 'Poppins', sans-serif;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.8);
  z-index: 99999;
  opacity: 0;
  -webkit-transition: opacity 400ms ease-in;
  -moz-transition: opacity 400ms ease-in;
  transition: opacity 400ms ease-in;
  pointer-events: none;
}

.modalDialog:target {
  opacity: 1;
  pointer-events: auto;
}

.modalDialog>div {
  width: 500px;
  position: relative;
  margin: 10% auto;
  padding: 26px;
  border-radius: 2em;
  background: #fff;
}
<div id="openModal1" class="modalDialog" data-modalorder="1">
  <div>
    <a href="#close" title="Close">X</a>
    <h1>Content modal 1</h1>
    <input type="button" onclick="start()" value="Start">
  </div>
</div>
<div id="openModal2" class="modalDialog" data-modalorder="2">
  <div>
    <a href="#close" title="Close">X</a>
    <h1>Content modal 2</h1>
    <input type="button" onclick="btn_next()" value="Next">
  </div>
</div>
<div id="openModal3" class="modalDialog" data-modalorder="3">
  <div>
    <a href="#close" title="Close">X</a>
    <h1>Content modal 3</h1>
    <input type="button" onclick="" value="Next">
  </div>
</div>
KooiInc
  • 119,216
  • 31
  • 141
  • 177
Coc L
  • 27
  • 3

2 Answers2

0

One method is to listen for hashchange event and store location.hash in localStorage or cookies. Here is an example with localStorage https://jsfiddle.net/jxy7oznm/

const openModal1 = () => {  
window.location.href = "#openModal1"; 
}

const openModal2 = () => {
window.location.href = "#openModal2";            
}

const openModal3 = () => {
window.location.href = "#openModal3";
}

function start(){  
openModal2();
}

const btn_next = () =>{
openModal3(); 
}

const settingName = "page"; //name of the setting that will be stored in localStorage
init();

function init()
{
    //listen for hash change event
    window.addEventListener("hashchange", e =>
  {
    //remove #
    let page = location.hash.substring(1);
    if (page != "close")
        localStorage.setItem(settingName, page); //save current page hash

  });
  let page = localStorage.getItem(settingName);
  if (page)
    location.hash = "#" + page;
  else
    window.location.href = "#openModal1"; //default page

}

function btn_reset()
{
    localStorage.removeItem(settingName);
}
.modalDialog {
position: fixed;
font-family: 'Poppins', sans-serif;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99999;
opacity: 0;
-webkit-transition: opacity 400ms ease-in;
-moz-transition: opacity 400ms ease-in;
transition: opacity 400ms ease-in;
pointer-events: none;
}
.modalDialog:target {
opacity: 1;
pointer-events: auto;
}
.modalDialog>div {
width: 500px;
position: relative;
margin: 10% auto;
padding: 26px;
border-radius: 2em;
background: #fff;
}
<div id="openModal1" class="modalDialog" data-modalorder="1">
<div>
<a href="#close" title="Close">X</a>
<h1>Content modal 1</h1>
<input type="button" onclick="start()" value="Start">
</div>
</div>
<div id="openModal2" class="modalDialog" data-modalorder="2">
<div>
<a href="#close" title="Close">X</a>
<h1>Content modal 2</h1>
<input type="button" onclick="btn_next()" value="Next">
</div>
</div>
<div id="openModal3" class="modalDialog" data-modalorder="3">
<div>
<a href="#close" title="Close">X</a>
<h1>Content modal 3</h1>
<input type="button" onclick="" value="Next">
</div>
</div>

<input type="button" onclick="btn_reset()" value="Reset">
vanowm
  • 9,466
  • 2
  • 21
  • 37
  • thank you! It works fine, but how could I make the modal where I left it for the last time to open automatically in 1 minute? Just to try. I know that opening the modal all the time is annoying but in the future I want to automatically open the modal every 12 or 24 hours. – Coc L May 05 '23 at 02:42
0

I would advise against inline event handlers (onclick=...). It is generally not a good idea.

You need something to save the state of your modal windows, and when you want to display the saved state after a certain time also the last time a modal was closed. I think localStorage will be suitable for that.

The snippet demonstrates how you can use event delegation to handle the clicks. It uses data-attributes to identify what the handler should execute.

In stackblitz snippets localStorage is not supported. So I created a small Stackblitz project to demonstrate the use of localStorage. In that project a closed modal re-opens after 15 seconds.

document.addEventListener(`click`, handle);
window.addEventListener(`load`, loadLast);

function loadLast() {
  // this would come from localStorage, but that's 
  // not supported in the Stackoverflow sandbox
  const lastOpen = {id: 1, lastTime: +new Date()};
  location.href = `#openModal${lastOpen.id}`;
}

function handle(evt) {
  if (evt.target.id === `close`) {
    document.body.classList.add(`noModal`);
    return;
  }

  if (evt.target.dataset?.modalid) {
    if (evt.target.value === `Reset`) {
      return location.reload();
    }

    const modal2Open = +evt.target.dataset?.modalid + 1;
    const nextExists = document.querySelector(`#openModal${modal2Open}`);
    if (nextExists) {
      return location.href = `#openModal${modal2Open}`;
    }
    return evt.target.closest(`.modalDialog`).querySelector(`[href='#close']`).click();
  }

  if (evt.target.id === `reload`) {
    location.href === ``;
    return location.reload();
  }
}
body {
  font-family: system-ui, sans-serif;
  color: black;
  background-color: white;
  margin: 1rem;
}

body.noModal .modalDialog{
  top: -10000px;
  height: 0;
}

#close {
  cursor: pointer;
  font-weight: bold;
  color: green;
  border: 1px solid #999;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  line-height: 1.2rem;
  text-align: center;
}

.modalDialog {
  position: fixed;
  font-family: 'Poppins', sans-serif;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.8);
  z-index: 99999;
  opacity: 0;
  -webkit-transition: opacity 400ms ease-in;
  -moz-transition: opacity 400ms ease-in;
  transition: opacity 400ms ease-in;
  pointer-events: none;
}

.modalDialog:target {
  opacity: 1;
  pointer-events: auto;
}

/* 
  Note: changed dimensions for use in the 
  stackoverflow snippet runner
*/
.modalDialog>div {
  width: 500px;
  height: 120px;
  position: relative;
  margin: 3% auto;
  padding: 26px;
  border-radius: 2em;
  background: #fff;
}
<h3>Hello world</h3>
<button id="reload">Reload page</button>
<div id="openModal1" class="modalDialog" data-modalorder="1">
  <div>
    <div id="close" title="Close">X</div>
    <h1>Content modal 1</h1>
    <input type="button" data-modalid="1" value="Start" />
  </div>
</div>
<div id="openModal2" class="modalDialog" data-modalorder="2">
  <div>
    <div id="close" title="Close">X</div>
    <h1>Content modal 2</h1>
    <input type="button" data-modalid="2" value="Next" />
  </div>
</div>
<div id="openModal3" class="modalDialog" data-modalorder="3">
  <div>
    <div id="close" title="Close">X</div>
    <h1>Content modal 3</h1>
    <input type="button" data-modalid="3" value="Reset" />
  </div>
</div>
KooiInc
  • 119,216
  • 31
  • 141
  • 177