1

We have a page with some Accordions. Some accordions start as empty, and they get filled when the user clicks the Accordion bar through a partial update. At the start, this works fine, but if the user opens the accordions in a later stage it doesn't work.

It happens when the user leaves the accordions closed, switches to different page in the same nsf, does a lot of things there, and then comes back to the first page. Somehow, the code related to the partial refresh isn't executed.

Here's some code:

<xe:djAccordionPane id="djAccordionPane3">
    <xp:div id="outerPanelModels">
        <xc:ccModelView>
            <xc:this.rendered><![CDATA[#{javascript:UserData.getVar("ShowModels")}]]></xc:this.rendered>
        </xc:ccModelView>
    </xp:div>
    <xe:this.dojoAttributes>
        <xp:dojoAttribute name="Title" value="#{javascript:constants.Models}"></xp:dojoAttribute>
    </xe:this.dojoAttributes>
    <xp:eventHandler event="onShow" submit="true" refreshMode="partial"
        refreshId="outerPanelModels">
        <xp:this.onComplete><![CDATA[hideAjaxLoader();]]></xp:this.onComplete>
        <xe:this.script><![CDATA[if(document.getElementById("#{id:outerPanelModels}").childElementCount==0) {
    showAjaxLoader();
    return true
}
return false;]]></xe:this.script>
        <xe:this.action><![CDATA[#{javascript:UserData.putVar("ShowModels", true)}]]></xe:this.action>
    </xp:eventHandler>
</xe:djAccordionPane>

UserData is a sessionScope bean. putVar and getVar used to be in a viewScope bean, I suspected the bean to be destroyed somehow (it actually is) so I moved the code over to sessionScope.

Why isn't the code line at the bottom executed, i.e. the line with UserData.putVar("ShowModels", true)?? Any clues? A solution maybe??

Thanks!

Update The application is set to keep all pages in memory.

xsp.properties:

xsp.error.page=xError.xsp
xsp.library.depends=com.ibm.xsp.extlib.library
xsp.min.version=8.5.3
xsp.persistence.mode=basic
xsp.resources.aggregate=false
xsp.theme.web=extendOneUI.theme

xsp.openlog.expireDate=15

xsp.error.page=Error.xsp
xsp.persistence.viewstate=fullstate
# org.openntf.domino.xsp=godmode,marcel,bubbleExceptions
xsp.application.forcefullrefresh=true
xsp.error.page.default=true
xsp.session.timeout=180
xsp.application.timeout=180
D.Bugger
  • 2,300
  • 15
  • 19
  • Are you sure the line isn't executing? Did you add a print statement to the method and then also check the console to verify? – David Leedy Sep 17 '15 at 11:24
  • The first thing putVar does is add a line to the (internal) log. That log can be inspected on a separate screen. Nothing there. The partial refresh does happen, actually, it's just that the code isn't executed. If you'd like me to add a System.out.print, I will do that, just to make sure. – D.Bugger Sep 17 '15 at 11:35
  • The server side code in this.action only runs if the client side code in this.script returns true. Do you expect it to run everytime? – Per Henrik Lausten Sep 17 '15 at 11:45
  • Well, the partial refresh executes every time, so I'd expect the code to run also. The if-condition _document.getElementById("#{id:outerPanelModels}").childElementCount==0_ is true, there are no children in the element. Also tested using the debugger (Firefox). – D.Bugger Sep 17 '15 at 11:50
  • Is the code getting past `showAjaxLoader()`? Perhaps an error there is preventing `return true`, thus the action isn't run. Add a print statement after showAjaxLoader to see I guess. – Brian Gleeson - IBM Sep 17 '15 at 13:48
  • Are there any rendered settings at a higher level than the Accordion? They may be relevant. – Paul Stephen Withers Sep 17 '15 at 14:45
  • Code is definitely getting past showAjaxLoader(), true is returned and I can see a partial refresh occurring. The result: _
    _, that's all. I therefore assume that higher level rendering settings aren't relevant. In any case, everything works at start of the page; only when returning to it after opening many other pages the code is no longer executed.
    – D.Bugger Sep 17 '15 at 16:07

1 Answers1

1

Review xsp.properties, specifically the Persistence Properties for the number of pages to keep in memory and keep on disk. There are also default settings.

Once a certain number of component trees is stored, if you try to store another, the earliest will be dumped. In the scenario you're describing, it sounds like it's dumping the component tree for the page with the accordion container, which will also dump UserData viewScoped variable.

There is no magic bullet answer, it will depend on your application and how users interact with it. It will also depend on whether you're keeping all pages in memory, all on disk or a mixture. Basically, if you allow users to open other tabs for the same NSF within the browser, unless you can keep that page's component tree available, there's the risk of the component tree being lost, because there's no way for the server-side to know it's still open in the browser.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • I updated the question text above: all pages are kept in memory. I know that old pages get dumped, but how much is getting dumped? Only memory? Or even functions that should be called? Why isn't the page correctly reloaded, why isn't the function called? It does execute some functions, we can see that in the log. What's also strange: the viewScoped bean is re-created every time the accordion is reopened (I log the creation of that bean). The application itself has some 5 frames and iframes, plus for each opened document a separate window. Many pages, I know... – D.Bugger Sep 17 '15 at 16:16
  • The whole component tree for the page will be dumped. That includes any event handlers on that page you're trying to call. (Any SSJS code in an event handler is not a function, it's a String stored in a property of the event handler, which is parsed during INVOKE APPLICATION phase, if that event handler is called for the particular event.) The first step for any partial refresh (POST, that is) is the RESTORE VIEW phase. If there's nothing to restore because it's been dumped, it can't get any further, so it won't get to INVOKE APPLICATION phase to run any SSJS. – Paul Stephen Withers Sep 17 '15 at 16:31
  • What can I do about it? How can I prevent that a specific page is destroyed? It's our main dashboard page, it's not supposed to die on the user. Or is it somehow possible to find out that the viewScope is lost at an appropriate moment so I can re-create the page, or reopen it? – D.Bugger Sep 17 '15 at 16:51