Get handle to the documents inside a panel which is within a repeat control from outside the repeat control - xpages

I am working on this functionality where-in I need to provide the user with a list of documents and provide an option for the user to change/add values to a field(s) inside these documents. I was going through this example Xpages - Display filtered Document Collection in a repeat control and did a similar implementation and got it to work. So what I have now is a panel inside a repeat which has its data source set with the form and document id set to return the value in the repeat control variable (which is the document UNID from the document collection), thus I am able to bind fields directly to these documents using the data source defined in the panel. The challenge is that I want to get the handle to these documents to set a particular value in them and also save the values in the fields that I bind to the back-end document. Is there any way I can access the documents from outside the repeat control (let say on the click of a button)? Following is my code for the repeat:
<xp:repeat id="rptApprDocuments" rows="30" var="apprDoc"
indexVar="docIndex" first="0">
<xp:this.value><![CDATA[#{javascript:// Look up the employee details view to get the employee appraisal details from the current database
var curDB:NotesDatabase = session.getCurrentDatabase();
var vwlkApprView:NotesView = curDB.getView("vwlkApprAllFGCompAppr");
var collDocAppr:NotesDocumentCollection = vwlkApprView.getAllDocumentsByKey(sessionScope.key);
var apprDocCount = collDocAppr.getCount();
if(apprDocCount != 0){
var docAppr:NotesDocument;
var docUNIDArray = new Array();
for(i=0;i<apprDocCount;i++){
docAppr = collDocAppr.getNthDocument(i+1);
//print(docAppr.getUniversalID());
docUNIDArray.push(docAppr.getUniversalID());
}
viewScope.put("docUNIDArray",docUNIDArray);
return docUNIDArray;
/*return collDocAppr;
/return sortColByItemName(collDocAppr, "AppraiseeCWLCluster");*/
}
return null;
]]></xp:this.value>
<xp:panel id="pnlRR">
<xp:this.data>
<xp:dominoDocument formName="frmAppraisal" var="appraisalDoc"
action="editDocument" ignoreRequestParams="true">
<xp:this.postSaveDocument><![CDATA[#{javascript:if(requestScope.SubmitRR == true){
appraisalDoc.setValue("ApperRRStatus","1");
appraisalDoc.save();
}}]]></xp:this.postSaveDocument>
<xp:this.documentId><![CDATA[#{javascript://apprDoc.getUniversalID();
return apprDoc;}]]></xp:this.documentId>
</xp:dominoDocument>
</xp:this.data>
<xp:tr>
<xp:td styleClass="tdCls" style="width:2%">
<xp:label id="SrNo">
<xp:this.value><![CDATA[#{javascript:var index = parseInt(docIndex)
index = index + 1;
index.toString();}]]></xp:this.value>
</xp:label>
</xp:td>
<xp:td styleClass="tdCls" style="width:20.0%">
<xp:label id="ApeName">
<xp:this.value><![CDATA[#{javascript://return apprDoc.getItemValueString("AppraiseeName");
return appraisalDoc.getItemValueString("AppraiseeName");}]]></xp:this.value>
</xp:label>
</xp:td>
<xp:td styleClass="tdCls" style="width:8.0%">
<xp:label id="ApeGrade">
<xp:this.value><![CDATA[#{javascript://return apprDoc.getItemValueString("Appraisee_Grade");
return appraisalDoc.getItemValueString("Appraisee_Grade");}]]></xp:this.value>
</xp:label>
</xp:td>
<xp:td styleClass="tdCls" style="width:15.0%">
<xp:div style="text-align:center">
<xp:label id="appeTotImpRate"
style="font-size:10pt;color:rgb(255,0,0);font-weight:bold">
<xp:this.value><![CDATA[#{javascript://return apprDoc.getItemValueDouble("AppeTotImpRate").toFixed(2);
return appraisalDoc.getItemValueDouble("AppeTotImpRate").toFixed(2);}]]></xp:this.value>
</xp:label>
</xp:div>
</xp:td>
<xp:td styleClass="tdCls" style="width:15.0%">
<xp:div style="text-align:center">
<xp:label id="apprTotImpRate"
style="color:rgb(255,0,0);font-size:10pt;font-weight:bold">
<xp:this.value><![CDATA[#{javascript://return apprDoc.getItemValueDouble("ApprTotImpRate").toFixed(2);
return appraisalDoc.getItemValueDouble("ApprTotImpRate").toFixed(2);}]]></xp:this.value>
</xp:label>
</xp:div>
</xp:td>
<xp:td styleClass="tdCls" style="width:15.0%">
<xp:div style="text-align:center">
<xp:label id="revTotImpRate"
style="font-size:10pt;color:rgb(255,0,0);font-weight:bold">
<xp:this.value><![CDATA[#{javascript://return apprDoc.getItemValueDouble("RevTotImpRate").toFixed(2);
return appraisalDoc.getItemValueDouble("RevTotImpRate").toFixed(2);}]]></xp:this.value>
</xp:label>
</xp:div>
</xp:td>
<xp:td styleClass="tdCls" style="width:12.0%">
<xp:div
style="font-size:10pt;color:rgb(255,0,0);font-weight:bold;text-align:center">
<xp:comboBox id="apprGrades" style="width:50.0px"
disableClientSideValidation="true" value="#{appraisalDoc.ApperFinalGrade}"
readonly="true">
<xp:selectItem itemLabel="-" itemValue=""
id="selectItem1">
</xp:selectItem>
<xp:selectItem itemLabel="1" itemValue="1"
id="selectItem2">
</xp:selectItem>
<xp:selectItem itemLabel="2" itemValue="2"
id="selectItem3">
</xp:selectItem>
<xp:selectItem itemLabel="3" itemValue="3"
id="selectItem4">
</xp:selectItem>
<xp:selectItem itemLabel="4" itemValue="4"
id="selectItem5">
</xp:selectItem>
<xp:selectItem itemLabel="5" itemValue="5"
id="selectItem6">
</xp:selectItem>
</xp:comboBox>
</xp:div>
</xp:td>
<xp:td styleClass="tdCls" style="width:12.0%">
<xp:div
style="font-size:10pt;color:rgb(255,0,0);font-weight:bold;text-align:center">
<xp:comboBox id="ApperRelativeRank" style="width:50.0px"
disableClientSideValidation="true" value="#{appraisalDoc.ApperRelativeRank}">
<xp:this.readonly><![CDATA[#{javascript:/*if(compositeData.UserRole == "Appraiser"){
return true;
}
if(parseInt(appraisalDoc.getValue("CurrFGRRStatus")) >= parseInt(compositeData.compStatus)){
return true;
}*/
return false;}]]></xp:this.readonly>
<xp:this.rendered><![CDATA[#{javascript:/*if(compositeData.UserRole == "Appraiser"){
return false;
}*/
return true;}]]></xp:this.rendered>
<xp:selectItem itemLabel="-" itemValue=""
id="selectItem13">
</xp:selectItem>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:// Look up the employee details view to get the employee appraisal details from the current database
var curDB:NotesDatabase = session.getCurrentDatabase();
var vwlkApprView:NotesView = curDB.getView("vwlkCWLApprAllFGCompAppr");
var cwlCluster = appraisalDoc.getItemValueString("AppraiseeCWLCluster");
var collEntAppr:NotesViewEntryCollection = vwlkApprView.getAllEntriesByKey(sessionScope.key + cwlCluster);
var entCount = collEntAppr.getCount()
if(entCount != 0){
var ranks = new Array();
var rankValue, rankLabel;
for(i=0;i<entCount;i++){
rankValue = i + 1;
rankLabel = rankValue + "/" + entCount;
ranks.push(rankLabel + "|" + rankValue);
}
return ranks;
}
return null;}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:div>
</xp:td>
</xp:tr>
</xp:panel>
</xp:repeat>

