xpages - prevent SSJS on page load in CSJS - xpages

I have some SSJS within CSJS onclick event of a button. Is there any way to prevent this SSJS from executing during page load?
Thanks

This can be done by checking facesContext.getRenderResponse(). If it is true, the page is reloaded, otherwise it is false. The flag is not set correctly but gives you an easy way to check if the page is loaded or not.
Here is an example XPage:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:button value="Reload CSJS" id="buttonReloadCSJS">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.script>
<![CDATA[#{javascript:
facesContext.getRenderResponse()?"alert('NotOnLoad');":"alert('OnLoad')";
}]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
</xp:view>
If you open the XPage and click the button, the page will be reloaded and you will have another CSJS code.
EDIT:
Here is another way to calculate code only if the button was partial refreshed:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div id="refreshMe">
<xp:button value="Reload CSJS" id="buttonReloadCSJS">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="refreshMe">
<xp:this.script>
<![CDATA[#{javascript:
var ajax = new com.ibm.xsp.ajax.AjaxUtil();
if( ajax.isAjaxPartialRefresh(facesContext) == true){
return "alert('Refreshed')";
}
}]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
</xp:div>
</xp:view>

Related

Get unid of document before it is saved and have it not change when saved

I have an XPage that has a single data source document1. I would like to know the unid of the document before it has been saved.
It's seems this is possible because document1.getDocument().getUniversalID() returns a value before it is saved.
However, this value always changes once the document is saved then it remains constant. Is there a way to set the unid so it doesn't change when saved? I've tried if (document1.isNewNote()) document1.getDocument().setUniversalID(document1.getDocument().getUniversalID()) but it is still changing when saved.
Change document's id on dominoDocument's querySaveDocument event.
if (document1.isNewNote()) {
document1.getDocument().setUniversalID(yourID);
}
Here is a complete XPage example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoDocument
var="document1"
formName="Test">
<xp:this.querySaveDocument><![CDATA[#{javascript:
if (document1.isNewNote()) {
document1.getDocument().setUniversalID(document1.getItemValueString("id"));
}
}]]></xp:this.querySaveDocument>
</xp:dominoDocument>
</xp:this.data>
<xp:inputText
value="#{document1.id}"
defaultValue="#{javascript:document1.getDocument().getUniversalID()}">
</xp:inputText>
<xp:button
value="Label"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete"
immediate="false"
save="true">
</xp:eventHandler>
</xp:button>
</xp:view>

How to do a partial refresh of multiple items in Xpages correctly

