Often, we want to confirm with the user that they actually want to save or submit a document in XPages. I thought it would be very simple to customize the server-side simple action ‘confirm’ to include client-side data that the user had just entered, but that was not yet saved to disk.
So, I had what I thought was some simple and straight-forward SSJS:
<xp:confirm> <xp:this.message><![CDATA[#{javascript:var baseText = "Are you sure that you want to set the exchange rate for "; var effectiveDate = getComponent("effectiveDate").getValue().toString(); var localCurrency = getComponent("localCurrency").getValue(); var exchangeRate = getComponent("exchangeRate").getValue(); return baseText + localCurrency + " to " + exchangeRate + " as of " + effectiveDate + "?"; }]]> </xp:this.message> </xp:confirm>
I posted my question on StackOverflow and Paul Withers pointed out that I wasn’t going to get what I was looking for….
You’re computing SSJS to pass to a CSJS confirm() message. I would expect it to display values at the last refresh, not values just entered by the user. If you want the latest values, I think you’ll need to access them via CSJS.
So, I made the classic mistake of failing to know whether I and my data were client-side or server-side. Thus, my getComponent commands were getting a handle to the last version of the server-side component, not what the user just entered on the client-side. So, I needed to move back to the client-side to display client-side values. Fortunately, I remembered that if your client-side javascript evaluates to false, the server-side script never executes.
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="false" save="true" id="eventHandler3"> <xp:this.script><![CDATA[var baseText = "Are you sure that you want to set the exchange rate for "; var effectiveDate = document.getElementById("#{id:effectiveDate}").value; var localCurrency = document.getElementById("#{id:localCurrency}").value; var exchangeRate = document.getElementById("#{id:exchangeRate}").value; return window.confirm (baseText + localCurrency + " to " + exchangeRate + " as of " + effectiveDate + "?");]]> </xp:this.script> <xp:this.action><![CDATA[#{javascript:exchangeRateDoc.save(); context.redirectToPage("/pro_exchangeRate_view.xsp")}]]> </xp:this.action> </xp:eventHandler>
The key to the client-side javascript is to make sure you return the value of that window.confirm at the end. In my initial attempt, I didn’t return the value and my testers pointed out to me that my ‘Are you sure?’ was just taunting my users. It would ask the question, but it ignored the response. Clicking OK would save it, as intended, but clicking Cancel would ALSO save it! Talk about ignoring user input!
Hopefully, my mistake will prove instructive in your attempts to find your way in XPages…..
I typically use SSJS for this. It’s more work but seems doable. I’ll have a button and that button doesn’t do anything other then ask the question. Either via a panel where I turn rendering on or in a dialog box. Then a second button in that dialog box/panel then “Yes – I’m sure” actually does the work. This also gives me the ability to get a little more information… like “How Many?” and then pass that into the function that needs it.
just a thought.
Interesting. So many ways to slice it. One of the good things about moving to more modern technologies in Domino is that it opens up more possibilities.