0
votes

On an xpage I calculate the message for an xp:confirm control:

var arr = viewScope.get("attachmentsAll");
if(arr.length>0){
    return "";
}else{
    return arr.length + " Are you sure want to upload the file?";
}

the viewScope is being updated after the event has been executed. I check this via a xp:text and I notice that this assumption is true.

<xp:text escape="true" id="computedField1"><xp:this.value><![CDATA[#{javascript:var arr = viewScope.get("attachmentsAll")

return arr.length + " number?"}]]></xp:this.value></xp:text>

The xp:confirm and xp:text reside in the same panel that is being partially updated after the event.

Can anyone explain me why the value for the viewScope variable is updated in the xp:text control and not in the xp:confirm control?

1
I'm not certain, but my gut feeling is order of events and place of action. xp:confirm isn't a server-side event, because you can't prompt for user response server-side. It's a server-side computation that then writes a response to the browser, to run next time the button triggers a partial refresh. Hopefully that will help you trace through what's set when. I thought I'd written a blog post about CSJS and server-side computations, but Google's not my friend on this search!Paul Stephen Withers

1 Answers

1
votes

The main idea of my answer to your previous question was to put hidden input with computed value. What if you try to use <xp:this.script> instead of xp:confirm, and get the confirmation message from that hidden input the same way?

Update

The reason and the alternative solution that does not require to make any changes to existing xpage

It came out that the back-end instance of xp:confirm evaluates the new message correctly. The new value is even being sent to the browser with the response to ajax request. But one of the functions of XSP client module is built so that it won't update the querySubmit listener function if there already exists one with the same name. So, we are stuck with the old confirmation function that contains the old message. There is a way to override this behavior without breaking any other features. I have tried this and it works for me.

Create a new JavaScript library (client-side). Add the code:

if (!XSP._pushListenerTuned) {
    XSP.__pushListener = XSP._pushListener;
    XSP._pushListener = function x__pl(listeners, formId, clientId, scriptId, listener) {
        if (scriptId && scriptId.endsWith("_confirm")) {
            for (var i = 0; i < listeners.length; i++) {
                if (scriptId == listeners[i].scriptId) {
                    listeners.splice(i, 1);
                }
            }
            listeners.push(new this._SubmitListener(formId, listener, clientId, scriptId));
        } else {
            XSP.__pushListener(listeners, formId, clientId, scriptId, listener);
        }
    }
    XSP._pushListenerTuned = true;
}

Attach your new library as resource globally via theme or as page resource on required page. I guess placing the above code as scriptBlock on a required page should also work. Now, any xp:confirm component on any page (if you used theme resource), or on particular page and everywhere after visiting this page (if you used page resource or scriptBlock), will work as naturally expected.