The xpage ssjs code to open xe:dialog does not open dialog but change document mode from edit to read - xpages

My Xpage has five sections for workflow. Section 1 submit button works fine.
For second section submit button I'm calling xe:dialog box (using ssjs) to get some user inupt and it does open the xe:dialog box. But original document is now in read mode and submit button is not visible
If I remove the section 1, the section 2 button open dialog and does not change the document mode of original document.
Here is a sample code of xpage with dialog box and button.
<?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"
dojoTheme="true"
dojoParseOnLoad="true">
<xp:this.resources>
<xp:dojoModule
name="dijit.Dialog"></xp:dojoModule>
<xp:dojoModule
name="dijit.form.Button"></xp:dojoModule>
<xp:dojoModule
name="dijit.form.TextBox"></xp:dojoModule>
</xp:this.resources>
<xp:br></xp:br>
<xp:this.data>
<xp:dominoDocument
var="document1"
formName="MetalWorking">
</xp:dominoDocument>
</xp:this.data>
<xp:panel>
<xp:panel>
 
<xp:button
value="Lab Man Approval"
id="button4">
<xp:this.rendered><![CDATA[#{javascript:document1.isEditable() & (document1.getItemValueDate("Section1DateCompleted")!=null) & (document1.getItemValueDate("Section2DateCompleted") == null)
}]]></xp:this.rendered>
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete"
immediate="false"
save="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var d=getComponent('dialog2');
d.show();}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:button>
   <xp:br></xp:br>
<xe:dialog
id="dialog2">
<xp:panel
style="background-color:rgb(226,226,226)">
<xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Response"
id="responseArea_Label1"
for="responseArea1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
id="responseArea1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xe:dialog>
</xp:panel>
</xp:panel>
<xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Doc history:"
id="docHistory_Label1"
for="docHistory1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.DocHistory}"
id="docHistory1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:view>

