Confirmation Action - Confirmation text, computed value not dynamic? - xpages

on my xpage I have a button where I have made the confirmation text computed with SSJS:
<xp:button value="Queue" id="btnQueue"
styleClass="btn-primary">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:return "Are you sure you want to change value from " + getComponent("From").value + " to " + getComponent("To").value + "?";}]]></xp:this.message>
</xp:confirm>
</xp:this.action></xp:eventHandler></xp:button>
I am using the same components to calculate the disable property. This works fine. Why not the computed text property?

Remember SSJS runs on the server, CSJS on the browser. #{javascript:....} means everything is being generated server-side and a literal message to the user is being passed to the browser, which will then be generated when the user clicks the button. So the "from" and "to" values are those that were on the server when it was last passed to the browser.
Don't use the simple action (which passes a server-side message to the browser). Use CSJS instead, confirm('My Message');. To get variable content from the current browser page into it, you need CSJS to retrieve the value from the relevant HTML element on the page, based on the ID. To use that, pass #{id:From} and #{id:To} into your preferred CSJS method for retrieving an element by ID.

Related

XPages: ask a confirmation when saving and set a value if confirmed

I have a document that gets published using an xagent (that does all sorts of things to the document).
Before sending to the xagent, I would like to ask the user if he wants the effective date of the document to be set to today's date. For now, I don't have that field available in edit mode on the page, but I guess I'll need it.
The big question is how to ask a confirmation (do you want the date to be set to today?) and put the date in the field before actually saving the document and sending it to the xagent page. I already have some simple actions into that save button. Here is the code:
<xp:button value="Save and Publish" id="button6">
<xp:this.rendered><![CDATA[#{javascript:database.queryAccessRoles(session.getEffectiveUserName()).contains('[Admin]') && currentDocument.isEditable()}]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:modifyField name="Status" var="pageDocument">
<xp:this.value><![CDATA[#{javascript:if(getComponent("publishLater1").getValue() == "1") {
return "Scheduled Publication";
} else {
return "To Be Published";
}}]]></xp:this.value>
</xp:modifyField>
<xp:saveDocument var="pageDocument">
</xp:saveDocument>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript: //remove the lock doc
//unlockDoc(pageDocument.getDocument().getUniversalID());
//for scheduled publications, a LotusScript agent will do the work
var res=facesContext.getExternalContext().getResponse();
if(getComponent("publishLater1").getValue() == "0") {
// Now load the publish Agent
res.sendRedirect(#Left(facesContext.getExternalContext().getRequestContextPath(),".nsf")+".nsf/xPublish?OpenAgent&docid=" + pageDocument.getDocument().getUniversalID());
} else {
//send to the drafts view, to show it has the clock icon in the draft view
res.sendRedirect(#Left(facesContext.getExternalContext().getRequestContextPath(),".nsf")+".nsf/adminDrafts.xsp");
} }]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
<i class="fa fa-newspaper-o pull-left fa-2x">
</i>
</xp:button>
You could do it several ways I'd think. If you're using the extension library you could use a dialogBox. so your save and publish button opens a dialog box with your question or even additional fields. Then you add a cancel button of course to the dialog box but also a "continue" button. That button accesses the fields if you put any in or knows that they want "today's" date and then that button calls the xagent passing in any appropriate parameters.
Presumably pageDocument is a dominoDocument datasource. A dominoDocument datasource is either all read only or all editable. And SSJS has access to that datasource. So add another executeScript action and you can modify whichever other field you want to as well.
What I'd recommend, though, is to skip the simple actions and do everything in script. The SSJS editor allows you to see all the methods available for a dominoDocument datasource. With a little knowledge of LotusScript or a little investigation, it should be obvious which method to use to replace an item value for the "Modify Field" simple action (quick tip, again go to the datasource rather than the publishLater1 component) and which method to save the document. If you start breaking away from simple actions and building your confidence in SSJS, it will give you greater flexibility in the long run.

How can I refresh the field in CSJS

