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

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>

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 2 partial refreshes from a required field

I have an inputText which is a required field on my Document.
<xp:inputText value="#{Cdoc.txt_NumeCompanie}" id="txt_NumeCompanie"
required="true" defaultValue="#{javascript:param.value}">
<xp:this.validators>
<xp:validateRequired message="Numele companiei este obligatoriu." loaded="true">
</xp:validateRequired>
</xp:this.validators>
<xp:eventHandler event="onchange" submit="false" disableValidators="true">
<xp:this.script><![CDATA[ XSP.partialRefreshPost("#{id:scrollDiv}", {
onComplete: function() {
XSP.partialRefreshPost("#{id:pers}");
}
});
]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
I also checked the Process data without validation ( from the Server tab ... ). But still no refresh is taking place.
You do not include the required second parameter on your second partialRefreshPost. Try this:
XSP.partialRefreshPost("#{id:scrollDiv}", {
onComplete: function() {
XSP.partialRefreshPost("#{id:pers}", {});
}
});
Update: you can use the onComplete event of the eventHandler to run your 2nd partial refresh. So use the traditional partial refresh of the first component and then run your 2nd partial refresh through the onComplete event:
<xp:inputText value="#{Cdoc.txt_NumeCompanie}" id="txt_NumeCompanie" required="true" defaultValue="#{javascript:param.value}">
<xp:this.validators>
<xp:validateRequired message="Numele companiei este obligatoriu." loaded="true">
</xp:validateRequired>
</xp:this.validators>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="scrollDiv">
<xp:this.onComplete><![CDATA[XSP.partialRefreshPost("#{id:pers}", {});]]></xp:this.onComplete>
</xp:eventHandler>
</xp:inputText>
By setting submit="false", you're preventing any server-side processing from being triggered by the eventHandler itself. That means disableValidators="true" is irrelevant, because the XPages lifecycle is not being processed from the eventHandler.
Instead the refresh is being generated from the client-side code, the XSP.partialRefreshPost. That doesn't have an option to disable validation, as covered here How to disable validators using the XSP.partialRefreshPost method?. disableValidators="true" doesn't and cannot influence the processing of the partialRefreshPost. So chances are your validation is still running. To confirm that, add an errors panel into the initial refresh area.
partialRefreshGet may work, I'm not sure.
My usual approach in these scenarios is to refresh a single area that comprises both areas you wish to refresh. Then set submit="true" and disableValidators="true". But bear in mind that even if validation is disabled, data conversion is still checked so if you enter a text value in a number field, the partial refresh would still fail.
Ok, first thing to do is open your toolbox and look at the network traffic. This will help you to understand what is going on. You can use FireBug in FireFox or Developer tools in Google Chrome.
What network traffic occurs for the above snippet?
Edit:
Still waiting to hear what network traffic is generated...
But just looking at your code... - try set submit="true". I had a look at some of the code I have, and I am not sure that the extra empty param is required :-)
Could you explain what you are trying to obtain?
Edit
Ok, I see what you want. I had a quick view in some code. I am not doing exactly the same that you are. However, when I nest the partial refreshes I typically do it this way:
<xp:button id="button1"
styleClass="btn btn-danger btn-lg#{FishingTripEdit.typeInput eq '1' ? ' inActive' : ''}">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial"
refreshId="inputTypeSelected" disableValidators="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:MyBean.setData('0')}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
<xp:this.onComplete><![CDATA[XSP.partialRefreshGet("#{id:buttonTopHolder}")]]></xp:this.onComplete>
<xp:this.script><![CDATA[return document.getElementById("#{id:triggerAsk}").value!=='1' ? true : confirm("Sure?")]]></xp:this.script>
</xp:eventHandler>
</xp:button>
So for the "first" refresh I use the builtin markup - and onComplete I add the second as plain JavaScript. I know this is an example with a partialRefreshGet (which I prefer to use if at all possible due to less overhead). But perhaps it can give you an idea....

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.

Setting renderwholetree=false breaks app

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.

Resources