Are you sure thats because of the "document1.isEditable()" and not because of all the other parts in your if your statement?
if i change your rendering code just like that
<xp:this.rendered><![CDATA[#{javascript: document1.isEditable() }]]></xp:this.rendered>
the button is pretty much visible.

Related

Button can be clicked only once on a XPage

I have the following XPage which has one table and only two tr's.
The first one is a button itself which puts into viewScope['showPasswordTr'] boolean true value when clicked first time, when puts false when clicked again.
The second tr has an input which is rendered if viewScope['showPasswordTr']is true.
The problem I've encountered is that I can only click the button only once and it's 100% because of input field present. If I remove it, it works as expected
The second time and so on, the button just freezes and doesn't execute the action specified onclick event. Why is so? And how can I make it work as expected?
Thanks in advance.
EDIT
Well, It's obviously all because of required property set to true... So, should I check the element for emptiness only in the disered control then? Is it a good practice?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:table id="buttonTable">
<xp:tr id="buttonTr">
<xp:td id="buttonTd">
<xp:button id="authAsPersonButton"
value="This button can be clicked only once" />
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" execId="buttonTable"
refreshId="buttonTable">
<xp:this.action>
<![CDATA[#{javascript:
print("clicked");
if(viewScope['showPasswordTr'])
{
viewScope['showPasswordTr'] = false;
}
else
{
viewScope['showPasswordTr'] = true;
}
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:td>
</xp:tr>
<xp:tr id="passwordLabelTr" rendered="#{javascript:
return viewScope['showPasswordTr'] == true;
}">
<xp:td id="passwordLabelTd">
<xp:text id="passwordText" style="font-size: 14px;">
<xp:this.value>
<![CDATA[#{javascript:
return 'password:';
}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td id="passwordInputTd" align="right">
<xp:inputText id="passwordInput" password="true"
required="true">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:view>
Add execId="buttonTd" or disableValidators="true" to your eventHandler properties. Then your example works as expected.
I optimized the code a bit (event handling within the button + shorter code for handling viewScope.showPasswordTr):
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:table id="buttonTable">
<xp:tr id="buttonTr">
<xp:td id="buttonTd">
<xp:button id="authAsPersonButton" value="Toggle password field">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="buttonTable" execMode="partial"
disableValidators="true">
<xp:this.action>
<![CDATA[#{javascript:
viewScope.showPasswordTr = !viewScope.showPasswordTr}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:td>
</xp:tr>
<xp:tr id="passwordLabelTr" rendered="#{!!viewScope.showPasswordTr}">
<xp:td id="passwordLabelTd">
<xp:text id="passwordText" style="font-size: 14px;" value="password:" />
</xp:td>
<xp:td id="passwordInputTd" align="right">
<xp:inputText id="passwordInput" password="true"
required="true">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:view>

Looking for best approach for signature button on xpage

I need a simple button whereby a user clicks to sign off on a document. A single signer per document, but when they click it, it puts their name and the date in two visible fields, and changes the status field.
What is the best approach for this? This is probably drop-dead simple but for some reason I cannot get it working.
They have been forced to log in by this time.
Thanks in advance.
Matt
Try the following:
<?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:dominoDocument>
</xp:this.data>
<xp:panel id="panelMain">
<xp:table>
<xp:tr>
<xp:td colspan="2">
<xp:label value="Main Form" id="label1"></xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:100.0px">
<xp:label value="Now" id="label2"></xp:label>
</xp:td>
<xp:td>
<xp:text escape="true" id="computedField1" value="${javascript:return #Now();}">
<xp:this.converter>
<xp:convertDateTime type="both"></xp:convertDateTime>
</xp:this.converter>
</xp:text>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
<xp:panel id="panelSignature" style="background-color:rgb(192,192,192)">
<xp:button value="I Agree" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="SignatureTable">
<xp:this.action><![CDATA[#{javascript:
document1.replaceItemValue("SignedDate",#Now());
document1.replaceItemValue("SignedBy",userBean.getDisplayName());}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:table id="SignatureTable">
<xp:tr>
<xp:td colspan="2">
<xp:label value="SignatureTable" id="label3"></xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:100.0px">
<xp:label value="SignedBy" id="label6"></xp:label>
</xp:td>
<xp:td>
<xp:inputText id="computedField4" value="#{document1.SignedBy}" readonly="true"></xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:100.0px">
<xp:label value="SignedDate" id="label5"></xp:label>
</xp:td>
<xp:td>
<xp:inputText id="computedField3" value="#{document1.SignedDate}" readonly="true">
<xp:this.converter>
<xp:convertDateTime type="both"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xp:view>
Judging by this "They have been forced to log in by this time." your problem is in your ACL. Seems, you allow anonymous reading of the document, but in the moment you want to save it, ACL does not allow anonymous users to do that, so Domino asks for their identity.
Set anonymous access to No access level.
Here's a button, but if the user is not logged in and does not have anonymous edit access, then a login dialog will appear. For a signing function, I assume the user must be logged in to sign. document1 is the Xpage data document to be signed.
<xp:button
value="Sign"
id="button1"
styleClass="btn btn-primary">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
document1.appendItemValue("SignerName", session.getEffectiveUsername();
document1.document1("SignedDate", session.createDateTime(#Now()));
document1.save();
}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:button>
If you need to update a document without logging in, then in the button, you will have to get the doc with sessionAsSigner and then update.

Cannot Save xPage

My XPage will not save any data that I enter into it. The screen just flashes and the document that is open just redisplays. I assume it has something to do with where the buttons to save (Speichern) / cancel (Abbrechen) have been placed but, no matter where I place them they don't work. I am having the same problem with the New button - although I assume if the one error is found the other problem will be solved :)
Any help would be greatly appreciated as I have been looking into this for the whole day!
Here is the code for the page layout control:
<?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">
<xe:applicationLayout id="applicationLayout1">
<xe:this.facets>
<xp:callback facetName="facetLeft" id="facetLeft" xp:key="LeftColumn">
</xp:callback>
</xe:this.facets>
<xp:callback facetName="facetMiddle" id="facetMiddle">
</xp:callback>
<xe:this.configuration>
<xe:simpleResponsiveConfiguration navbar="true" invertedNavbar="true" fixedNavbar="fixed-top"
navbarText="Thomas Vogel Dokumentation" pageWidth="fluid">
<xe:this.navbarAppLinks>
<xe:pageTreeNode label="Neu" page="/xpNewDocument.xsp"></xe:pageTreeNode>
<xe:loginTreeNode enabled="true" title="Abmelden" label="Abmelden"></xe:loginTreeNode>
</xe:this.navbarAppLinks>
</xe:simpleResponsiveConfiguration>
</xe:this.configuration>
</xe:applicationLayout>
</xp:view>
Here the code for the menu:
<?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">
<xe:navigator id="navigator1">
<xe:this.treeNodes>
<xe:pageTreeNode label="nach Titel" page="/xpByTitle.xsp"></xe:pageTreeNode>
<xe:pageTreeNode label="nach Kategorie" page="/xpByCategory.xsp"></xe:pageTreeNode>
<xe:pageTreeNode label="nach Ersteller_in" page="/xpByCreatedBy.xsp"></xe:pageTreeNode>
<xe:pageTreeNode label="nach Datum" page="/xpByDate.xsp"></xe:pageTreeNode>
</xe:this.treeNodes>
</xe:navigator></xp:view>
And finally the for the EditDocument page:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.data>
<xp:dominoDocument var="document1" formName="fmDoc" action="editDocument">
</xp:dominoDocument>
</xp:this.data>
<xc:ccPageLayout>
<xp:this.facets>
<xc:ccMenu xp:key="facetLeft"></xc:ccMenu>
<xp:panel xp:key="facetMiddle">
<xp:table>
<xp:tr>
<xp:td>
<xp:label value="Titel" id="titel_Label1" for="titel1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText value="#{document1.Titel}" id="titel1">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Datum" id="dokDatum_Label1" for="dokDatum1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText value="#{document1.dokDatum}" id="dokDatum1">
<xp:dateTimeHelper id="dateTimeHelper1">
</xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date" dateStyle="short">
</xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Kategorie" id="label3" for="kategorie1">
</xp:label>
</xp:td>
<xp:td>
<xp:comboBox id="kategorie1" value="#{document1.kategorie}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var currDB:NotesDatabase = database;
var profileDoc:NotesDocument=currDB.getProfileDocument("configDatabase","");
var docUID=profileDoc.getItemValueString("kategorieDok");
var categoryDoc:NotesDocument = currDB.getDocumentByUNID(docUID);
var categories = categoryDoc.getItemValueString("kategorie");
#Explode(#Text(categories), ";")
}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Anhänge" id="label1" for="fileUpload1">
</xp:label>
</xp:td>
<xp:td>
<xp:fileUpload id="fileUpload1" value="#{document1.anhaenge}" useUploadname="true"></xp:fileUpload>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value=" " id="label2" for="fileDownload1">
</xp:label>
</xp:td>
<xp:td>
<xp:fileDownload rows="5" id="fileDownload1" displayLastModified="false" value="#{document1.anhaenge}"
hideWhen="true" displayType="false" displayCreated="false" allowDelete="true">
</xp:fileDownload>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td colspan="2">
<xp:inputRichText id="inputRichText1" value="#{document1.body}">
</xp:inputRichText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td colspan="2">
</xp:td>
</xp:tr>
</xp:table>
<xp:button value="Speichern" id="button2">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="false" save="false">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument var="document1"></xp:saveDocument>
<xp:openPage name="$$PreviousPage"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Abbrechen" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:openPage name="$$PreviousPage"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
</xp:this.facets>
</xc:ccPageLayout>
</xp:view>

In one of the buttons I noticed this part immediate="false" save="false"
save should be set to true, I think.
I may have missed it but you should ALWAYS have a displayErrors control. There could be a conversion error or something that you wouldn't otherwise see. You should also think about adding the XPages Log Reader as that can expose other error messages.

XPages: save action button inside an mobile appPage and panel does not save the data source document assigned to the panel

I'm building in Domino Application with the Xpages extension library enabled a mobile page with an xe:singlePageApp and more xe:appPage(s). An xe:appPage is containing a panel having as data source a domino document. Within the same panel is a submit/save buttons I'm using to save the contents edited/changed in fields in document data source.
Due to indications of already posted questions and answers at Xomino , here on StackOverflow as well a on the XPages Wiki (links not provided here because I'm not allowed yet to post more than 2 links) - the submit button is within the panel and the data source is also declared for/within that panel (in the code below "panelDocContent").
The xp:inputText controls on the page have the same id and variable as the fields of the data source. If I set via SSJS in another button some values on the page - they are successfully set and a round rect list item with visibility depending on the set values is appearing as expected showing the fields also changed.
Problem: the Save/Submit button "Submit for approval" does not save the changes to the data source assigned to the panel.
I already tried also "ignoreRequestParams"=true set in the document data but this is in this context not an option. When I try this the corresponding document from the initial appPage with a DataView element supposed to open with the document AppPage is not loaded with its values - they are shown empty.
Any idea what I'm doing wrong here or what I could do different to submit the values in the editable changed fields (visible first when pressing "Request this tool" button ?
Here is the xPages / Custom control code:
<?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">
<xe:appPage id="docContent" pageName="docContent"
resetContent="true">
<xp:panel id="panelDocContent">
<xp:this.data>
<xp:dominoDocument var="docTool" formName="Tool"
action="editDocument" scope="request">
</xp:dominoDocument>
</xp:this.data>
<xe:djxmHeading id="djxmHeading2" back="Back" style="text-align:center">
<xe:this.moveTo><![CDATA[#{javascript:viewScope.get("pageToReturn");}]]></xe:this.moveTo>
<xp:this.facets>
</xp:this.facets>
<xe:this.label><![CDATA[#{javascript:"Tool"}]]></xe:this.label>
</xe:djxmHeading>
<!-- BUTTONS ! -->
<xp:panel id="preButtonPanel" style="font-size:8px;">.</xp:panel>
<xp:panel id="buttonPanel" style="text-align:center">
<xp:button value="Request this Tool" id="button1" style="font-size:12pt">
<xp:this.rendered><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
(_status=="Available")}]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:docTool.getDocument().replaceItemValue("Status", "Requested");
docTool.getDocument().replaceItemValue("SubmissionStatus", "Not Submitted");}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Submit for Approval" id="button4" style="font-size:12pt">
<xp:this.rendered><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
_submissionstatus = docTool.getDocument().getItemValueString("SubmissionStatus");
(_status=="Requested") && (_submissionstatus == "Not Submitted") }]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:if (docTool.isEditable()) {
docTool.save();
sessionScope.msg="Data source docTool saved.";
_dump(sessionScope);
} else {
sessionScope.msg= "Document not in edit mode";
}
_dump(sessionScope);
context.redirectToPage("#viewPage");
}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action></xp:eventHandler></xp:button>
</xp:panel>
<xp:panel id="panelPostButtons" style="font-size:8px;">.</xp:panel>
<!-- END OF BUTTONS -->
<xe:djxmRoundRectList id="djxmRoundRectList2">
<xp:messages id="errormessages1"></xp:messages>
</xe:djxmRoundRectList>
<xe:djxmRoundRectList id="djxmRoundRectList1">
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="font-weight:bold">
Tool information
</xp:td>
</xp:tr>
</xp:table>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:22.0%">Type</xp:td>
<xp:td style="width:69.0%">
<xp:label id="dspType">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("ToolType");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22.0%">Part No.</xp:td>
<xp:td style="width:69.0%">
<xp:label id="dspPartNo">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("PartNumber");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Status</xp:td>
<xp:td>
<xp:label id="dspStatus">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("Status");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Submission status</xp:td>
<xp:td><xp:label id="dspSubmissionStatus">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("SubmissionStatus");}]]></xp:this.value>
</xp:label></xp:td>
</xp:tr>
</xp:table>
</xe:djxmRoundRectList>
<xe:djxmRoundRectList id="djxmRoundRectList3">
<xe:this.rendered><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
_submissionstatus = docTool.getDocument().getItemValueString("SubmissionStatus");
(_status!="Available") && (_submissionstatus != "") }]]></xe:this.rendered><xp:table style="width:100.0%">
<xp:tr>
<xp:td
style="font-weight:bold;color:rgb(255,0,0)">
Please enter following mandatory
information:
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="font-weight:bold">
Shipping Address
</xp:td>
</xp:tr>
</xp:table>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:22%">
Company data
<xp:span
style="font-weight:bold;color:rgb(255,0,0)">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="Company" style="width:99%"
value="#{docTool.Company}">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22%">
Customer data
<xp:span
style="font-weight:bold;color:rgb(255,0,0)">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="CustomerData"
style="width:99%" value="#{docTool.CustomerData}">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22%">
Demo reason
<xp:span
style="color:rgb(255,0,0);font-weight:bold">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="DemoReason"
style="width:99%" value="#{docTool.DemoReason}">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xe:djxmRoundRectList>
</xp:panel>
</xe:appPage>
</xp:view>
Here is also a link to ZIP with the entire application for getting the whole and direct idea of dependencies.
https://www.dropbox.com/s/rs1la3m0pfm548a/DemoTools_dev.zip?dl=0
I'll keep it there for the next 2-3 months.
In that code I also tried a simple "save document" action with the same data source indicated.
I've already spent a lot of time to get that solved and I'm stuck at this point. Any help will be much appreciated.
A colleague in my team shown me how to bring my custom control with that problem to work.
He made the "Request for approval" button to do only a partial refresh of the rounded list where status is set - the one with computed labels only. The same button to use then client side javascript to hide/show buttons and rounded list with editable fields. The submit button can then set the status fields again and save the document behind the data source "docTool". With that trick the page does not refresh fully with the effect that the document handle is then lost for the "Submit for approval" button.
He taken also advantage of the possibilities to execute CSJS in other events than onclick. These events can be found by selecting the eventhandler for the button in the Source view and then look at All properites in the Properties panel. These can be used when a partial refresh is triggered.
Another part of the trick was using Computed value for style in All properties for the different elements client-side, insted of the "Visible" property (in code "rendered" on server-side).
Here is the code of the corrected custom control where the "Submit for approval" button works the way described above:
<?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">
<xe:appPage id="docContent" pageName="docContent"
resetContent="true">
<xp:panel id="panelDocContent">
<xp:this.data>
<xp:dominoDocument var="docTool" formName="Tool"
action="editDocument" scope="request">
</xp:dominoDocument>
</xp:this.data>
<xe:djxmHeading id="djxmHeading2" back="Back"
style="text-align:center">
<xe:this.moveTo><![CDATA[#{javascript:viewScope.get("pageToReturn");}]]></xe:this.moveTo>
<xp:this.facets>
</xp:this.facets>
<xe:this.label><![CDATA[#{javascript:"Tool"}]]></xe:this.label>
</xe:djxmHeading>
<!-- BUTTONS ! -->
<xp:panel id="preButtonPanel" style="font-size:8px;">.</xp:panel>
<xp:panel id="buttonPanel" style="text-align:center">
<xp:button value="Request this Tool" id="buttonRequest">
<xp:this.rendered><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
(_status=="Available")}]]></xp:this.rendered>
<xp:this.style><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
var display = "none";
if(_status=="Available"){
display = "inline-block";
}
"font-size:12pt;display:"+display;}]]></xp:this.style>
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="djxmRoundRectListDisplayFields">
<xp:this.action><![CDATA[#{javascript:docTool.getDocument().replaceItemValue("Status", "Requested");
docTool.getDocument().replaceItemValue("SubmissionStatus", "Not Submitted");}]]></xp:this.action>
<xp:this.onComplete>
<![CDATA[var buttonSubmit = "#{id:buttonSubmit}";
document.getElementById(buttonSubmit).style.display = "inline-block";
var buttonRequest = "#{id:buttonRequest}";
document.getElementById(buttonRequest).style.display = "none";
var editablefields_id = "#{id:djxmRoundRectListEditableFields}";
document.getElementById(editablefields_id).style.display = "block";]]></xp:this.onComplete>
</xp:eventHandler>
</xp:button>
<xp:button value="Submit for Approval" id="buttonSubmit">
<xp:this.style><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
_submissionstatus = docTool.getDocument().getItemValueString("SubmissionStatus");
var display = "none";
if((_status=="Requested") && (_submissionstatus == "Not Submitted")){
display = "inline-block";
}
"font-size:12pt;display:"+display;}]]></xp:this.style>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:if (docTool.isEditable()) {
print("Data source docTool saved.");
docTool.replaceItemValue("SubmissionStatus", "Submitted");
docTool.replaceItemValue("Status", "Requested");
docTool.save();
} else {
print("Document not in edit mode");
}
context.reloadPage();}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:panel>
<xp:panel id="panelPostButtons" style="font-size:8px;">.</xp:panel>
<!-- END OF BUTTONS -->
<xe:djxmRoundRectList id="djxmRoundRectListDisplayFields">
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="font-weight:bold">
Tool information
</xp:td>
</xp:tr>
</xp:table>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:22.0%">Type</xp:td>
<xp:td style="width:69.0%">
<xp:label id="dspType">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("ToolType");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22.0%">Part No.</xp:td>
<xp:td style="width:69.0%">
<xp:label id="dspPartNo">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("PartNumber");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Status</xp:td>
<xp:td>
<xp:label id="dspStatus">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("Status");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Submission status</xp:td>
<xp:td>
<xp:label id="dspSubmissionStatus">
<xp:this.value><![CDATA[#{javascript:docTool.getDocument().getItemValueString("SubmissionStatus");}]]></xp:this.value>
</xp:label>
</xp:td>
</xp:tr>
</xp:table>
</xe:djxmRoundRectList>
<xe:djxmRoundRectList id="djxmRoundRectListEditableFields">
<xe:this.style><![CDATA[#{javascript:_status = docTool.getDocument().getItemValueString("Status");
_submissionstatus = docTool.getDocument().getItemValueString("SubmissionStatus");
var display = "none";
if((_status!="Available") && (_submissionstatus != "")){
display = "block"
}
"display:"+display;}]]></xe:this.style>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td
style="font-weight:bold;color:rgb(255,0,0)">
Please enter following mandatory
information:
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="font-weight:bold">
Shipping Address
</xp:td>
</xp:tr>
</xp:table>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:22%">
Company data
<xp:span
style="font-weight:bold;color:rgb(255,0,0)">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="Company" style="width:99%"
value="#{docTool.Company}">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22%">
Customer data
<xp:span
style="font-weight:bold;color:rgb(255,0,0)">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="CustomerData"
style="width:99%" value="#{docTool.CustomerData}">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:22%">
Demo reason
<xp:span
style="color:rgb(255,0,0);font-weight:bold">
*
</xp:span>
</xp:td>
<xp:td style="width:69.0%">
<xp:inputText id="DemoReason"
style="width:99%" value="#{docTool.DemoReason}">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xe:djxmRoundRectList>
</xp:panel>
</xe:appPage>
</xp:view>
Here is also dropbox link with a zipped copy of the entire database with this construct for testing. I think I'll keep it 6 months from now:
https://www.dropbox.com/s/2iy00xc10v3tis4/DemoTools_dev_forforums2.zip?dl=0
This is NOT an answer but an attempt to give some information and I needed more room then the comments allowed.
I downloaded and played with this for a little but. I'm not sure what's going on here.
You're save button is a little odd. I added a print statement and couldn't get anything to print. It's in an action group for now reason so you might want to get rid of that and just redo the button. Since there was only 1 action I would NOT use the simple action - execute script - I'd just type the code in via the script editor. After doing that I got mu print statements and it LOOKED like it saved but each save caused a replication conflict and the customer data wasn't even there. So there's some fundamental issue I'm not seeing.
One thing that I'm missing... and it might be because I don't work with DataView controls but I'm not seeing how the data document is being linked. You're declaring the "docTool" var in your Panel dataSource... but there's no document ID in there. So I'm not seeing how that's supposed to work. Obviously it is to some extent at least because you're reading data.
I'd be curious to try and rebuild this from scratch to try and replicate but personally I just don't like Mobile controls anymore and don't recommend them but what you're doing here is "simple enough" and should work. But I'm sure stumped at the moment without putting more time in.
Suggest you step back - add more print("") statements... to output info to the console. For instance in your dataSource I could get a message to print on document open but not anything for document save.
Below is the little code for a new save button that I was playing with. Again I got it to save but it only created conflicts.
another note. Everywhere for reading you're doing docTool.getDocument()..... but for save you're just docTool.save(). So the conflicts might be a result of the XSPDocument vs the real document. I'm not sure. I have to think that if you can get into your dataSource the documentID that MIGHT solve your problems. but that's just a guess.
Good Luck!
<xp:button value="New Save" id="button5">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print("CHECKING")
if (docTool.isEditable()) {
print("Editable")
docTool.save();
print("Data source docTool saved.");
} else {
print("NOT EDITABLE")
print("Document not in edit mode");
}
context.redirectToPage("#viewPage");
}]]></xp:this.action>
</xp:eventHandler></xp:button>