You can access the data sources of a panel, see http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_datasources#Reset+%2F+clear+a+datasource for example code.
But that solves only half of the problem, you need a handle to each panel inside the repeater.
You can find an XPages API browser on openNTF (I don't know the exact name at the moment). Taking this, you can examine the repeat's control at runtime and check for methods and properties. I bet there is something to get components that are inside the repeater.

Related

Xpages display attachment in dialog box from another document

I am opening a dialog box in an Xpage. In the dialog box I am displaying some fields from 3 other documents, and allowing the user to save some notes. All of this works, except I want to display attachments if there are any. I entered a file download control and for the data source pointed to the target document and did a
tmpDoc.getAttachment("attachments")
to get the attachments. But nothing shows up.
Here is the code from the one row in the table in the dialog box.
The other fields work fine, and I know I am getting the tmpDoc, but how do I display the attachment so the user can view it?
<xp:td>
<xp:fileDownload
rows="30"
id="fileDownload1"
displayLastModified="false">
<xp:this.value><![CDATA[#{javascript:
var prtUNID:String = document.getItemValueString("PCTaskParentID");
var tmpView:NotesView = database.getView("(dbAllPCTasksByTaskID)");
var tmpDoc:NotesDocument = tmpView.getDocumentByKey(prtUNID);
tmpDoc.getAttachment("attachments")
}]]></xp:this.value>
</xp:fileDownload>
</xp:td>
I am having more issues with this. Now it does not really work at all.
Here is what I am trying to accomplish.
I have a form PC Build. It is all the tasks that must be done to build a PC in my company. There is a list of Master Tasks called PC Tasks. When a new PC Build is saved, the PC Tasks get copied to rspPCTask forms attached to the PC Build.
As a user works om building a computer they can open up the PC Build and see the individual tasks. I want them to be able to click on a task and pull up the notes and attachments from the master task, while entering notes for the individual task.
Below is a screen shot. In the second field I am grabbing something with javascript. In the first field I am binding the field to the data source, but it is always blank. I cannot figure out why.
I have put in all my code below. Any assistance would be greatly appreciated!!!
<?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"
dojoForm="true"
dojoParseOnLoad="true"
dojoTheme="true">
<xp:this.data>
<xp:dominoDocument
var="document1"
action="openDocument"
computeWithForm="onsave"
formName="PCBuild">
<xp:this.postNewDocument>
<xp:actionGroup>
<xp:setValue
binding="#{document1.ID}"
value="#{javascript:session.evaluate('#Unique')}" />
<xp:setValue
binding="#{document1.crtDte}"
value="#{javascript:session.evaluate('#Today')}" />
<xp:setValue
binding="#{document1.crtUsr}"
value="#{javascript:session.getCommonUserName()}" />
</xp:actionGroup>
</xp:this.postNewDocument>
</xp:dominoDocument>
</xp:this.data>
<xp:this.resources>
<xp:styleSheet
href="/custom.css" />
<xp:script
src="/xpValidationPCBuild.jss"
clientSide="false" />
<xp:script
src="/xpUtilities.jss"
clientSide="false"></xp:script>
<xp:styleSheet
href="/.ibmxspres/dojoroot/dojox/grid/resources/tundraGrid.css">
</xp:styleSheet>
<xp:styleSheet
href="/.ibmxspres/dojoroot/dojox/grid/resources/tundraEnhancedGrid.css">
</xp:styleSheet>
<xp:dojoModule
name="dojox.grid.EnhancedGrid"></xp:dojoModule>
</xp:this.resources>
<xp:this.beforePageLoad><![CDATA[#{javascript:viewScope.ID = document1.getItemValueString("ID")}]]></xp:this.beforePageLoad>
<xp:this.afterPageLoad><![CDATA[#{javascript:viewScope.put("rows","25")}]]></xp:this.afterPageLoad>
<xp:panel
style="width:900.00px">
<xp:panel>
<xp:text
escape="true"
id="dspDocUNID"
style="display:none">
<xp:this.value><![CDATA[#{javascript:if (#IsNewDoc())
{
return "0"
}
else
{
var doc:NotesDocument = document1.getDocument();
var sUNID = doc.getUniversalID();
return sUNID
}}]]></xp:this.value>
</xp:text>
<xp:scriptBlock
id="scriptBlock1">
<xp:this.value><![CDATA[// Conditionally return an image tag to display an icon in a cell
function displayIcon (value) {
var image = '';
switch (value.toLowerCase()) {
case "open":
image = '<img alt="" src="blueUncheckedCheckBox15.png" />';
break;
case "closed":
image = '<img alt="" src="blueCheckedCheckBox15.png" />';
break;
default:
image = '<img alt="" src="greenChk50.png" />';
break;
}
return image;
}]]></xp:this.value>
</xp:scriptBlock>
</xp:panel>
<xe:widgetContainer
id="widgetContainerHeader">
<xp:panel
style="padding-top:8.0px;padding-bottom:8.0px">
<xp:button
id="button1"
value="Edit"
style="font-weight:bold;font-size:10pt"
rendered="#{javascript:!(document1.isEditable())}">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action>
<xp:changeDocumentMode
mode="edit" />
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button
value="Save"
id="button3"
style="font-weight:bold;font-size:10pt"
rendered="#{javascript:(document1.isEditable())}">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="plContainer">
<xp:this.action>
<xp:actionGroup
condition="#{javascript:validateForm()}">
<xp:saveDocument
var="document1"></xp:saveDocument>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript://Get handle on current doc and see if it is a new doc
var thisDoc:NotesDocument = document1.getDocument();
var tg = thisDoc.getItemValueString("tasksGenerated");
if (tg != "Y") {
//Set flag to Y and save document
thisDoc.replaceItemValue("tasksGenerated","Y")
thisDoc.save(true)
var rspDoc:NotesDocument;
//Loop through all PC Task Docs
var pcTasksView:NotesView = database.getView("(dbAllPCTasks)");
var pcTaskDoc:NotesDocument = pcTasksView.getFirstDocument();
var tmpDoc:NotesDocument;
while (pcTaskDoc != null)
{
//Make new doc and add as response to this doc
rspDoc = database.createDocument();
rspDoc.replaceItemValue("Form","rspPCTask");
rspDoc.replaceItemValue("category",pcTaskDoc.getItemValueString("category"));
rspDoc.replaceItemValue("title",pcTaskDoc.getItemValueString("title"));
rspDoc.replaceItemValue("status","Open");
rspDoc.replaceItemValue("PCBuildParentID",thisDoc.getItemValueString("ID"));
rspDoc.replaceItemValue("PCTaskParentID",pcTaskDoc.getItemValueString("ID"));
rspDoc.replaceItemValue("PCTaskParentUNID",pcTaskDoc.getUniversalID());
rspDoc.replaceItemValue("order",pcTaskDoc.getItemValueInteger("order"));
rspDoc.save();
tmpDoc = pcTasksView.getNextDocument(pcTaskDoc);
pcTaskDoc.recycle();
pcTaskDoc = tmpDoc;
}
}}]]></xp:this.script>
</xp:executeScript>
<xp:openPage
name="$$PreviousPage"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button
id="button2"
style="font-weight:bold;font-size:10pt"
value="Close">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="norefresh">
<xp:this.action>
<xp:openPage
name="$$PreviousPage"
target="openDocument" />
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:text
escape="true"
id="computedField3"
style="font-size:14pt;color:rgb(79,79,79);padding-left:px;padding-bottom:px;margin-bottom:px;padding-right:25.0px">
<xp:this.value><![CDATA[#{javascript:document1.getItemValueString("crtDte")}]]></xp:this.value>
</xp:text>
</xp:panel>
</xe:widgetContainer>
<xp:panel
id="plContainer">
<xp:panel>
<xe:widgetContainer
id="widgetContainerData">
<xe:formTable
id="frLocationMaster"
disableErrorSummary="true"
disableRowError="true">
<xp:this.facets>
</xp:this.facets>
<xe:formRow
id="formRow5"
labelPosition="none"
style="padding-bottom:10.0px">
<xp:table
style="width:99%"
border="0"
cellpadding="0"
role="presentation"
cellspacing="0"
id="table4">
<xp:tr>
<xp:td
style="width:80.0px;min-width:120px">
<xp:text
id="cfTitle"
xp:key="header"
style="font-size:14pt;color:rgb(79,79,79);padding-left:px;padding-bottom:px;margin-bottom:px">
<xp:this.value><![CDATA[#{javascript:"PC Build"}]]></xp:this.value>
</xp:text>
</xp:td>
<xp:td
style="width:250.0px">
</xp:td>
<xp:td
style="text-align:right">
<xp:text
escape="true"
id="computedField1"
style="font-size:14pt;color:rgb(79,79,79);padding-left:25.0px;padding-bottom:px;margin-bottom:px">
<xp:this.value><![CDATA[#{javascript:document1.getItemValueString("crtUsr") + " on "}]]></xp:this.value>
<xp:this.rendered><![CDATA[#{javascript:if (#IsNewDoc() == 1) {
return false
} else {
return true;
}}]]></xp:this.rendered>
</xp:text>
<xp:text
escape="true"
id="computedField2"
style="font-size:14pt;color:rgb(79,79,79);padding-left:px;padding-bottom:px;margin-bottom:px;padding-right:px"
value="#{document1.CrtDte}">
<xp:this.converter>
<xp:convertDateTime
type="both"
timeStyle="short" />
</xp:this.converter>
<xp:this.rendered><![CDATA[#{javascript:if (#IsNewDoc() == 1) {
return false
} else {
return true;
}}]]></xp:this.rendered>
</xp:text>
</xp:td>
</xp:tr>
</xp:table>
</xe:formRow>
<xe:formRow
id="formRow1"
labelPosition="none">
<xp:table
style="width:99%"
border="0"
cellpadding="0"
role="presentation"
cellspacing="0"
id="table3">
<xp:tr>
<xp:td
style="width:10%;min-width:120px;">
<xp:label
id="label4"
for="formRow1"
value="Employee Name" />
</xp:td>
<xp:td
style="width:100px">
<xp:inputText
value="#{document1.employeeName}"
id="employeeName1">
<xp:typeAhead
mode="full"
minChars="1"
valueListSeparator=","
ignoreCase="true"
id="typeAhead1">
<xp:this.valueList><![CDATA[#{javascript:var dbname = new Array(#Subset(#DbName(), 1),"names.nsf");
return #DbColumn(dbname,"($PeopleByName)",1);}]]></xp:this.valueList>
</xp:typeAhead>
</xp:inputText>
</xp:td>
<xp:td
style="width:20px">
<xe:valuePicker
id="valuePicker1"
for="employeeName1"
pickerIcon="/picker.png"
dialogTitle="Choose Employee">
<xe:this.dataProvider>
<xe:simpleValuePicker>
<xe:this.valueList><![CDATA[#{javascript:var db:NotesDatabase = session.getDatabase(database.getServer(),"names.nsf");
var viewHandle:NotesView = db.getView("($PeopleByName)");
return viewHandle.getColumnValues(0)
}]]></xe:this.valueList>
</xe:simpleValuePicker>
</xe:this.dataProvider>
</xe:valuePicker>
</xp:td>
<xp:td>
<xp:message
id="message1"
for="employeeName1" />
</xp:td>
</xp:tr>
</xp:table>
</xe:formRow>
<xe:formRow
id="formRow2"
labelPosition="none">
<xp:table
style="width:99%"
border="0"
cellpadding="0"
role="presentation"
cellspacing="0"
id="table1">
<xp:tr>
<xp:td
style="width:10%;min-width:120px;">
<xp:label
id="label1"
for="formRow1"
value="Computer Name" />
</xp:td>
<xp:td
style="width:100px">
<xp:inputText
value="#{document1.computerName}"
id="computerName1">
</xp:inputText>
</xp:td>
<xp:td
style="width:20px">
</xp:td>
<xp:td>
<xp:message
id="message2"
for="computerName1" />
</xp:td>
</xp:tr>
</xp:table>
</xe:formRow>
<xe:formRow
id="formRow3"
labelPosition="none"
rendered="false">
</xe:formRow>
<xe:formRow
id="formRow4"
labelPosition="none"
rendered="false">
</xe:formRow>
</xe:formTable>
</xe:widgetContainer>
</xp:panel>
</xp:panel>
<xp:panel>
<xe:widgetContainer
id="widgetContainer1">
<xp:panel>
<xp:viewPanel
rows="30"
id="viewPanel1"
var="thisEntry">
<xp:this.facets>
<xp:pager
partialRefresh="true"
layout="Previous Group Next"
xp:key="headerPager"
id="pager1">
</xp:pager>
</xp:this.facets>
<xp:this.data>
<xp:dominoView
var="view1"
viewName="(dbAllRpPCTasks)">
<xp:this.keys><![CDATA[#{javascript:document1.getItemValueString("ID")}]]></xp:this.keys>
</xp:dominoView>
</xp:this.data>
<xp:viewColumn
columnName="title"
id="viewColumn5"
displayAs="link">
<xp:viewColumnHeader
value="Title"
id="viewColumnHeader5">
</xp:viewColumnHeader>
<xp:eventHandler
event="onclick"
submit="false"
refreshMode="partial"
refreshId="panelDig">
<xp:this.action><![CDATA[#{javascript:viewScope.UNID = thisEntry.getDocument().getUniversalID();
viewScope.parUNID = thisEntry.getDocument().getItemValueString("PCTaskParentUNID");
getComponent('dialog1').show()}]]></xp:this.action>
</xp:eventHandler>
</xp:viewColumn>
</xp:viewPanel>
<xp:panel
id="panelDig">
<xp:this.data>
<xp:dominoDocument
var="document2"
formName="PCTask"
action="editDocument"
documentId="#{javascript:viewScope.parUNID}">
</xp:dominoDocument>
<xp:dominoDocument
var="document3"
formName="rspPCTask"
action="editDocument"
documentId="#{javascript:viewScope.parUNID}">
</xp:dominoDocument>
</xp:this.data>
<xe:dialog
id="dialog1"
style="width:700px;height:600px"
refreshOnShow="true">
<xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Master Title"
id="label2" />
</xp:td>
<xp:td>
<xp:text
escape="true"
id="computedField4"
value="#{document2.title}">
</xp:text>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label
value="Master Task Notes"
id="label3" />
</xp:td>
<xp:td>
<xp:text
escape="true"
id="computedField5">
<xp:this.value><![CDATA[#{javascript:var tmpDoc:NotesDocument = database.getDocumentByUNID(viewScope.parUNID)
tmpDoc.getItemValueString("notes")}]]></xp:this.value>
</xp:text>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label
value="Master Attachments"
id="label5" />
</xp:td>
<xp:td></xp:td>
</xp:tr>
<xp:tr>
<xp:td></xp:td>
<xp:td></xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label
id="label7"
value="Notes" />
</xp:td>
<xp:td>
<xp:inputTextarea
id="inputTextarea1"
style="width:98.0%;height:100px"
value="#{document3.notes}">
</xp:inputTextarea>
</xp:td>
</xp:tr>
</xp:table>
</xe:dialog>
</xp:panel>
</xp:panel>
</xe:widgetContainer>
</xp:panel>
</xp:panel>
<xp:eventHandler
event="onClientLoad"
submit="true"
refreshMode="norefresh">
<xp:this.script><![CDATA[try {
dojo.byId("#{id:employeeName1}").focus();
} catch (e) { }]]></xp:this.script>
</xp:eventHandler>
</xp:view>
To show all rich text field's attachments of "another" document in a fileDowndload control:
add a panel around your fileDownload control,
add a dominoDocument data source to the panel
set attribute documentId to "another" document's UNID
set fileDownload's value to document's rich text field
(in your case the rich text field is called "attachments")
<xp:td>
<xp:panel>
<xp:this.data>
<xp:dominoDocument
var="documentPCTaskParent"
action="openDocument">
<xp:this.documentId><![CDATA[#{javascript:
document.getItemValueString("PCTaskParentID")
}]]></xp:this.documentId>
</xp:dominoDocument>
</xp:this.data>
<xp:fileDownload
rows="30"
id="fileDownload1"
displayLastModified="false"
value="#{documentPCTaskParent.attachments}">
</xp:fileDownload>
</xp:panel>
</xp:td>
BTW tmpDoc.getAttachment("attachments") you used doesn't return all attachments of rich text field "attachments" but would look for an attachment with the file name "attachments" somewhere in document.
I would avoid the file download control if possible. What you likely want to do is just build html links or images to the actual files themselves. So it's mostly a matter of figuring out the correct URL to get to it. Typically these are old school "non XPages" URL's... the classic domino stuff.
Everything I know about doing this I learned form this post: http://www.wissel.net/blog/d6plinks/SHWL-86QKNM
Short answer: you can add tmpDoc as a true document data source (using

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>

Save button using SSJS does not open xe:dialog in web xpage but works on mobile xpage

The following save button code works well on mobile xpage:
var checkBox31:com.ibm.xsp.component.xp.XspInputCheckbox = getComponent("checkBox31");
var customerID1:com.ibm.xsp.component.xp.XspInputText = getComponent("customerID1");
var a = checkBox31.getValue();
var b = customerID1.getValue()
if (a == "" || a == null){
if (b == ""){
sessionScope.put("ITDialog","You must enter Customer ID");
var dialog1:com.ibm.xsp.extlib.component.dialog.UIDialog = getComponent("dialog1");
dialog1.show();
}
}
But it does not work on web xpage. I'm using 8.5.3FP6. I used 8.5.3FP1 and 8.5.3FP5 bu had same issue.
Thanks in advance for any help.
Here is sample of code which is not working.
 
 
]]></xp:this.script>
</xp:executeClientScript>
</xp:this.script>
</xp:eventHandler>
</xp:button>
 
</xp:panel>
</xe:dialog>
</xp:panel>
<xp:table>
<xp:tr>
<xp:td style="background-color:rgb(226,226,226)">
<xp:label
value="Company:"
id="company_Label1"
for="company1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.Company}"
id="company1">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="background-color:rgb(226,226,226)">
<xp:label
value="Address:"
id="address_Label1"
for="address1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.Address}"
id="address1">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="background-color:rgb(226,226,226)">
<xp:label
value="Contact person:"
id="contactPerson_Label1"
for="contactPerson1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.ContactPerson}"
id="contactPerson1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xp:view>
A checkbox has a value of either 'false' or 'true' (indicating it is 'deselected' & 'selected'), it shouldn't return a value of "" or null. Therefore, the first if statement is never true, and your dialog will never appear.
I believe what you want is that if the checkbox is unselected, there must be a customer ID entered in the input. If so, I think this is the code you want:
var checkBox31:com.ibm.xsp.component.xp.XspInputCheckbox = getComponent("checkBox31");
var customerID1:com.ibm.xsp.component.xp.XspInputText = getComponent("customerID1");
var a = checkBox31.getValue();
var b = customerID1.getValue();
if (a == "false") {
if (b == "") {
sessionScope.put("ITDialog","You must enter Customer ID");
var dialog1:com.ibm.xsp.extlib.component.dialog.UIDialog = getComponent("dialog1");
dialog1.show();
}
}

How can I set focus to Edit Box inside repeat control?

I would like to set focus + place cursor to an Edit Box (the last one) within a repreat control. The repeat is inside a panel (panelRep). I then have a button outside the panel.
This is the client side code for the button which almost works.. Focus is set (blue border around field), but cursor is not placed in field.
User must still click the field to be able to write input.
Example without focus:
Example with focus:
Client side code for button which sets focus to last Edit Box in which id contains the string inputKode:
try {
var el = dojo.query('div[id*="inputKode"]');
var node = el[el.length-1];
setTimeout(function() { node.focus(); }, 500);
//node.focus();
} catch (e) { }
Code for panelRep:
<xp:panel id="panelRep">
<xp:repeat id="repeat1" rows="12" var="row" indexVar="idx"
value="#{view1}" repeatControls="false">
<xp:panel id="panelLinje">
<xp:this.data>
<xp:dominoDocument formName="frmPBudKodeVerdi"
var="dsdoc" action="editDocument" computeWithForm="both"
documentId="#{javascript:row.getUniversalID();}">
</xp:dominoDocument>
</xp:this.data>
<xp:table style="width:800.0px">
<xp:tr>
<xp:td style="width:100px">
<xp:inputText id="inputKode"
value="#{dsdoc.KodeNr}" style="width:62px">
<xp:this.attrs>
<xp:attr name="tabindex"
value="#{javascript:return idx + '1';}">
</xp:attr>
</xp:this.attrs>
<xp:typeAhead mode="partial"
minChars="1" var="lukey" valueMarkup="true" id="typeAhead1">
<xp:this.valueList><![CDATA[#{javascript://var type = compositeData.type;
return TypeAheadKode2(sessionScope.type,lukey);
}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange"
submit="true" refreshMode="partial" refreshId="panelLinje">
<xp:this.action><![CDATA[#{javascript:onChangeKode();}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
</xp:td>
<xp:td style="width:450px">
<xp:inputText id="inputNavn"
value="#{dsdoc.KodeNavn}" style="width:440px"
readonly="true">
</xp:inputText>
</xp:td>
<xp:td style="width:60px">
<xp:inputText id="inputNorm"
style="width:45px" value="#{dsdoc.NormPrProd}"
rendered="#{javascript:viewScope.visNorm}" readonly="true">
<xp:this.attrs>
<xp:attr name="tabindex"
value="#{javascript:return idx + '2';}">
</xp:attr>
</xp:this.attrs>
<xp:this.converter>
<xp:convertNumber
type="number">
</xp:convertNumber>
</xp:this.converter>
</xp:inputText>
</xp:td>
<xp:td style="width:50px">
<xp:inputText id="inputAntall"
style="width:45px" value="#{dsdoc.NormAntall}"
rendered="#{javascript:viewScope.visNorm}">
<xp:this.converter>
<xp:convertNumber
type="number">
</xp:convertNumber>
</xp:this.converter>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="inputTimer">
<xp:this.action><![CDATA[#{javascript:onChangeAntall()}]]></xp:this.action>
</xp:eventHandler>
<xp:this.attrs>
<xp:attr name="tabindex"
value="#{javascript:return idx + '3';}">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
</xp:td>
<xp:td
style="width:50px;text-align:right">
<xp:inputText id="inputTimer"
value="#{dsdoc.Timer}" style="width:45px;text-align:right">
<xp:this.converter>
<xp:convertNumber
type="number">
</xp:convertNumber>
</xp:this.converter>
<xp:this.attrs>
<xp:attr name="tabindex"
value="#{javascript:return idx + '4';}">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
</xp:td>
<xp:td>
</xp:td>
</xp:tr>
</xp:table>
<xp:eventHandler event="onClientLoad" submit="true"
refreshMode="norefresh">
</xp:eventHandler>
</xp:panel>
</xp:repeat>
</xp:panel>
Update 22.09.2012:
#MarkyRoden - Thanks for pointing me in the right direction.
After refining the dojo.query selector, I ended up with 1 line of code.
var el = dojo.query('div[id*="inputKode"] .dijitInputField > input').at(-1)[0].focus();
Original post:
I found out that the element being set focus on was not an INPUT element.
Element id started with widget_
E.g widget_view:_id1:_id2:_id3:repeat1:8:inputKode if there are 8 rows in the repeat
I then discovered that the nodeType of the element was DIV
By viewing the element.innerHTML, I discovered that it had multiple children.
I tried to use element.querySelector or element.querySelectorAll, but I couldn't get them to work for the element, so I ended up looping through element.childNodes.
Not very pretty, but it does the work for now..
I'm sure it can be done much nicer by adding elements to the dojo.query selector, or by using jquery. Have to look into that later..
Well, here's the code I put in the onClientLoad event for my CC:
var el = dojo.query('div[id*="inputKode"]');
var node = el[el.length-1];
node.focus();
var activeElementId = document.activeElement.id;
var activeElement = dojo.byId( activeElementId );
var kids = activeElement.childNodes;
for(var i=0; i < kids.length; i++)
{
if(kids[i].className == 'dijitReset dijitInputField dijitInputContainer')
{
var elementDiv = kids[i];
var elementDivKids = elementDiv.childNodes;
for(var j=0; j < elementDivKids.length; j++)
{
var elementInput = elementDivKids[j];
elementInput.focus();
}
}
}
regards,
Petter

Hiding based on previous combo box choice in xpages?

I have 3 comboboxes
Combo1
Combo2
Combo3
If Combo1 is blank (no selection) then combo2 is hidden. If Combo2 is blank then Combo3 is hidden.
If Combo1 is changed, it blanks Combo2, if Combo2 is changed it blanks Combo3.
This is because Combo2 choices are determined by Combo1 and Combo3 choices by Combo2. This is all working well.
What is happening if I change Combo1 then Combo2 and Combo3 are being blanked just as expected but Combo3 is not being hidden. If all I do is change Combo1 again, Combo3 is hidden. It is almost like I need 2 update events.
Is there any way around this?
Update
The issue seems to be with comboboxes that have computed selection values. In the sample below, changing the State should cause the ShowRoom scope variable to be "0" Changing Floor sets it to "1". A Computed Field will show the current value of the scope variable. It appears the onChange event of the State combo box is not being triggered. If you change the city selection from computed to static values then it works fine.
Not Working (Computed Selections)<xp:table style="width:100%" id="tblSurvey2">
<xp:tr>
<xp:td style="width:300px">
<xp:label value="*State" style="width:66.0px" styleClass="FieldLabel" id="label1">
</xp:label>
</xp:td>
<xp:td style="width:745.0px">
<xp:comboBox id="comboBoxState2" style="width:173.0px">
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="tblSurvey2">
<xp:this.action><![CDATA[#{javascript:viewScope.put("ShowRoom2","0");}]]></xp:this.action>
</xp:eventHandler>
<xp:selectItem itemLabel="AL"></xp:selectItem>
<xp:selectItem itemLabel="CA"></xp:selectItem>
<xp:selectItem itemLabel="NY"></xp:selectItem>
<xp:selectItem itemLabel="PA"></xp:selectItem>
</xp:comboBox>
State = 
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:getComponent("comboBoxState2").getValue()}]]></xp:this.value>
</xp:text>
   Show Room = 
<xp:text escape="true" id="computedField4">
<xp:this.value><![CDATA[#{javascript:viewScope.get("ShowRoom2");}]]></xp:this.value>
</xp:text>
</xp:td>
</xp:tr>
<xp:tr id="tr1">
<xp:td style="width:300px">
<xp:label value="*City" style="width:66.0px" styleClass="FieldLabel" id="label2">
</xp:label>
</xp:td>
<xp:td style="width:785.0px">
<xp:comboBox id="comboBoxCity2" style="width:175.0px">
<xp:eventHandler event="onclick" submit="true"
refreshMode="norefresh" id="eventHandler1">
</xp:eventHandler>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="tblSurvey2" id="eventHandler2"></xp:eventHandler>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:new Array(getComponent("comboBoxState2").getValue() + " City1", getComponent("comboBoxState2").getValue() + " City2", getComponent("comboBoxState2").getValue() + " City3");}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr id="tr2">
<xp:td style="width:300px">
<xp:label value="*Floor" style="width:66.0px" styleClass="FieldLabel" id="label3">
</xp:label>
</xp:td>
<xp:td style="width:745.0px">
<xp:comboBox id="comboBoxFloor2" style="width:89.0px">
<xp:eventHandler event="onclick" submit="true" refreshMode="norefresh" id="eventHandler5">
</xp:eventHandler>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="tblSurvey2" id="eventHandler7">
<xp:this.action><![CDATA[#{javascript:viewScope.put("ShowRoom2","1");}]]></xp:this.action>
</xp:eventHandler>
<xp:selectItem itemLabel="Floor1"></xp:selectItem>
<xp:selectItem itemLabel="Floor2"></xp:selectItem>
<xp:selectItem itemLabel="Floor3"></xp:selectItem>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr id="tr3">
<xp:this.rendered><![CDATA[#{javascript:viewScope.get("ShowRoom2") == "1";}]]></xp:this.rendered>
<xp:td>
<xp:label value="*Room" style="width:66.0px" styleClass="FieldLabel" id="label6">
</xp:label>
</xp:td>
<xp:td>
<xp:comboBox id="comboBoxRoom2" style="width:89.0px">
<xp:selectItem itemLabel="A"></xp:selectItem>
<xp:selectItem itemLabel="B"></xp:selectItem>
<xp:selectItem itemLabel="C"></xp:selectItem>
</xp:comboBox>
</xp:td>
</xp:tr>
</xp:table>
<xp:br></xp:br>
<xp:br></xp:br>
I presume you are using partial refresh to do this?
So you have
C1 -> C2/C3
C2 -> C3
Since you only can have one partial refresh target you need to wrap C2/C3 into a panel and target that one for C1's partial refresh. Also check how you hide C3. you might want to use a viewScope variable to manage the states and depend your visibility on that one.
Update: You should bind your fields to viewScope variables, not set extra values. Also: a combobox shows when the bound variable value is missing or has no match the first value, but doesn't reflect it. So in a combobox you always need to have a first value that makes sense "-Please select|-" is common or looking up the actual first value. In your case the "please select" makes sense. You also might consider if you really want to hide the fields (that becomes a "mystery meat" navigation) or just update the possible selections (remove the rendered properties from the example below to see how it works).
Here you go:
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:table style="width:100%" id="tblSurvey2">
<xp:tr>
<xp:td style="width:300px">
<xp:label value="*State" style="width:66.0px"
styleClass="FieldLabel" id="label1">
</xp:label>
</xp:td>
<xp:td style="width:745.0px">
<xp:comboBox id="comboBoxState2" style="width:173.0px"
value="#{viewScope.selectedState}">
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="tblSurvey2" id="eventHandler2">
<xp:this.action><![CDATA[#{javascript:viewScope.selectedCity = "-";
viewScope.selectedFloor = "-";
viewScope.selectedRoom = "-";}]]></xp:this.action>
</xp:eventHandler>
<xp:selectItem itemLabel="-Please select-"
itemValue="-" id="selectItem1">
</xp:selectItem>
<xp:selectItem itemLabel="AL" itemValue="AL" id="selectItem2"></xp:selectItem>
<xp:selectItem itemLabel="CA" itemValue="CA" id="selectItem3"></xp:selectItem>
<xp:selectItem itemLabel="NY" itemValue="NY" id="selectItem4"></xp:selectItem>
<xp:selectItem itemLabel="PA" itemValue="PA" id="selectItem5"></xp:selectItem>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr id="tr1" style="background-color:rgb(253,250,227)">
<xp:this.rendered><![CDATA[#{javascript:viewScope.selectedState && (viewScope.selectedState != "-")}]]></xp:this.rendered>
<xp:td style="width:300px">
<xp:label value="*City" styleClass="FieldLabel"
id="label2">
</xp:label>
</xp:td>
<xp:td style="width:785.0px">
<xp:comboBox id="comboBoxCity2"
value="#{viewScope.selectedCity}">
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" id="eventHandler1" refreshId="tblSurvey2">
<xp:this.action><![CDATA[#{javascript:viewScope.selectedFloor = "-";
viewScope.selectedRoom = "-";}]]></xp:this.action>
</xp:eventHandler>
<xp:selectItems id="selectItems1">
<xp:this.value><![CDATA[#{javascript:var hasState = viewScope.selectedState && (viewScope.selectedState != "-");
var result = ["-Please select-|-"];
var cities = viewScope.selectedState + " " + ["City1","City2","City3"];
for (var x in cities) {
result.push(cities[x]);
};
return hasState ? result : "Please select a state first|-";
}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr id="tr2">
<xp:this.rendered><![CDATA[#{javascript:viewScope.selectedCity && (viewScope.selectedCity != "-")}]]></xp:this.rendered>
<xp:td style="width:300px">
<xp:label value="*Floor" style="width:66.0px"
styleClass="FieldLabel" id="label3">
</xp:label>
</xp:td>
<xp:td style="width:745.0px">
<xp:comboBox id="comboBoxFloor2"
value="#{viewScope.selectedFloor}">
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" id="eventHandler5" refreshId="tblSurvey2">
<xp:this.action><![CDATA[#{javascript:viewScope.selectedRoom = "-";}]]></xp:this.action>
</xp:eventHandler>
<xp:selectItems id="selectItems2">
<xp:this.value><![CDATA[#{javascript:var hasCity = viewScope.selectedCity && (viewScope.selectedCity != "-");
var result = ["-Please select-|-"];
var floors = viewScope.selectedCity + " " + ["Floor1","Floor2","Floor3"];
for (var x in floors) {
result.push(floors[x]);
};
return hasCity ? result : "Please select a city first|-";
}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr id="tr3" style="background-color:rgb(253,250,227)">
<xp:this.rendered><![CDATA[#{javascript:viewScope.selectedFloor && (viewScope.selectedFloor != "-")}]]></xp:this.rendered>
<xp:td>
<xp:label value="*Room" style="width:66.0px"
styleClass="FieldLabel" id="label6">
</xp:label>
</xp:td>
<xp:td>
<xp:comboBox id="comboBoxRoom2"
value="#{viewScope.selectedRoom}">
<xp:selectItems id="selectItems3">
<xp:this.value><![CDATA[#{javascript:var hasFloor = viewScope.selectedFloor && (viewScope.selectedFloor != "-");
var result = ["-Please select-|-"];
var rooms = viewScope.selectedFloor + " " + ["Room A","Room B","Room C"];
for (var x in rooms) {
result.push(rooms[x]);
};
return hasFloor ? result : "Please select a floor first|-"; }]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="computedField4" id="eventHandler3">
</xp:eventHandler>
</xp:comboBox>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Current variables</xp:td>
<xp:td>State:
<xp:text escape="true" id="computedField1" value="#{viewScope.selectedState}">
</xp:text>
<xp:br></xp:br>
City:
<xp:text escape="true" id="computedField2" value="#{viewScope.selectedCity}">
</xp:text>
<xp:br></xp:br>
Floor:
<xp:text escape="true" id="computedField3" value="#{viewScope.selectedFloor}">
</xp:text>
<xp:br></xp:br>Room:
<xp:text escape="true" id="computedField4" value="#{viewScope.selectedRoom}">
</xp:text></xp:td></xp:tr></xp:table></xp:view>
You could simplify the code by moving the "please select" into its own value item and use a function rather repeating code, but you get the idea.
you can execute multiple partial updates with some javascript. Take a look at this:
http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_events_and_partial_or_full_refresh

Resources