I have read many of the blog posts on doing a partial refresh on more than one element, but I cannot seem to get it to work.
I made a "toy" example, an Xpage with two fields and one button. Both fields are bound to a sessionScope counter. The button increments the counter and does a partial refresh on the containing panel.
I want to do a partial refresh on the first field, which is not in the panel [in my real Xpage the two fields are very far apart on the form.
Tried many different things to get this to work, but none worked. Is it even possible to do this?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom"
style="background-position:center left"
xmlns:on="http://www.openntf.org/domino/xsp" viewState="nostate"
xmlns:debug="http://www.openntf.org/xsp/debugtoolbar">
First Var<br></br>
<xp:text escape="true" id="computedField1" value="#{sessionScope.number}">
</xp:text>
<br></br>
<xp:br></xp:br>
<br></br>
Second Var<xp:panel id="pnl1">
<xp:text escape="true" id="computedField2" value="#{sessionScope.number}">
</xp:text>
<br></br>
<br></br>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pnl1" execMode="partial"
execId="pnl1">
<xp:this.action><![CDATA[#{javascript:var t = sessionScope.number + 1;
sessionScope.number = t;}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
</xp:view>
Read Knut's link and got this to work. I made a change to the event handler of the button and it worked. Here is the code:
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="pnl1" execMode="partial"
execId="pnl1">
<xp:this.action><![CDATA[#{javascript:var t = sessionScope.number + 1;
sessionScope.number = t;}]]></xp:this.action>
<xp:this.onComplete><![CDATA[XSP.partialRefreshPost("#{id:computedField1}");]]></xp:this.onComplete>
</xp:eventHandler>
Use XSP.partialRefreshPost(): http://avatar.red-pill.mobi/tim/blog.nsf/d6plinks/TTRY-84B6VP

XPage fileDownload1 control becomes editable on page full refresh?

Why fileDownload1 control becomes editable (delete file attachment icon appears next to fileDownload control) when I just refresh the page. Here is my code where I use a button to refresh the page (just for the example)
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete"></xp:eventHandler>
</xp:button>
<xp:this.data>
<xp:dominoDocument var="document1" formName="myXpage"
databaseName="${javascript:sessionScope.SUPPORT_DB_FILE}"
action="openDocument">
</xp:dominoDocument>
</xp:this.data>
<xp:fileDownload
id="fileDownload1"
rows="30"
displayLastModified="false"
displayType="false"
displayCreated="false"
hideWhen="true"
allowDelete="true"
value="#{document1.MyBodyRTF}">
</xp:fileDownload>
I tried to replicate what you're describing, but am having trouble doing so. I created a new XPage and modeled it after your sample code.
Notable differences:
I never see the trash icon
I had to compute the UNID of some document with an attachment in the appropriate field
I set both the DB name and UNID in beforePageLoad
I noticed an interesting change in the UI behavior (see animated gif below)
I'm not sure what you're running into without having more source code to be able to view, but I can confirm that what I tried doesn't reproduce the result you're describing.
XPage source:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad><![CDATA[#{javascript:sessionScope.myDbName = database.getFilePath();
var vw:NotesView = database.getView("SomeForms");
var first:NotesDocument = vw.getFirstDocument();
sessionScope.myFirstDoc = first.getUniversalID();
first.recycle();
vw.recycle();}]]></xp:this.beforePageLoad>
<xp:this.data>
<xp:dominoDocument
var="document1"
action="openDocument"
formName="SomeForm"
databaseName="${javascript:return sessionScope.myDbName;}"
documentId="${javascript:return sessionScope.myFirstDoc;}" />
</xp:this.data>
<xp:fileDownload
rows="30"
id="fileDownload1"
displayLastModified="false"
value="#{document1.SomeAttachments}" />
<xp:button
value="Refresh"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete" />
</xp:button>
</xp:view>

Partial refresh on dynamic field binding removes values

