Skip to content

multiple popups at once mod #3

@knutesears

Description

@knutesears

I have code using this library which sometimes wants to make a new popup before the user has dealt with an existing one. As it exists currently, this is not possible without the library destroying the first popup in the process. What I wanted was to put the subsequent popups behind the earlier ones, using z-index, and I also decided to shift them slightly up and to the left. Here are the mods I made, in case they help anyone else out, or the maintainer wants to incorporate them.

First, at the end of the IIFE, I passed the Popup function itself to the window, since we're gonna want a 'new' one each time:

    // REMOVE: window.PurePopup = new Popup();
   window.Popup = Popup;

Then I made an object in my main code to hold a couple vars to keep track of the multiple popups (these could just as easily be standalone vars not in a object):

let State = { popup_num: 0, popups_open: 0 };

Then, in the creator Popup function, make this change:

    // REMOVE: this.wrap.id = 'purePopupWrap';

    State.popup_num++;
    this.wrap.id = `purePopupWrap_${State.popup_num}`; // e.g. purePopupWrap_23

    // each new popup will have lower z-index value so that is underneath the previous ones
    this.wrap.style.zIndex = 999999 - State.popup_num;

Then I added this to the .show function:

    // inner div was positioned with CSS; let's overwrite it so that we can offset the position
    // of subsequent popups if they come while the first one is still open
    State.popups_open++;

    const margin_shift_vmin = (State.popups_open - 1) * 1.5; // use whatever spacing units and multiplier you want
    const margin_left_vmin = (10 - margin_shift_vmin); // starts at 10vmin
    const margin_top_vmin = (25 - margin_shift_vmin);  // starts at 25vmin

    const inner_div_el = this.wrap.firstChild; 
    inner_div_el.style.left = `${margin_left_vmin}vmin`;
    inner_div_el.style.top = `${margin_top_vmin}vmin`;

And add this in the .close function (at the end of the setTimeout function):

        // now that we can have multiple popups (instead of re-using one div), we should remove them...
        document.body.removeChild(this.wrap);
        // ...and keep track of how many are open so we can slightly offset them using a formula
        State.popups_open--;

Now, whenever we want a new popup, we need two lines instead of one, since we need to do the 'new' ourself:

        let PurePopup = new Popup();
        PurePopup.alert({   title: 'Alert 1'    });

And if you need to close it before the user does, do like so:

        PurePopup.close();

Oh, and I almost forgot, I had to change the CSS now that we have a unique id for each new popup. This could have been done differently by using more classes instead of CSS that relied on a single id, but I learned something new that will probably come in handy in the future, and it made for less work in making this mod. Just change all the id selectors:

        #purePopupWrap

...to attribute selectors (this was new to me):

        [id^="purePopupWrap"]

This selects elements where the id starts with (^=) the string "purePopupWrap". Now we'll hit all the sequentially numbered ids of our popups.

Hope this helps someone not spend most of the day on this issue like I did. Or maybe someone wants to incorporate this into the library?

Cheers,
-knute

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions