Looking for best approach for signature button on xpage - xpages

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.

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>

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>

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

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.

XPage - Refreshing Repeat control

I have button in a xpage which creates a document and refreshes a repeat control. All is working fine except the repeat control is showing the newly added document at the top of the table (IMG1).
But after refresh the xpage again, the repeat control renders the table properly (IMG2)
Repeat Code
<xp:panel>
<xp:table style="width:100.0%">
<xp:tr>
<xp:td style="font-weight:bold">
Hardware
</xp:td>
<xp:td style="font-weight:bold">
Quantity
</xp:td>
<xp:td style="font-weight:bold">
Asset Tag No
</xp:td>
<xp:td style="font-weight:bold">
Previous User
</xp:td>
<xp:td>
</xp:td>
</xp:tr>
<xp:repeat id="rpHardware" rows="30" var="clHardwares">
<xp:this.value>
<![CDATA[#{javascript:var docMain:NotesDocument = compositeData.docOnboarding.getDocument();
var vwApp:NotesView = database.getView("lkupHardwaresByParentID");
vwApp.getAllDocumentsByKey(docMain.getUniversalID(),true)}]]>
</xp:this.value>
<xp:tr>
<xp:td>
<xp:text escape="true" id="cfHWName">
<xp:this.value>
<![CDATA[#{javascript:clHardwares.getItemValueString("REQ_HW_Name")}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td>
<xp:text escape="true" id="cfHWQuantity">
<xp:this.value>
<![CDATA[#{javascript:clHardwares.getItemValueString("REQ_HW_Quantity")}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td>
<xp:text escape="true" id="cfHWAssetTagNo">
<xp:this.value>
<![CDATA[#{javascript:clHardwares.getItemValueString("REQ_HW_AssetTagNo")}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td>
<xp:text escape="true" id="cfHWPreviousUser">
<xp:this.value>
<![CDATA[#{javascript:clHardwares.getItemValueString("REQ_HW_PreviousUser")}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td>
<xp:link escape="true" text="Edit" id="link4">
<xp:eventHandler event="onclick"
submit="true" refreshMode="complete">
<xp:this.action>
<![CDATA[#{javascript:viewScope.put("selHardware",clHardwares.getNoteID());
getComponent("dlgAddHardware").show();}]]>
</xp:this.action>
</xp:eventHandler>
</xp:link>
<xp:link escape="true" id="link5" text="Delete">
</xp:link>
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table>
</xp:panel>
Have you tried setting the repeat's "removeRepeat" property to TRUE? This removes unwanted div controls created from the repeat after the control's job is done.
(repeat >> All Properties >> basics)
EDIT:
forgot to mention that your button cannot perform a partial refresh on the repeat itself if that property is set to TRUE. Instead give your surrounding table or an aditional panel its own id which you can use to perform the necessery update
Did you refresh your view after creating the new document?
database.getView("ViewName").refresh();

Resources