Really looking for an idea why my XPage is doing this.
I have field with a dynamic databinding:
<xp:inputText id="CORE_Input" value="#{Document[compositeData.PARA_DataBinding]}"</xp:inputText>
That works quit well until I start to hide it based on a notes formula.
Let me tell what it does: I click a checkbox in my XPage. That checkbox is running SSJS which is calling: Document.getDocument(true) to push the data from my XPage back into the notesdocument without saving it. Once that is done I can use session.evaluate("checkbox!="something"") to hide the inputText field.
It works quit well but the problem is that once I untick the checkbox the value is gone from the inputfield.
If you know a better way to use notes formulas for hiding or the reason why the inputfield is empty once it comes back would be highly appreciated. Here is an example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:checkBox id="checkBox1" value="#{Document.Check}" text="hide" checkedValue="hide">
<xp:eventHandler event="onchange" submit="false">
<xp:this.script><![CDATA[document.getElementById("#{id:hide}").click()]]></xp:this.script>
</xp:eventHandler>
</xp:checkBox>
<xp:panel id="test">
<xp:inputText id="CORE_Input" type="#{compositeData.NODE}"
value="#{Document[compositeData.PARA_DataBinding]}"
defaultValue="#{javascript:compositeData.PARA_DefaultValue}" style="margin-left:24px">
<xp:this.styleClass><![CDATA[#{javascript:DOMElement.getAttribute("stylesize");}]]></xp:this.styleClass> <xp:this.rendered><![CDATA[#{javascript:var doc:NotesXspDocument=Document;
var erg=session.evaluate('Check="hide"',doc.getDocument());
if(#Text(erg)=="1")
{return false}
else
{return true}}]]></xp:this.rendered>
</xp:inputText>
<xp:button value="hide" id="hide">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="test">
<xp:this.action>
<![CDATA[#{javascript:var doc:NotesXspDocument=Document;doc.getDocument(true)}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xp:button value="unhide" id="unhide">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="test">
<xp:this.action><![CDATA[#{javascript:sessionScope.hide=""}]]></xp:this.action>
</xp:eventHandler></xp:button>
</xp:panel></xp:view>
The problem you have is your default value: As soon the component is unhidden, the value is recalculated. You have to check if the component is partially refreshed. If so, stop the recalculation:
<xp:this.defaultValue>
<![CDATA[#{javascript:
importPackage( com.ibm.xsp.ajax );
if( AjaxUtil.isAjaxPartialRefresh(facesContext) == true )
return;
compositeData.PARA_DefaultValue
}]]>
</xp:this.defaultValue>
This should solve your problem

When I save a document from an extension library dialog box some values are blank

Using 8.5.3 UP1
When I save my document from a dialog box certain fields are not being populated. If I save the document from within the xpage it saves these fields just fine. Here is a simple example to illustrate the issue:
<xp:link text="Save Document By Dialog"
id="link21">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[XSP.openDialog("#{id:dialog1}");]]></xp:this.script>
</xp:eventHandler>
</xp:link>
<br/>
<xp:button value="Save By Button" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:saveDocument var="document1"></xp:saveDocument>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xe:dialog id="dialog1" title="Dialog">
<br />
<b>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:"Save this document?"}]]></xp:this.value>
</xp:text>
</b>
<br />
<br />
<xp:button value="Yes" id="button7">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.script><![CDATA[XSP.closeDialog("#{id:dialog1}");]]></xp:this.script>
<xp:this.action>
<xp:saveDocument var="document1"></xp:saveDocument>
</xp:this.action></xp:eventHandler>
</xp:button>
<xp:button value="No" id="button8">
<xp:this.onclick><![CDATA[XSP.closeDialog("#{id:dialog1}");]]></xp:this.onclick>
</xp:button>
</xe:dialog>
<br/><br/>
<xp:inputText id="TitleTX" value="#{document1.TitleTX}"></xp:inputText>
<br/><br/>
<xp:inputRichText id="inputRichText1" value="#{document1.ProcessMapsRT}">
</xp:inputRichText>
The DOJO processes associated with the xe:dialog moves the dialog to another place in the DOM which means it will loose track of the data sources in the main parts of the document. If you do you saving in the dialog with SSJS instead of simple actions it may work better.
I have had the most success using a dialog contained in a custom control where the datasource is passed in through the composite data. That way the connection to the data is not lost and still works, BUT, I still use SSJS for saving in these situations.
/Newbs
UPDATE: This may be a time to use the technique Steve Pridemore described in NotesIn9 #42 (see xpages.tv).
First put a new event onto your XPage at the level with the data source in it.
<xp:eventHandler
id="saveEventHandler"
submit="true"
save="true"
event="calledbyid"
refreshMode="complete">
</xp:eventHandler>
Next, have the action in the dialog invoke this event using client side javascript:
XSP.executeOnServer('#{id:saveEventHandler}')
That "should" do it. I have not fully tested it but the examples from NoteIn9 do work.
/Newbs
Have you tried using dataContexts to define your datasource? I believe dataContext is a global object.
Update: dataContexts or even dominoDocument datasource worked when saving a document, but the problem was that the values were not saved. I therefore used a viewScope variable to store the values and that did the trick. I am not sure if this will help you, but here you go, this works for me:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xp:dominoDocument var="newDoc" formName="frmContact"></xp:dominoDocument>
</xp:this.data>
<xp:inputText id="inputText1" value="#{viewScope.firstName}"></xp:inputText>
<xp:inputText id="inputText2" value="#{viewScope.lastName}"></xp:inputText>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="dialog1">
<xp:this.action><![CDATA[#{javascript:getComponent("dialog1").show();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xe:dialog id="dialog1">
<xp:button value="Label" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:newDoc.replaceItemValue("fldFirstName", viewScope.firstName);
newDoc.replaceItemValue("fldLastName", viewScope.lastName);
newDoc.save();
getComponent("dialog1").hide();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xe:dialog>
</xp:view>
Hope this helps!
Ensure your data are posted to server before opening dialog. I would suggest to open such dialog with SSJS syntax - getComponent("dialog1").show()

Resources