SSJS Codes behind the button runs after page is refreshed - xpages

I have SSJS code behind a button. When i click the button that code creates a document in another database.
When i click the button It Works fine but I look at the Domino Admin COnsole I realize that The code behind to button Works twice.. I think When the page is refreshed It Works again? How can i prevent it?
What is it thet I miss?
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print("Before createNewDoc()");
createNewDoc();
print("After createNewDoc()");
}]]></xp:this.action>
</xp:eventHandler></xp:button>

Add print statements to the beforePageLoad, afterPageLoad etc events to confirm where it is running. Also, it's worth using XPages OpenLog Logger or some other logging framework that can output a full stack trace. That might identify whether the code is running twice in the refresh, and where from.
There is no reason the code should be running twice from the button. I'm assuming this is an SSJS function in a Script Library, maybe something else is triggering that.

Related

Xpages typeahead in dialog does not work unless onChange triggered first

UPDATED at bottom...
I have a custom control that contains an input field with typeAhead enabled:
<xp:inputText id="UTAN1" value="#{document1.UTAN}"
maxlength="5" styleClass="dbListFieldData" style="width:60px;font-size:13px;">
<xp:typeAhead mode="full" minChars="2">
<xp:this.valueList><![CDATA[#{javascript:var key = getComponent("UTAN1").getValue();
var path = new Array("","utans.nsf")
#Unique(#DbLookup(path,"(UTAN Lookup)",key,1,"[PARTIALMATCH]"));}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="utanPanel1">
<xp:this.action>
<!-- DO SOME STUFF -->
</xp:this.action>
</xp:eventHandler>
</xp:inputText>
If I use the control inline on an xpage, typeAhead works fine.
However, if I insert the control in a dialog and call it to open:
<xp:link escape="true" id="link3" styleClass="dbListFieldData" >
<xp:eventHandler event="onclick" submit="false" id="eventHandler3">
<xp:this.script><![CDATA[XSP.openDialog('#{id:miniDialogUTAN1}');]]></xp:this.script>
</xp:eventHandler>
<xp:image id="image2" url="/edit2.png" style="height:16px;width:16px;" alt="Edit UTAN"></xp:image>
</xp:link>
The typeAhead seems to be partly crippled.
If the field is already empty, suggestions comes up fine.
If the field has an existing value, backspacing only shows the existing value as a suggestion.
Overwriting the value entirely gives no suggestions at all.
The only thing that will get the typeAhead working is to change the value and hit Enter. Basically, trigger an onChange. After that, ALL the typeAhead fields start working.
Any ideas on how to correct this behavior? FYI, I'm an xpages noob, so please go easy on me.
UPDATE 6/29/2021:
I'm still desperately in need of help with this. I've been playing around with Firebug and found something interesting.
In type-aheads on a normal Xpage form (where type-ahead works), entering each character calls a POST every time. However, when the type-ahead is in a dialog, typing in characters calls GETs. If I hit Enter or tab out of the field (triggering onChange), I get a single POST, and then clicking back into the field and typing, it starts using GETs again and it pulls valid suggestions as long as I don't backspace and type something different. Then the suggestions go away. This would be expected since GETs are cached and POSTs are not.
So what's going on with type-aheads in dialogs that makes them use GET, and how to I force it to use POST on every key press?
To people of the future...
After weeks of fretting over this and finally giving up I stumbled upon the solution by accident.
My dialog opens in read mode. I have both an Edit button and a Cancel button at top and bottom that were originally hard coded in both spots of the dialog custom control. Later I went to clean some stuff up and decided to create a single custom control for both sets of buttons. Once I did that, suddenly the type-aheads worked!
It turns out that when I copied and pasted the XML from the (supposedly) duplicate button panels to the new custom control, I had copied from the bottom button panel (which I rarely used while testing).
When I compared the XML for the top and bottom Edit Buttons, I found that the top one had the following attributes in the onClick:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
while the bottom one had:
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="dialogOuterPanel1">
So, the full refresh broke my type-aheads and a partial refresh fixed them.

Not executing SSJS code in eventHandler with complete refreshMode in XPages

It's been 3 weeks since I've been struggling with this problem
onClick eventHandler rejects to show any signs of being working properly when it goes hand in hand with refreshMode="complete"
The code is below:
<xp:button id="begginYOU"
style="float: right; margin-right:20px;"
value="Send">
<xp:eventHandler event="onclick" refreshMode="complete"
submit="true">
<xp:this.action><![CDATA[#{javascript:
print("I will never get this message printed with complete refreshMode");
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
I've tried everything - setting properties of id (on eventHandler itself), adding CSJS code which returns true (the message which I've added to console.log was always printed btw), setting disableValidators to true
I've even tried to remove all the inputs and just leave this one button on the entire page - nothing helped
Whenever I click the button - all I get is just a loading next to the tab's icon in the browser for just half a second and nothing, literally NOTHING happens
It ONLY works with refreshMode and execMode set to partial (provided that I provide ids respectively) but I have no idea why
It really drives me around the bend
But anyway I hope to receive experts' opinion on that problem, because I've run out of ideas
Many thanks in advance

Working dialog code from one application does not work in another application

I've working code to open dialog box using SSJS code to show error or warning to user when user click submit button. This button appears at the top of the xpage.
Applied the modified version of the above code in another application but instead of top of xpage, put button in section. If comboBox1 has initial value it is suppose to popup the dialog box. But it is not working. The client side validation is off in working as well as non working application. Why this code is not working? Where to check?
Here is code for a section button:
<xp:button value="Must click to Assign Quote Number" id="button6" style="width:207.0px">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="false" save="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var comboBox1:com.ibm.xsp.component.xp.XspSelectOneMenu = getComponent("comboBox1");
var a=comboBox1.getValue();
if ( a=="Assign the PE Staff"){
var d=getComponent('dialog2');
d.show();
}
}]]></xp:this.script>
</xp:executeScript>
</xp:this.action></xp:eventHandler>
</xp:button>
Things to check off the top of my head:
Check that Ext Lib is loaded properly in new app (check application properties)
Check that namespace for ExtLib is on the new page (drag any Ext Lib control on the page, and this will be added for you)
Check that resources from the first page are on the new one (script libraries, etc)
Try print("var a=" + a) to see if comboBox1 is giving you a value (check your server log.nsf)
If you give more info on what is happening when it doesn't work then we might be able to suggest more things to check.

