Is there a way to tell when a page has lost focus?

I want to periodically refresh the information on one of the tabs on the control panel for my plugin.
I’m using setInterval/clearInterval and it works great. Too great.

I need to find a way to tell when the user leaves the page so I can clear the Interval timer.

I can call the clear function in each of the other tabs but that, of course, is not good enough.

This code is in the J_WiFiUDP1.js file that is loaded by the D_WiFiUDP1.json. Surely there is a way to tell the user has left the control panel.

Can someone point me to a page that might help? The Vera stuff I’ve found has not been helpful.

TIA, Jim

You can register for a close event:

api.registerEventHandler('on_ui_cpanel_before_close', module/object, 'onBeforeCpanelCloseFunction')

Ref: http://wiki.micasaverde.com/index.php/JavaScript_API#registerEventHandler.28eventName.2C_object.2C_functionName.29

[quote=“rigpapa, post:2, topic:200381”]You can register for a close event:

api.registerEventHandler('on_ui_cpanel_before_close', module/object, 'onBeforeCpanelCloseFunction')

Ref: http://wiki.micasaverde.com/index.php/JavaScript_API#registerEventHandler.28eventName.2C_object.2C_functionName.29[/quote]

Thanks, rigpapa,
I saw this last night when I was looking for solutions but I couldn’t figure out how to use it until I looked at again today. I now see you have to migrate to the ‘new JavaScript API’. which I spent most of today doing. :frowning:

Unfortunately, the registerEventHandler isn’t working for me. I put an alert at the beginning of the onBeforeCpanelCloseFunction function but it never gets there. The only way to stop the interval is to reload the browser or call from another tab.

I’ve checked everything I could think of to make sure my migrated JavaScript file looked just like the J_HomeCare_UI7.js provided in the migration example but no joy. Everything else is working fine on all the tabs, I just can’t turn off the interval.

The call:
function init()
{
// register to events…
api.registerEventHandler(‘on_ui_cpanel_before_close’, myModule, ‘onBeforeCpanelClose’);
}
function onBeforeCpanelClose(args)
{
alert(“***** Entered onBeforeCpanelClose *****”);
}

I did see the line:
parameters: idForDeviceWhichOpenedTheCpanel
in the defination of on_ui_cpanel_before_close but have no clue what to do with it.

Any suggestions as to a direction to look or more documentation are much appreciated.
TIA, Jim

Go all the way to the Dashboard. Closing the control panel doesn’t mean closing the tab or moving to another tab. It works. I use this in almost every plugin of mine.

Thanks again,
That was my problem. I must have missed the memo… :wink:

Thanks again,
That was my problem. I must have missed the memo… ;)[/quote]

We all did/do. The learning curve is steep, the details many. This is the best place to commiserate with peers, learn the secret incantations, and occasionally, share tales of woe. :wink:

Well, I’m still left with the original problem. I don’t want the content being refreshed every 5 seconds if the user has gone back to the ‘configure’ tab or even switched to another device.

I saw the api.getCpanelContent() and thought I might use this to inspect the currently displayed control panel to see if it was me but I haven’t been to get it to return anything.

Guess I don’t really HAVE to have the feature but it would just be so cool.
Still looking…

Jim, each tab, when clicked, will have the function called that is named in static JSON (the D_xxx.json file). You could keep a flag that is set true when the tab with refresh/status is displayed, and set to false by your other tabs’ functions. The interval callback can then check this flag, and if its false, clear the interval and exit without doing anything else. I do similar in my plugins (although I try not to use setinterval/settimeout and instead use the on_ui_deviceStatusChanged event to know when something has changed and I need to update the display).

Edit(s): need wayyyyy more coffee at this hour.

Actually…
If I’m understanding the documentation correctly, this only happens when the TabType is javascript. My Options tab TabType is flash. Unless there is a way to have a tab both javascript and flash? I’d love to know how to know how to do that.

But I have discovered my REAL problem. I’ve been doing my testing on ALTUI and that interface doesn’t appear to ever fire on_ui_cpanel_before_close, thus my earlier statement that the only way I could turn off the interval is to reload the window.
Is there something special I need to do to make AltUI fire on_ui_cpanel_before_close?

And, even if I used on_ui_deviceStatusChanged as you suggested, wouldn’t I still have the same problem of being unable to turn it off on AltUI without on_ui_cpanel_before_close?

Sorry to be such a noob but after 41 years of writing in C, C++, C# and various assemblys this documentation from Mios drives me nuts. They seem to have completely mastered Microsoft’s trick of writing help that is both 100% accurate and 100% unhelpful.

And, thanks for both the help and the encouragement.

[quote=“Jim McGhee, post:9, topic:200381”]Actually…
If I’m understanding the documentation correctly, this only happens when the TabType is javascript. My Options tab TabType is flash. Unless there is a way to have a tab both javascript and flash? I’d love to know how to know how to do that.

But I have discovered my REAL problem. I’ve been doing my testing on ALTUI and that interface doesn’t appear to ever fire on_ui_cpanel_before_close, thus my earlier statement that the only way I could turn off the interval is to reload the window.
Is there something special I need to do to make AltUI fire on_ui_cpanel_before_close?

And, even if I used on_ui_deviceStatusChanged as you suggested, wouldn’t I still have the same problem of being unable to turn it off on AltUI without on_ui_cpanel_before_close?

Sorry to be such a noob but after 41 years of writing in C, C++, C# and various assemblys this documentation from Mios drives me nuts. They seem to have completely mastered Microsoft’s trick of writing help that is both 100% accurate and 100% unhelpful.

And, thanks for both the help and the encouragement.[/quote]

Ah, yes. The only “flash” tab I ever use is for the first one, the “Control” tab as it is typically called, with the Vera static-data-driven interface (which is usually substandard and therefore reserved just for the most basic functions, and why I then go on to build more extensive interfaces on the JavaScript tabs).

