Setting renderwholetree=false breaks app - xpages

I have an xpage that has a file upload control and a save button that uploads selected file. Below that is a panel with a viewPanel that shows newly uploaded file (for that instance). I am using a viewScope.key that is being set on the afterPageLoad event. The view is filtered by this key.
It was working until I set the renderwholetree=false in the application properties. Current behavior is that on first save, it doesn't show but when I click on the save button again, the view panel shows the last document that was uploaded. The save just saves the doc and does a full update.
<xp:button value="Save" id="button1"dojoType="dijit.form.Button">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete id="eventHandler1">
<xp:this.action>
<xp:saveDocument></xp:saveDocument>
</xp:this.action>
</xp:eventHandler>
</xp:button>
I was wondering if there is any other way to fix this without setting the renderwholetree back to true again.
Any help, suggestions is appreciated.

Related

xpages - partial refresh from dialogbox does not seem to work on repeat control. from outside the dialogbox it works

In an xp:dialog I have a button which loads back-end data and closes the dialog.
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="rptContainer">
<xp:this.action><![CDATA[#{javascript:
//load data. will not add the code for that but works fine;
viewScope.put("customers",promoBean.getCampaign().getCustomers());
getComponent("dlgCampaign").hide();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
On the event I have set partial refresh on a xp:panel control that contains a repeat control that is data-binded to viewScope.
<xp:panel id="rptContainer">
<xp:repeat id="rptCustomers" var="obj" indexVar="index" value="#{viewScope.customers}">...
With help of the xpages debug toolbar I see that the viewScope from the button in the dialog is being updated. but when the dialog is closed the changes are not visible in the repeat control.
I have placed a button outside the dialogbox which only performs the partial refresh and then the repeat control renders the changes.
Can anyone explain me how I can update the repeat control from within the dialog box?
I tried the onHide property of the dialog and used as code:
XSP.partialRefreshGet('#{id:rptContainer}');
But this has no effect.
I even tried a full update for the button event but this has also no result.
Can someone guide me how to do it the proper way?
when I close a dialogbox through SSJS, I close it using following syntax:
<xp:button value="OK" id="btnOK">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:/*your processing code*/
var dialogBox = getComponent('/*id of the dialog to close*/');
dialogBox.hide('/*id of the component to refresh*/');}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Although the refresh mode is 'complete', only the component in the 'hide' method is refreshed.

XPages form won't save field values if save button is within a xe:dialog

I have a Xpage with two custom controls containing editable fields tied to the single data source on the Xpage. On the Xpage I use a xe:dialog that contains a button to save the data source document1 (using SSJS). No validation is occurring yet. I use a xe:dialogButtonBar to call the xe:dialog (using CSJS) which opens fine and then click the OK button containing Action Save Document data source.
diablogButtonBar onClick call to open dialog.
XSP.openDialog("#{id:dialogSaveAsDraft}");
With this configuration the document is saved but the editable fields are not created nor data saved. The Xpage has the following two properties set, computeWithForm: onsave, action:editDocument but have tried createDocument too.
Here is the twist: If I take the button in the xe:dialog and place it outside the xe:dialog, the button works and the Xpage and all editable fields save properly.
What am I missing? I have done almost exactly the same thing before but instead of using the xe:dialogButtonBar I used a string of buttons. I wanted to use the xe:dialogButton Bar to organize the UI.
Can some one explain why that would occur?
The problem is about the form submission. When you launch the dialog, editable fields on the other parts of the page are not submitted (dialog is launched upon partial refresh). Therefore the back-end component tree is not aware of the field updates of the client-side.
You can either open the dialog from the SSJS (so it submits the page) or create a "noupdate" submission with onComplete script to launch the dialog.
<xp:link
escape="true"
text="Open Dialog with SSJS"
id="link1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="norefresh"
action="#{javascript:getComponent('dialogSaveAsDraft').show()}">
</xp:eventHandler>
</xp:link>
<xp:link
escape="true"
text="Open Dialog with onComplete"
id="link2">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="norefresh"
onComplete="XSP.openDialog('#{id:dialogSaveAsDraft}');">
</xp:eventHandler>
</xp:link>
If you use ComputeWithForm then you have to have a DisplayErrors control. That is where validation error messages will appear. Do you have that? If not you could be getting a validation error from the formulas on the form and they have no place to display the error messages. By the way, using ComputeWithForm is not really a good thing to do. You should repeat your validation logic directly on the XPage. Otherwise, you got too many things going on, the validation/translation that happens at the XPage level and again at the form level.

xpages go to a previous principal xpage

My scenario:
There is a navigator, having some links which redirect the user to some .xsp. Those .xsp contains some views listing certain documents. The users can create new documents using:
<xp:this.action>
<xp:openPage name="/doc.xsp" target="newDocument"></xp:openPage>
</xp:this.action>
Inside this doc., they can create other docs. ( with other datasource declared ) inside a <xe:dialog>. It has only one save and close button, which redirects me: into the current doc. if I opened the dialog from there or it directs me to the .xsp described above.
The problem: if I create a new Doc. and from its inside I create some docs from the dialog, with my Save button, I must hit it 2 times ( in most cases ) to redirect me to those .xsp described above. Why? because in this case my desired destination .xsp is not the PreviousPage, but the PreviousPreviousPage, the PreviousPage being doc.xsp?action=newDocument and the current page it is doc.xsp?documentId=E1141A490316FD88C2257D3400322723&action=openDocument, considering the fact that the doc. was already saved to open the dialog and from the save and close button I just redirect the users back to the main doc.
<xp:button value="Save" id="buttonSave" styleClass="lotusFormButton"
rendered="#{javascript:currentDocument.isEditable()}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" immediate="false" save="false"
id="eventHandler1">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument var="Cdoc"></xp:saveDocument>
<xp:openPage name="$$PreviousPage"></xp:openPage>
</xp:actionGroup>
</xp:this.action></xp:eventHandler>
</xp:button>
How can I resolve this issue?
I found this solution and for my case it seems to be the most useful.
Return-to-last-view
You just log the page name in a scope variable ( when you're opening a view - in my case the principal Xpage which contains the view ) , and from the Save button I just return to the last view opened ( contained by the xpage ).
I hope I got it right:
You may want to have a look at "navigation rules". Your save button e.g. could return a SSJS value:
return "home"
where 'home' is the name of your rule, directing you to your index.xsp.
So no matter what you did when you used your doc.xsp, how many dialogs you opened, if you click this button that uses the nav rule it will bring you to the page. You used the $$PreviousPage placeholder which simply generates a simple CSJS
history.go(-1)
which then will get you in the trouble you face now.
Try replacing the code for the Save button in the dialog with the following, assuming the id for the xe:dialog is dialog1:
<xp:button value="Save" id="buttonSave" styleClass="lotusFormButton"
rendered="#{javascript:currentDocument.isEditable()}">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
Cdoc.save();
var c = getComponent("dialog1");
c.hide("refreshPanel1");
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
The optional "refreshPanel1" passed to the hide method is the id of the containing element on the XPage to perform a partial refresh when the dialog is closed.

xpages redirect to page and close current dialog

My button code :
<xp:button value="Raport" id="button1" styleClass="lotusFormButton"
style="float:right;">
<xp:eventHandler event="onclick"
submit="true" refreshMode="complete" immediate="false"
save="true" id="eventHandler2">
<xp:this.action><![CDATA[#{javascript:context.redirectToPage("export_hidden.xsp");
getcomponent('exampleDialog').hide()}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
It just go to the export_hidden.xsp ( XAgent for creating an excel file ) but without closing the dialog.
I tried reverse the 2 actions, but same results.
I appreciate your time.
Add a client-side call to XSP.closeDialog('#{id:exampleDialog}') in the onComplete event of the eventHandler.
If I understand you correctly you want to send an attachment to the user but remain on the same page. and after the attachment is delivered close the dialogbox.
the problem above is that your code tries to do two things at once. both clse the dialog and deliver the attachment. That isn't possible.
I see two solutions I would try.
Remove the getcomponent('exampleDialog').hide() and execute that thru a button onclick on a second hidden button in the oncomplete event.
If that don't work, set the url to the export_hidden.xsp in an hidden iframe in your dialogbox and also do a on button click on a hidden button the closes the dialogbox
Doing the CSJS with partial update on the dialog box, along with context.redirectToPage(xAgentName) will work, Domino 9.0.1 FP9.

How can I duplicate a "cancel" button using a toolbar

I am using the toolbar control and that has several actions on it to allow the user to switch document modes, save, return to the view, etc.
I want to add a cancel button to allow the user to cancel their edits and switch them back to read mode.
Since the same event is shared by all these actions (I am using simple actions in computed action groups) I can't check off the "Do not validate or update data". If I do a context.redirectToPage("newpage.xsp") that will cause validation to happen.
I want to be able "cancel" the validation and then perform some action like switch to read mode or to another XPage. Any suggestions?
I guess I need a context.DontSave() method...Is there a method I can use to disable the validation/updating when submitting?
Thanks,
Howard
You can create a standalone cancel button that discards changes and reloads the current page. In the example below I have not taken into account that the current page can contain parameters such as editDocument, documentId etc.
<xp:button id="cancel" value="Cancel" rendered="#{javascript:document.isEditable()}">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="true" save="false" id="eventHandler1">
<xp:this.action>
<xp:actionGroup>
<xp:openPage name="#{javascript:view.getPageName()}"></xp:openPage>
</xp:actionGroup>
</xp:this.action></xp:eventHandler>
</xp:button>

Resources