Teamstudio Unplugged: Inline edit - xpages

I'm using teamstudio's unplugged for the record.
I'm trying to build a table using a repeat control with a view as a data source.
The user should be able to change edit the documents and then save all data sources.
Below is a example that currently does not work.
I have also tried using computed ids for all the different check-boxes in the cells and
storing the UNID of the row's document in a hidden text field and then read every row based on the computed ids and saving them. That didn't work because computing ids in a repeater is impossible in unplugged despite tons of effort.
If i have done something wrong or there is a trick i haven't tried, i would love to hear about it.
<xp:table id="table">
<xp:tr>
<xp:td>Document name</xp:td>
<xp:td>Field1</xp:td>
<xp:td>Field2</xp:td>
<xp:td>Field3</xp:td>
</xp:tr>
<xp:repeat id="repeat1" rows="30"
value="#{TestDocs}" indexVar="index" var="Docs" first="0"
removeRepeat="true" repeatControls="true">
<xp:panel>
<xp:tr>
<xp:td>
<xp:text id="Name" escape="true"
value="#{document1.Name}">
</xp:text>
</xp:td>
<xp:td>
<xp:checkBox id="Field1"
checkedValue="true" uncheckedValue="false"
value="#{document1.Field1}">
<xp:this.defaultChecked><![CDATA[${javascript:
if(document1.getDocument().getItemValue("Field1")=="[true]"){
return true;
}else{
return false;
}}]]></xp:this.defaultChecked>
</xp:checkBox>
</xp:td>
<xp:td>
<xp:checkBox id="Field2"
checkedValue="true" uncheckedValue="false"
value="#{document1.Field2}">
<xp:this.defaultChecked><![CDATA[${javascript:
if(document1.getDocument().getItemValue("Field2")=="[true]"){
return true;
}else{
return false;
}}]]></xp:this.defaultChecked>
</xp:checkBox>
</xp:td>
<xp:td>
<xp:checkBox id="Field3"
checkedValue="true" uncheckedValue="false"
value="#{document1.Field3}">
<xp:this.defaultChecked><![CDATA[${javascript:
if(document1.getDocument().getItemValue("Field3")=="[true]"){
return true;
}else{
return false;
}}]]></xp:this.defaultChecked>
</xp:checkBox>
</xp:td>
</xp:tr>
</xp:panel>
</xp:repeat>
</xp:table>
<xp:button value="Save" id="button3"
styleClass="button">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" disableValidators="true">
<xp:this.action>
<xp:save></xp:save>
</xp:this.action>
</xp:eventHandler>
</xp:button>

My inclination would be to move the logic for all of this client side. So build the table with jQuery, and then on save, take the values out of the fields you create and write them into hidden fields that will actually get saved.
In terms of computing IDs of fields etc, I would add attributes to the elements you want to work with and then select them using jQuery:
$('[myattr="the value"]')

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.

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>

How to Save Values in Documents Edited In-line On Repeat Control