To work around that ALTUI difference, I have my timeout callback make sure my container element is on the page, using a very specific jQuery selector to match both an ID and class I want (that is unlikely to be used elsewhere), something like this: [tt]if ( jQuery( ‘div#conditions.reactortab’ ).length == 0 ) return; // I’m no longer displayed, stop working.[/tt]

[quote=“rigpapa, post:10, topic:200381”]Ah, yes. The only “flash” tab I ever use is for the first one, the “Control” tab as it is typically called, with the Vera static-data-driven interface (which is usually substandard and therefore reserved just for the most basic functions, and why I then go on to build more extensive interfaces on the JavaScript tabs).

To work around that ALTUI difference, I have my timeout callback make sure my container element is on the page, using a very specific jQuery selector to match both an ID and class I want (that is unlikely to be used elsewhere), something like this: [tt]if ( jQuery( ‘div#conditions.reactortab’ ).length == 0 ) return; // I’m no longer displayed, stop working.[/tt][/quote]

Since I have no idea what I’m doing, I’m back.
It’s better.
I added
Html += ‘

’;
to the beginning of my html and added
if (jQuery(‘#WiFiUDP_StausList’).length == 0 )
{
Utils.logError(“***** length == 0 *****”);
onBeforeCpanelClose(); // stop the interval for StatusList
return; // I’m no longer displayed, stop working.
}
to the beginning of DisplayStatusList and now if I click the back arrow or devices or scenes, everything works great!!
Unfortunately, if I Actions/Used In/Notifications in the lower menu or the Options tab (which is flash) it still keeps seeing the length as non-zero.
I assume this is because I completely misunderstood your suggestion.
Remember, you’re talking to a real noob here when it comes to html. :slight_smile:

[quote=“Jim McGhee, post:11, topic:200381”][quote=“rigpapa, post:10, topic:200381”]Ah, yes. The only “flash” tab I ever use is for the first one, the “Control” tab as it is typically called, with the Vera static-data-driven interface (which is usually substandard and therefore reserved just for the most basic functions, and why I then go on to build more extensive interfaces on the JavaScript tabs).

To work around that ALTUI difference, I have my timeout callback make sure my container element is on the page, using a very specific jQuery selector to match both an ID and class I want (that is unlikely to be used elsewhere), something like this: [tt]if ( jQuery( ‘div#conditions.reactortab’ ).length == 0 ) return; // I’m no longer displayed, stop working.[/tt][/quote]

Since I have no idea what I’m doing, I’m back.
It’s better.
I added
Html += ‘

’;
to the beginning of my html and added
if (jQuery(‘#WiFiUDP_StausList’).length == 0 )
{
Utils.logError(“***** length == 0 *****”);
onBeforeCpanelClose(); // stop the interval for StatusList
return; // I’m no longer displayed, stop working.
}
to the beginning of DisplayStatusList and now if I click the back arrow or devices or scenes, everything works great!!
Unfortunately, if I Actions/Used In/Notifications in the lower menu or the Options tab (which is flash) it still keeps seeing the length as non-zero.
I assume this is because I completely misunderstood your suggestion.
Remember, you’re talking to a real noob here when it comes to html. :)[/quote]

It’s usually benign to update in hidden content. Not perfectly efficient, admittedly, but it can have the advantage that when the user returns to the tab, it’s already displaying valid data.

If you really need to take it further and shut down that interval firing when your tab is not displayed (even if another tab for the same device is), you’re going to need to figure out how the UI’s container is handling tabs. The implementation of tabs in pretty much every system I’ve worked with involves the hiding of the container for the content of the tab. When you switch between tabs, the content doesn’t go away, the container is simply hidden and the container of the tab just clicked is made visible. If you browse the DOM, you find the entire content of every tab is there (in some cases, it may only be every tab that has been displayed so far, and in some cases, it’s all of them). In this case, you’re going to need to dig for the tab implementation’s container element (I don’t know off-hand what it is by id and/or class, I’ve never needed to go that far) and look at its visibility in your test. But it will be different in UI7 vs ALTUI, so that complicates matters. And I’m sure the upcoming UI8 will be different as well. You may be better off just letting it update in the background silently. Eventually, the cpanel close event or the length test will catch up with it.

[quote=“rigpapa, post:12, topic:200381”]It’s usually benign to update in hidden content. Not perfectly efficient, admittedly, but it can have the advantage that when the user returns to the tab, it’s already displaying valid data.

If you really need to take it further and shut down that interval firing when your tab is not displayed (even if another tab for the same device is), you’re going to need to figure out how the UI’s container is handling tabs. The implementation of tabs in pretty much every system I’ve worked with involves the hiding of the container for the content of the tab. When you switch between tabs, the content doesn’t go away, the container is simply hidden and the container of the tab just clicked is made visible. If you browse the DOM, you find the entire content of every tab is there (in some cases, it may only be every tab that has been displayed so far, and in some cases, it’s all of them). In this case, you’re going to need to dig for the tab implementation’s container element (I don’t know off-hand what it is by id and/or class, I’ve never needed to go that far) and look at its visibility in your test. But it will be different in UI7 vs ALTUI, so that complicates matters. And I’m sure the upcoming UI8 will be different as well. You may be better off just letting it update in the background silently. Eventually, the cpanel close event or the length test will catch up with it.[/quote]

Thanks for the info. That explains a lot of what I was seeing. It now works fine on the Vera Desktop and the jQuery makes it work OK on AltUI.

Now it’s time for me to go back to fixing REAL bugs and getting this thing set up on GitHub so I can release it for testing. :slight_smile:

Thanks again for all the help.

Ahhhh! @rigpapa Thx! I did not know JS finally is available for Vera, that would make my life much easier

1 Like