How to refresh one field in csjs? the code is here:
<xp:repeat id="repeat1" rows="30" var="currentDetail" indexVar="detailIndex" value="#{LeaveBean.details}">
<xp:inputText id="leavefrom" value="#{currentDetail.subfromtime}">
<xp:eventHandler event="onblur" submit="false" refreshMode="partial" refreshId="repeat1">
<xp:this.script><![CDATA[
XSP.partialRefreshPost('#{id:view:_id1:repeat1:0:leavefrom}');
var detailIndex = document.getElementById("#{id:detailIndexText}").innerHTML;
myRPC.checkfromdate(detailIndex).addCallback(function(returnAlert){alert(returnAlert);});
]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
</xp:repeat>
what I want to do is call ssjs from csjs as you can see, but the strange thing to me is the click thing didn't work immediately, for example, when I first open the page, and click the input field, and enter "1" in it, it should be popup alert just when i left the field, but nothing happend, then I click this field again, and enter "2", then I left the field, but I just got the alert "1" on the secreen...sorry for my poor expressions...
so my question is I should refresh the field just when I left the field immediately, but why the XSP.partialRefreshPost not working? I tried to refresh repeat1, not working either
update 2015/06/13:
At last, I found view.postScript....so....
One obvious problem is the partialRefreshPost id won't work. You're combining #{id:...} which runs server-side to calculate the corresponding client-side ID. But the ID that you're passing is a client-side ID for the first row of the repeat. Even if that corresponded to a server-side component, you're trying to hard-code every row to map to a field in row 1 of the repeat ("repeat1:0").
Is there a reason for not using a normal partial refresh and using view.postScript in your SSJS to post CSJS back to the browser? You're triggering a partial refresh posting data back anyway. I'm not sure what the final line of your code is doing, but it seems like it's calling another server-side request to add a response. So the code seems to do two calls to the server, to trigger an alert. I don't know the design and what that subsequent rpc call is doing, but if it can be achieved in a single partial refresh, that would seem better.

Xpages: 'Go back to last page' breaks if there is a login form in between

Here is the scenario:
Page 1 is accessible to Anonymous users and has a link to Page 2, which has access control. When the user clicks on the button and is not logged in, he gets redirected to the $$LoginUserForm. As a result my simple-action 'Back' button (redirect to $$PreviousPage) is broken.
Is there anything I am missing, or must I do a solution where Page 1 notes where it is in a session variable, and the back button is coded to redirect to go back to Page 1?
I've seen these examples:
http://xcellerant.net/2013/03/15/return-to-last-view/
Saving current page in scope variable in xPages?
I've tried the various
facesContext.getExternalContext().getRequest().getRequeslURL|URI|getContextPath
but they are not storing the full url, only the bit before the parameters.
i.e.
http://albis/Development/Schulungen/Schulungen1_0/Schulungen_(1_0)_Dev.nsf/Kurs.xsp
and not
http://albis/Development/Schulungen/Schulungen1_0/Schulungen_(1_0)_Dev.nsf/Kurs.xsp?documentId=30760AABFD61BCC2C1257CCC0051B7A5&action=openDocument
Any pointers? Should I store the parameters separately?
To get the full URL have a look at this: http://mardou.dyndns.org/Privat/osnippets.nsf/snippet.xsp?documentId=C6D87172AE858572C1257B1000070CA6
(Watch the last code snippet there)
This value can be stored in a scope variable and then be used as value for a hidden field called "redirectto" that you have to define in your custom login page (with 2 other fields "username" and "password"). Domino will redirect you to that page defined in that hidden field.
Second option is to compute the scope value (with the full URL) in to the URL that redirects you to the login page, e.g.
/myNSF/myLoginPage.xsp?redirectto=http://redirectWhereYouWantGivenFromTheScopeVariable
Its not necessary to manage the page navigation in scoped variables when there is a single "back" location, i.e. page 1. Also, when this is the case stay away from $$PreviousPage and $$HomePage as well. For a one-option-navigation why not just hard code the location for the page open like follows?
<xp:button value="Back" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:openPage name="/XPage1.xsp"></xp:openPage>
</xp:this.action>
</xp:eventHandler>
</xp:button>

Session Expiration Warning

I have an XPages app that is supposed to save the main doc (and do a couple of other things) when the user clicks a button on the dialog box. The dialog box is presented by a CSJS function which runs according to a setInterval command. The dialog box and all the programming that present it are on a Custom Control. I have no problem displaying the dialog box, but have been unable to come up with a way to save the underlying document. I have other dialog boxes on their respective XPages, and saving the doc with a click (and some SSJS) works fine, but the same process doesn't seem to work if the dialog box is on a CC. I have searched all over the web, including StackOverflow, and haven't been able to find just what I need. Any ideas as to what I am missing?
Here's the code from one of my more recent attempts:
<xp:button value="Continue" id="button1">
<xp:eventHandler event="onclick" submit="false" id="eventHandler1">
<xp:this.script>
<![CDATA[
if (intvlID2) {
clearInterval(intvlID2);
}
var b18 = dojo.query('[id$="button18"]')[0];
if (b18) {
b18.click();
} else {
location.reload(true);
}
XSP.closeDialog('#{id:WarningDialog}');
]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
As you can see, it clears the interval first, then looks for a button on the underlying form. I've been able to verify that it does, in fact, find the button, but nothing happens with the click() command. The button it finds includes this save command that doesn't appear to execute:
document1.getDocument(true).save();
The button works perfectly when clicked by mouse or tapped by finger, but not when 'clicked' programmatically by another button on a CC.
The currentDocument global variable can be used to access the nearest dominoDocument datasource. Alternatively, the Extension Library dialog box has an additional parameter when closing the dialog box, the id of the refresh area. Maybe you can use that to trigger a save, something like setting a requestScope variable on close, and in the refresh area having code that does a save if the requestScope variable is set and, after save, clearing the requestScope variable?

Creating a response document via a button

I have two forms, Organisation and Contact. Contact is a response to Org, and each form has an XPage where the form can be filled in, saved etc. When opening edit_contact.xsp directly and creating a document (not as a response to an org), everything works fine.
On edit_org.xsp, I have a button with 2 events. The first copies some values into sessionScope so I can inherit them into the Contact. The second is a "Create Response Document" event which creates a new response with the parent ID being the current org document, and sends the user to edit_contact.xsp. Pressing the button changes XPage correctly and the field inheritance works fine, but pressing "Submit" on the Contact form doesn't save anything, and no document is created.
This exact same setup works 100% as desired in another database, I have no idea why it won't work properly here. Is there an obscure setting somewhere I am missing?
<xp:button value="Create Contact" id="button1" rendered="#{javascript:!document1.isEditable()}">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:var doc = document1.getDocument();
sessionScope.PFirstName = doc.getFirstItem("P_Firstname").getValueString();
sessionScope.PSurname = doc.getFirstItem("P_Surname").getValueString();
sessionScope.PFamily = doc.getFirstItem("P_Family").getValueString();
sessionScope.PDOB = doc.getFirstItem("P_DOB")
sessionScope.PAGE = doc.getFirstItem("P_Age").getValueString();}]]
</xp:this.script>
</xp:executeScript>
<xp:createResponse name="/edit_contact.xsp" parentId="#{javascript:document1.getNoteID()}">
</xp:createResponse>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>`
Here is a link that shows what I am trying to do (minus the field inheritance):
http://min.us/mKSJED8tT
Currently the forms and views all work, but the document created with the "Response" form appears not to be a response document - it has no $REF field. This setup works perfectly in a different database - what is going on?
It's hard to tell what might be happening without seeing any code. Since it works for you in another database, could it be an ACL issue? Where the user you're logging in as - possibly - anonymous - doesn't have the ability to create documents?
Instead of "push" approach go for "pull" - just open response page with url parameter of parent document. In its postNewDocument event initialize field values from it.
It would be useful to get an update on two key points made by others:
Is ignoreRequestParams set on your response document datasource? If not, regardless of what you're trying to define for the second datasource, it's UNID etc are pulled from the request parameters. So both datasources are effectively the same datasource.
Is it throwing a validation error? If so, nothing will be saved.
There are two possible issues:
First the use of getFirstItem("x") is not a best practice. So:
sessionScope.PDOB = doc.getFirstItem("P_DOB")
would be storing a NotesItem in the sessionScope which will not work. It is recommended to use:
sessionScope.PDOB = doc.getItemValueString("P_DOB");
Second the use of getNoteID() might not be returning what you want (Which is the UNID of the document). Use .getDocument().getUniversalID() instead.
<xp:createResponse
name="/edit_contact.xsp"
parentId="#{javascript:document1.getDocument().getUniversalID()}">
</xp:createResponse>
-edited-
/Newbs

Resources