XPages Mobile Control Partial refresh returns to menu page

I have a simple page inside mobile controls. I have an edit box and what I want to happen is to a partial refresh of the current in the onChange event of the edit control. Basically type something in the edit control - hit enter and do the partial refresh.
What's happening is hitting enter if returning the page to the main menu. If I put a value in and hit TAB then it works as I would want.
I'm starting a new app from scratch. But I've done this concept many times with an app in production. I can't find anything special in the code that would "trap" an enter button... So I'm at a loss why I can't get the behavior I want this time around.
Here's a video demo of the problem:
http://traffic.libsyn.com/notesin9/SO-Question2-HB.mp4
Below is the full code.
Thanks for any help!!
<?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">
<xp:this.resources>
<xp:styleSheet href="/.ibmxspres/dojoroot/dijit/themes/tundra/tundra.css">
</xp:styleSheet>
<xp:styleSheet href="/mobile.css"></xp:styleSheet>
</xp:this.resources>
<xe:singlePageApp id="singlePageApp1"
selectedPageName="mainMenu">
<xe:djxmHeading id="djxmHeading1" label="My App"></xe:djxmHeading>
<xe:appPage id="mainMenuID" pageName="mainMenu">
<xe:djxmRoundRectList id="djxmRoundRectList1"
title="Main Menu">
<xe:djxmLineItem id="djxmLineItem9" moveTo="#container"
label="Test Page">
</xe:djxmLineItem>
</xe:djxmRoundRectList>
</xe:appPage>
<xe:appPage id="containerID" pageName="container"
resetContent="true">
<xe:djxmHeading id="djxmHeading5" label="My Page"
back="Main Menu">
</xe:djxmHeading>
<xe:djxmRoundRectList id="djxmRoundRectList2">
<xp:panel id="mainPanel">
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="width:50%"></xp:td>
<xp:td>Details</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:inputText id="inputText1" styleClass="target alignVMiddle"
value="#{sessionScope.myValue}">
<xp:this.attrs>
<xp:attr name="autocorrect" value="off"></xp:attr>
<xp:attr name="placeholder" value="Tap to Scan...">
</xp:attr>
</xp:this.attrs>
<xp:eventHandler event="onchange" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:viewScope.put("test", "test");}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
</xp:td>
<xp:td></xp:td>
</xp:tr>
</xp:table>
<xp:br></xp:br>
Current Value: 
<xp:text escape="true" id="computedField1" value="#{sessionScope.myValue}"></xp:text>
<xp:br></xp:br>
<xp:br></xp:br>
Current Time: 
<xp:text escape="true" id="computedField2" value="#{javascript:#Now();}">
<xp:this.converter>
<xp:convertDateTime type="time"></xp:convertDateTime>
</xp:this.converter>
</xp:text>
</xp:panel>
</xe:djxmRoundRectList>
</xe:appPage>
</xe:singlePageApp>
</xp:view>
Can you do something like this to force a partial refresh on Enter?
<xp:inputText id="inputText1" value="#{sessionScope.myValue}">
<xp:eventHandler event="onkeypress" submit="true" refreshMode="partial" refreshId="something">
<xp:this.script><![CDATA[//partial refresh on Enter
if( thisEvent.keyCode === dojo.keys.ENTER ){
dojo.stopEvent( thisEvent );
} else {
return false;
}
]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
I think the problem is that enter will try to do a submit and submit will return you to the first page. Try to add a check in onkeyup or down for charcode 13 and if this is found return false.
You might also need to do a stopproprigate or something like that.
Google for enter key submit form
From my mobile ;-)
Or perhaps this post. http://tinyurl.com/bsgy9g6

Resources