I have a repeat control on an xPage with a text field displayed directly in edit mode. When a user changes the value in the field, I need them to be able to either:
Select an icon directly beside the field to save the value in the document.
Make changes to this field in more than one document and click a button to save all of these changes to the appropriate documents saved simultaneously.
What I have so far is a method of capturing the unids of the documents whose editable field has been updated.
I cannot get either of these saves to work. I have listed below the portion of the code that controls these areas.
Here's the save all and sessionScope information
<xp:panel id="InlineEditContainer" xp:key="facetMiddle" style="width:100%">
<xp:this.data>
<xp:dominoView var="view1" viewName="vwMetricsByAssigned">
<xp:this.postOpenView><![CDATA[#{javascript:var myList = new java.util.ArrayList();
sessionScope.put("myList", myList);}]]></xp:this.postOpenView></xp:dominoView>
</xp:this.data>
<xp:button value="Submit All" id="button1">
<xp:eventHandler event= <"onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:// Getting list of unids from docs which have been updated, and saving those docs
var db:NotesDatabase
if(sessionScope.myList == null){
return;
}else{
for (var s in sessionScope.myList){
var doc:NotesDocument = (db ? db.getDocumentByUNID(s) : database.getDocumentByUNID(s));
if (doc && doc.isValid()) {
doc.save();
}
}
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:repeat id="repeat1" rows="30" value="#{sessionScope.myList}" var="listData">
<xp:text escape="true" id="computedField6"><xp:this.value><![CDATA[#{javascript:listData + " , "}]]></xp:this.value></xp:text></xp:repeat>
<xp:br></xp:br>
Here's all the repeat data
<xp:repeat id="repeat2" rows="20" var="FColl" indexVar="idx" value="#{javascript:view1}">
<xp:panel id="InlineEditContainer2">
<xp:this.data>
<xp:dominoDocument var="document1" formName="frmMetricData" action="editDocument" documentId="# {javascript:FColl.getNoteID();}" >
</xp:dominoDocument>
</xp:this.data>
<xp:tr>
<xp:td id="td1">
<xp:text escape="true" id="computedField3">
<xp:this.value> <![CDATA[#javascript:FColl.getDocument().getItemValueString("BusinessUnit")}]]>
</xp:this.value>
</xp:text>
</xp:td>
<xp:td id="td2">
<xp:link escape="true" id="link1" value="/MetricData.xsp">
<xp:this.text><![CDATA[#{javascript:FColl.getDocument().getItemValueString("MetricName")}]]> </xp:this.text>
<xp:eventHandler event="onclick" submit="true" refreshMode="norefresh" immediate="true">
<xp:this.action>
<xp:openPage name="/MetricData.xsp" target="editDocument" documentId="#{javascript:return FColl.getNoteID();}" />
</xp:this.action></xp:eventHandler>
</xp:link>
</xp:td>
<xp:td id="td3">
<xp:inputText id="EditBox3" value="#{document1.Actual}" tabindex="1">
<xp:this.defaultValue><![CDATA[# {javascript:FColl.getDocument().getItemValueString("Actual")}]]></xp:this.defaultValue>
<xp:this.converter>
<xp:convertNumber type="number" integerOnly="true" />
</xp:this.converter>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="repeat1">
<xp:this.action><![CDATA[#{javascript:// get the universalID of the document
var keyCode = FColl.getDocument().getUniversalID();
// Create an Array
var myArray = sessionScope.get("myList");
//If it's not already in the Array then add it.
if (!myArray.contains(keyCode)) {
myArray.add(keyCode);
}}]]></xp:this.action>
</xp:eventHandler></xp:inputText>
<xp:span>
<xp:image url="/.ibmxspres/domino/oneuiv2/images/iconConfirmation16.png" id="image1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:saveDocument var="document1" />
</xp:this.action>
</xp:eventHandler>
</xp:image>
</xp:span>
If anybody can give me any ideas to try, I would be very grateful.
Make it simple! There is a simple action "save". Comes in save and save all flavors. The later goes below the repeat and saves any changed document.

xpages search modulo inside a popup

With your help, I did create an Xpage with FTsearch & export into Excel features. The problem is the search being made based on multiple input fields ( let say > 10 ) the xpage is heavy texted + considering the fact there is also a view panel where I list the search results once the Search button is clicked.
This is the main reason I've tried to create ( after the link to Search&Export is clicked ) some pop-up dialog ( which contains an xpage, I guess ) and this pop-up dialog to contain all my input fields + the 2 buttons already created: search & export. So, after I press the Search button from my pop-up => the pop-up dialog is closed and the search results are displayed in the view panel, same thing for the Excel button: pop-up is closed and I open the excel file.
Currently, when I click the link to Search&Export I 'see' all the input panel for the search ( all the input fields + the two buttons ) and of course the view panel. It does work but I think a pop-up dialog will be more user-friendly and it will give more space for the xpage.
What I want to do: move all the inputs fields + the search and export to excel buttons into a dialog, which should appear when the link is clicked.
How to create a dialog which opens when a link is clicked and contains this panel below ( where all the input fields and button for the FTsearch are contained there )
My code for the panel which contains the input fields and the search & export button:
<xp:panel style="background-color:rgb(242,242,242);border-color:rgb(168,168,168);border-width:thin;border-style:solid">
<xp:table><xp:tr><xp:td><xp:label value="Din" id="label3" style="font-size:8pt;font-family:Verdana;color:rgb(128,0,0)">
</xp:label></xp:td>
<xp:td><xp:inputText id="inputText1" value="#{sessionScope.searchDate1}">
// some extra code
</xp:label></xp:td>
<xp:td></xp:td>
<xp:td>
<xp:inputText id="inputText2" value="#{sessionScope.searchDate2}">
// some extra code
</xp:inputText></xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Author" id="label1"
style="font-size:8pt;font-family:Verdana;color:rgb(128,0,0)">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText id="searchAutor"
value="#{sessionScope.searchAutor}">
</xp:inputText>
</xp:td>
<xp:td></xp:td>
<xp:td></xp:td>
</xp:tr>
<xp:tr>
<xp:td style="font-family:Verdana;font-size:8pt">
<xp:label id="label2" value="Titlu carte"
style="color:rgb(128,0,0);font-size:8pt;font-family:Verdana">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText id="searchTitlu"
value="#{sessionScope.searchTitlu}">
</xp:inputText>
</xp:td>
<xp:td></xp:td>
<xp:td></xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:button value="Search" id="button6"
styleClass="lotusFormButton">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" immediate="false" save="true"
id="eventHandler1">
</xp:eventHandler>
</xp:button>
</xp:td>
<xp:td>
<xp:text escape="true" id="computedField1"
rendered="false">
<xp:this.value><![CDATA[#{javascript:return "Query = " + sessionScope.queryString}]]></xp:this.value>
</xp:text>
</xp:td>
<xp:td></xp:td>
<xp:td>
<xp:button value="Export" id="button1"
styleClass="lotusFormButton" style="float:right;">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" immediate="false" save="true"
id="eventHandler2">
<xp:this.action>
<xp:openPage
name="/export_hidden.xsp">
</xp:openPage>
</xp:this.action>
</xp:eventHandler>
</xp:button></xp:td>
</xp:tr>
</xp:table></xp:panel>
I appreciate your time.
Here's an example of a dialog where you can add your fields to:
<xe:dialog id="exampleDialog" title="Example dialog">
<xp:div styleClass="lotusDialogContent">
<!-- Add your table here -->
</xp:div>
<div class="lotusDialogFooter">
<!--
add your buttons here
-->
<!-- example cancel link -->
<xp:link id="link1" text="Cancel" styleClass="lotusAction">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[XSP.closeDialog('#{id:exampleDialog}')]]></xp:this.script>
</xp:eventHandler>
</xp:link>
</div>
</xe:dialog>
You open the dialog using server-side JS like this:
getComponent("exampleDialog").show();
Or like this using client-side JS:
XSP.openDialog("#{id:exampleDialog}")
You can also style the content and button bar area entirely using extension library. Your dialog would then look like this:
<xe:dialog id="exampleDialog">
<xe:dialogContent id="dialogContent1">
<!-- content here -->
</xe:dialogContent>
<xe:dialogButtonBar id="dialogButtonBar1">
<!-- buttons here -->
</xe:dialogButtonBar>
</xe:dialog>
Here's an example of a button that you can use inside the dialog to close the dialog and refresh the viewpanel on the same XPage (assuming the viewpanel is called "viewpanel1"):
<xp:button value="Search" id="searchButton">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" immediate="false" save="false" refreshId="viewpanel1">
<xp:this.action><![CDATA[#{javascript:
getComponent('exampleDialog').hide()
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
You can use XSP.addOnLoad() to open the dialog once the page is loaded. Add this to your XPage:
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
XSP.openDialog("#{id:exampleDialog}")
});
]]></xp:this.value>
</xp:scriptBlock>

Resources