XPages SSJS is not started throw Reverse-Proxy

may be someone helps :)
I don't know much about Apache-Reverse-Server
I have a simple X-Page, see the code bellow.
If I open the xpage via
http: //domain1.de/e.nsf/test.xsp
and press the button, in log.nsf i see my print-out "Button is clicked"
If I open the xpage via
https: //example1.someproxy/rp/sproxy/http$domain1.de$80$/e.nsf/test.xsp
and press the button, in log.nsf i DON'T see my print-out "Button is clicked"
The Proxy-Server is installed and configured not by me.
<?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:link escape="true" id="link1" disableTheme="true">
<xp:image id="image1" url="/btn.jpg"></xp:image>
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" >
<xp:this.action><![CDATA[#{javascript:print("Button is clicked");}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
What could be the problem, that the SSJS-code is not started via Reverse-Proxy at all?
Is reverse proxy the problem? Or is the problem that your code is not triggering?
I can't tell from your user id how experienced with XPages you are, but bear in mind a number of steps are performed on the server before it gets to your print statement. One of the key ones is conversion and validation. So if anything on your XPage throws a validation error, it won't run SSJS code.
Do you have a Display Errors control on the XPage and, more importantly, inside the refresh area? If not, add one. We've all spent hours in our early XPages life because validation or data conversion has failed and we didn't add anything to let us know. Once you get more confident, a PhaseListener is another useful tool for checking any or all lifecycle phases are running.

How to open a classical Notes document in a new client tab, triggered by a XPage

I have to implement the following request, but all my tries failed:
If you click on a button/link in a XPage (XPiNC), a classic Notes-Document shall be created in another Notes Database. This new Notes document has to be open in a new client tab beside the tab with the XPage.
I’ve tried several ways with
FacesContext.getCurrentInstance().getExternalContext().redirect("notes://server/anotherdb/newdocumentunid?openDocument")
but none of them led to the desired result (There were 3 tabs opened or the XPage tab is empty).
Have you tried using window.open in client side javascript.
Add the code window.open("Notes://database/view/document?EditDocument")
that should work.
EDIT:
It is possible to execute CSJS from SSJS with view.postScript().
<xp:button value="client" id="button3">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" disableValidators="true">
<xp:this.action><![CDATA[#{javascript:var url = myJavaClass.createNewDocumentAndReturnNotesUrl(); view.postScript("window.open('" + url + "')");}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
CSJS function window.open(url) is executed from SSJS after creating document in other database and getting back the URL for the new document. This way, the code is only executed when button is clicked and new document opens in a new window.
Actually, to create a document in the other database, you don't need to worry about what the document's UNID is. Just use this javascript:
window.open("Notes://database/form?CreateDocument")

Resources