Flyer53 / jsPanel4

A JavaScript library to create highly configurable floating panels, modals, tooltips, hints/notifiers/alerts or contextmenus for use in backend solutions and other web applications.
https://jspanel.de/
Other
313 stars 57 forks source link

Detect when panel is closed through residual panel reference (question) #161

Closed syonfox closed 3 years ago

syonfox commented 3 years ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

so I create the panel and save a reference to it then say the user close the panel. but there is the hanging reference to the panel. so in my show panel function i want to detect if my panel reference is closed or just minimised. so that i know weather to reinitialise the panel or just normalize it.

Describe the solution you'd like A clear and concise description of what you want to happen.

there should be a way to go panel.isClosed() or something. if you know what i can check to see if the panel is closed without side effects please let me know alternatively a panel.getState() that returns closed, normalised minimised etc could also work.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

I can probably do this through an event listener on close and delete my panel reference or something but having a quick way to ask a panel if its closed would be nice.
also my current work around is to just call close first and if the panel is already closed this will throw an error so I can catch that but then its in a known state. I don't want to be recreating the panel if I don't have to though.

Additional context Add any other context or screenshots about the feature request here.

syonfox commented 3 years ago

this seems to do the trick a getState might still be useful what do you think? let isclosed = jsPanel.getPanels().find(p=>p.id == panelref.id) != undefined

Flyer53 commented 3 years ago

Hi there,

If I understand you correctly there are two things that might help you:

  1. Each panel has a status property - https://jspanel.de/#properties/status
  2. How about using the onclosed callback to remove the reference when a panel is closed? Example:
    var mypanel = jsPanel.create({
    onclosed: function() {
        mypanel = null;
    }
    });

    Or if you want to keep the reference in memory:

    var mypanel = jsPanel.create({
    onclosed: function() {
        mypanel.closed = true;
    }
    });
Flyer53 commented 3 years ago

Another option - and maybe the easiest - is to use a custom ID for the panel and just query the ID:

jsPanel.create({
  id: 'panel8'
});

var panel = document.querySelector('#panel8');
var status = panel ? panel.status : false;

Note: I'll think about adding a status 'closed' to the panel property status. But it would be available only for panels with a saved reference.

syonfox commented 3 years ago

haha I ended up having an

closed: () => {
    this.panel = undefined;
}

instead of a

onclosed: () => {
      this.panel = undefined;
}

in my jspanel options

You're right i can just query the whole document for it my premature optimization hates that though haha. That's why i searched withing jspanel. if you know the approx cost lmk but its probably doesn't matter and that is cleaner

thanks for telling me about the status property a quick look and adding this

   self.statusBefore = self.status;
   self.status = 'closed';
   document.dispatchEvent(jspanelstatuschange);

to the end of this

https://github.com/Flyer53/jsPanel4/blob/0ea53cc22910341bc4302da200ba8104a4366ccf/es6module/jspanel.js#L2627

self.close = (cb, closedByUser) => {
            if (self.closetimer) {
                window.clearInterval(self.closetimer);
            }
            document.dispatchEvent(jspanelbeforeclose);
            if (
                self.options.onbeforeclose &&
                self.options.onbeforeclose.length > 0 &&
                !jsPanel.processCallbacks(self, self.options.onbeforeclose, 'some', self.status, closedByUser)
            ) {
                return self;
            }
            if (self.options.animateOut) {
                if (self.options.animateIn) {
                    jsPanel.remClass(self, self.options.animateIn);
                }
                jsPanel.setClass(self, self.options.animateOut);
                self.addEventListener('animationend', (e) => {
                    e.stopPropagation();
                    self.remove(self.id, closedByUser, cb);
                });
            } else {
                self.remove(self.id, closedByUser, cb);
            }
        };

should work but properly cleaning up my reference also worked :)

ps. thanks for the library its an improvement over jquerys dialog by a long shot I almost have module which combine's jspanel and https://github.com/6pac/SlickGrid with any postgress table.

Flyer53 commented 3 years ago

Hi again, I'll take a look at that as soon as I can ... Regards, Stefan

Flyer53 commented 3 years ago

Ok, you can download an updated v4.12.0 which includes a 'closed' string value for the panel property status. I didn't test it very much but there shouldn't be any problems I think.

Please give it a try and let me know how it works out....

Flyer53 commented 3 years ago

Implemented with v4.12.0 release