i have a DataTable on my Xpage. I´ve filled with JavaScript an array with elements from 4 Notes Databases, which i´ve returned to the Table to show it on the DataTable.
This works, but now i need a search (edit box with search button) to search and update the results in the DataTable.
Is this possible? I only found a solution for a datatable, which is directly bind to a view, and nothing for a "manually" filled DataTable.
This is my Datatable code , which includes the JS code to create the array
<xp:dataTable id="dataTable3" rows="990" var="coll2Test"
style="width:70%" indexVar="idx">
<xp:this.facets>
<xp:pager partialRefresh="true"
layout="Previous Group Next"
xp:key="header" id="pager8">
</xp:pager>
</xp:this.facets>
<xp:this.value><![CDATA[#{javascript:
var fa:NotesDatabase = session.getDatabase(#DbName()[0], "???????");
var faSh:NotesDatabase = session.getDatabase(#DbName()[0],"???????");
var faKb:NotesDatabase = session.getDatabase(#DbName()[0],"???????");
var fa20:NotesDatabase = session.getDatabase(#DbName()[0],"???????");
var vFa:NotesView = fa.getView("???????");
var vSh:NotesView = faSh.getView("???????");
var vKb:NotesView = faKb.getView("????????");
var v20:NotesView = fa20.getView("???????");
var doc:NotesDocument = vFa.getFirstDocument();
var docSh:NotesDocument = vSh.getFirstDocument();
var docKb:NotesDocument = vKb.getFirstDocument();
var doc20:NotesDocument = v20.getFirstDocument();
var faArr= new Array();
while(doc!= null) {
var eintrag = new Array();
eintrag.push(doc.getItemValue("Name"));
eintrag.push(doc.getItemValue("Description"));
faArr.push(eintrag)
doc = vFa.getNextDocument(doc);
}
while(docSh!= null) {
var eintrag = new Array();
eintrag.push(docSh.getItemValue("Name"));
eintrag.push(docSh.getItemValue("Description"));
faArr.push(eintrag)
docSh = vSh.getNextDocument(docSh);
}
.....
//another 2 while
...
return faArr;}]]></xp:this.value><xp:table>
<xp:tr>
<xp:td>
<xp:label
value="Suche:" id="label14"
style="font- weight:bold">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
id="inputText7"
value="#
{viewScope.searchView6}">
</xp:inputText>
</xp:td>
<xp:td>
<xp:button value="suchen"
id="button7">
<xp:eventHandler
event="onclick"
submit="true" refreshMode="complete" immediate="false"
save="true" id="eventHandler7">
</xp:eventHandler>
</xp:button>
</xp:td>
</xp:tr>
</xp:table>
<xp:column id="column6">
<xp:this.facets>
<xp:label id="label11"
xp:key="header"
style="color:rgb(0,128,255);font-weight:bold"
value="Name">
</xp:label>
</xp:this.facets>
<xp:text escape="false"
id="computedField5">
<xp:this.value><![CDATA[#
{coll2Test[0]}]]></xp:this.value>
</xp:text>
</xp:column>
<xp:column id="column7">
<xp:this.facets>
<xp:label id="label12"
xp:key="header"
style="color:rgb(0,128,255);font-weight:bold"
value="Description">
</xp:label>
</xp:this.facets>
<xp:text escape="true" id="computedField6">
<xp:this.value><![CDATA[#
{coll2Test[1]}]]></xp:this.value>
</xp:text>
</xp:column>
</xp:dataTable>
Regards
Stefan
Write your completely filled JavaScript array into a view scope variable e.g. viewScope.AllEntries at the beginning. Fill your DataTable with
the complete array if no search string is entered.
the values matching search string if user entered a search string
This way you only need to read the data once from your four views and just filter it later depending on search string.
Move your code to beforePageLoad event. Add at the top
if (viewScope.AllEntries) {
return;
}
and replace the last line return faArr; with
viewScope.AllEntries = faArr;
This way you'll calculate faArr only once and store it in viewScope.AllEntries.
Replace your code in DataTable "value" with:
if (!viewScope.search) {
return viewScope.AllEntries;
}
...create and return an array (walking through viewScope.AllEntries)
...which contains only elements with search string viewScope.search
The search field can be an edit field bound to a viewScope like viewScope.search. Trigger a partial refresh of DataTable when user clicks on search button.
Related
We have an XPage which is using a named JDBC connection via the OpenNTF extension library.
This is successfully retrieving data and placing it inside a View Panel, I've selected to display a Check Box next to first field in the Row, and need to access the returned value for that field in that row (or an array for multiples of the selected rows).
So far have tried these methods:
var Docs2=getComponent("viewPanelDocs");
//var db2 = Docs2.getAttributes();
//var doc2Array=Docs2.getSelectedIds();
//var test = getComponent("something");
var p=Docs2.getParent()
var pp=something.getColumnValue("extName")
var Rows = Docs2.getChildCount().valueOf();
var doc2Array= new Array();
var SelectedDocs2 = new Array();
for(i=0; i < Rows; i++) {
// Works, no output: var Selected2Docs=Docs2.getAttributes();
// FAILS: var Selected2Docs=Docs2_xspGetRendererData();
// WORKS, no output: var Selected2Docs=Docs2._xspGetRendererData();
// WORKS, gets local ID of viewPanel: var Selected2Docs=Docs2.getId();
// Works: javax.faces.component.UIComponentBase$AttributesMap#0: var Selected2Docs=Docs2.getAttributes();
// FAILS, doesn't like string: var Selected2Docs=Docs2.getAttributes("ExternalUNCLink");
// WOrks, no output: var Selected2Docs=Docs2.getAttributes().get("ExternalUNCLink");
// Fails, something, something: var Selected2Docs=Docs2.getAttributes().values("ExternalUNCLink");
var Selected2Docs=Docs2.toString().valueOf();
doc2Array.push(Selected2Docs);
}
getComponent("Docs2").value=Rows + ": " + #Implode(doc2Array, ",");
//viewScope.put("Documents", #Implode(docArray, ","));
Any clues how to access the returned value of ExternalUNCLink?
Caveat: I'm not a Domino developer, so excuse me if some of the terminology is incorrect.
[EDIT]
We have a JDBC driver, which lives in the Packages -> Web Content -> WEB-INF -> jdbc folder with a test name and four criterea in an XML style format, thus:
<jdbc>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<url>jdbc:jtds:sqlserver://malbec/aps_dsql</url>
<user>user</user>
<password>pass</password>
</jdbc>
Then on the page we have an SQL query in the afterPageLoad event:
var TmpSql="select * from TABLE"
viewScope.put("SQLQuery", TmpSql );
getComponent("strSQLQuery").value=TmpSql;
After that, you put the viewScope variable "SQLQuery" into the value field for sqlQuery on a JDBCQuery view, using the connectionName variable of the name of the JDBC driver shown above. It returns the data, but we can't seem to access it.
[/EDIT]
[EDIT2]
(with apologies for the dogs breakfast ...)
<?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.afterPageLoad><![CDATA[#{javascript:var TmpSql="select A.extName,A.extUNC,A.extObjInstID,LEFT(A.extUNC,5) as Category, B.cltMailName From cdblink A inner join cdbClientMaster B on A.extobjinstid=B.objInstID where extobjectid=1 and extobjinstid in (1536,1871,632)"
viewScope.put("strSQLQuery", TmpSql);
getComponent("strSQLQuery").value=TmpSql;
getComponent('viewPanelDocs').getData().refresh();
}]]></xp:this.afterPageLoad>
<xc:testjdbcrowdataaccess></xc:testjdbcrowdataaccess>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
// --var vp=getComponent("viewPanelDocs");
// --
// --//var test=vp._xspGetRendererData().getParent();
// --//var test=vp._xspGetStateId().valueOf();
// --//var test= vp.getChildren().lastIndexOf();
// --var test= vp.getChildren().size();
// --var test=vp.getChildCount();
// --var test=vp._xspGetStateId().valueOf();
// --//var test=vp._xspGetReadOnlyObj().hashCode();
// --//var test=vp.getAttributes().get();
// --var test=vp.getFamily().valueOf();
// --var test=vp.getParent();
// --
// --getComponent("Test").value=test.toString();
//var database=mssql_test.jdbc;
//
//var viewPanel=getComponent("viewPanelDocs");// get the componet of viewPanel
//var docIDArray=viewPanel.getSelectedIds(); //get the array of document ids
//for(i=0; i < docIDArray.length; i++){
// var docId=docIDArray[i];
// var doc=database.getDocumentByID(docId);
// .. your code to deal with the selected document
// getComponent("Test").value=doc.toString();
//}
var test = getComponent("viewPanelDocs").value;
#ErrorMessage("ID: "+test);}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br><xp:table id="DEBUG" style="width:100%">
<xp:tr>
<xp:td>inputText2</xp:td>
<xp:td>
<xp:inputText id="inputText2" value="#{viewScope.searchDOCID}" style="width:100%">
<xp:eventHandler event="onfocus" submit="true" refreshMode="complete" id="eventHandler2">
<xp:this.action>
<![CDATA[#{javascript:
var viewPanel:com.ibm.xsp.component.xp.XspViewPanel = getComponent('viewPanel2');
var dominoView:com.ibm.xsp.model.domino.DominoViewData = viewPanel.getData();
var filterValue = getComponent('inputText2').getValue();
if (filterValue == 'NA') {
filterValue = '';}
viewScope.clear()
dominoView.setKeys(filterValue);}]]>
</xp:this.action>
</xp:eventHandler>
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>inputText3 (displayvar)</xp:td>
<xp:td>
<xp:inputText id="inputText3" value="#{viewScope.documentDOCID}" style="width:100%">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>Test</xp:td>
<xp:td>
<xp:inputText id="Test" style="width:100%" value="#{viewScope.test}">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>inputText1</xp:td>
<xp:td>
<xp:inputText id="inputText1" style="width:100%"></xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>inputText4</xp:td>
<xp:td>
<xp:inputText id="inputText4" style="width:100%"></xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>SQLQuery</xp:td>
<xp:td>
<xp:inputText id="strSQLQuery" style="width:100%" defaultValue="strSQLQuery">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>SQLQueryCat</xp:td>
<xp:td>
<xp:inputText id="strSQLQueryCat" style="width:100%">
</xp:inputText></xp:td>
</xp:tr>
<xp:tr>
<xp:td>Doc1</xp:td>
<xp:td>
<xp:inputText id="Docs" style="width:100%">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:15%">Doc2</xp:td>
<xp:td>
<xp:inputText id="Docs2" style="width:100%"></xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>scopeVariable.Documents</xp:td>
<xp:td>
<xp:inputText id="svDocuments" style="width:100%"></xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>scopeVariable.Recipients</xp:td>
<xp:td>
<xp:inputText id="svRecipients" style="width:100%"></xp:inputText>
</xp:td>
</xp:tr>
</xp:table></xp:view>
[/EDIT2]
When you have a ViewPanel that is linked to a Notes View, the selected documents can be found using the getSelectedIds() method on the viewPanel object. You then can loop through the values to get the documents and their full URLs:
var viewPanel=getComponent("viewPanel1");get the componet of viewPanel
var docIDArray=viewPanel.getSelectedIds(); get the array of document ids
for(i=0; i < docIDArray.length; i++){
var docId=docIDArray[i];
var doc=database.getDocumentByID(docId);
// .. your code to deal with the selected document
}
Might work for your JDBC use case too.
It looks like the answer to my question is a three part one - firstly we use the Domino side of things to get the boxes which are checked, thus:
var Docs2=getComponent("viewPanelDocs");
var APKArray=Docs2.getSelectedIds();
//getComponent("svDocuments").value=#Implode(APKArray,",");
Then we use the OpenNTF "Model" Java code to get an array of the documents inside the SQL selection:
// get the Array from the SQL selection
var namesArray=[];
var PathArray=[];
var locationArray = [];
var FinalNames=[];
var FinalLocations=[];
var Model:com.ibm.xsp.component.xp.XspViewColumn = getComponent("xxxviewColumn3");
var modelData=Model.getDataModel();
var Rows = Model.getChildCount().valueOf();
namesArray.push(Rows);
for(i=0; i < modelData.getRowCount(); i++) {
modelData.setRowIndex(i);
var x=modelData.getRowIndex();
var y=modelData.getRowData().getColumnValue("ExternalName").toString();
var z=modelData.getRowData().getColumnValue("ExternalUNCLink").toString();
namesArray.push(x);
locationArray.push(y);
PathArray.push(z);
}
//getComponent("Docs2").value=namesArray
Then we use the index from the Domino side, to reference the names on the SQL side, and put that into a new array:
// put the selected docs in the selected array
for(i=0; i < APKArray.length; i++) {
var z = APKArray[i].valueOf();
FinalNames.push(PathArray[z].valueOf() + "\\" + locationArray[z].valueOf())
//FinalLocations.push(locationArray[z].valueOf())
}
getComponent("Docs2").value=#Implode(FinalNames,",");
The Path + Names ends up in the Docs2 edit box. It's pretty messy, but works (I hope this doesn't ruin my caveat!!)
I am trying to get selected documents from a view and save as separate documents
Here is the design of the xpage
A combo box on the top, a view with check box (this view is used for selection), a button for save the selection values from the view and the combo box. Also there will another view which will display the saved values.
From this post, I can get the unid of selected documents and save to view scope variable. The add button can save the selected value from the combo box and the view and show the result in another view.
However, if I choose more than one value in the view and click save, it saves all values in one document. So I try to use for loop to loop through the selected values in view and save, it still saves one value only in one document.
<xp:table id="table1a">
<xp:tr>
<xp:td id="table1">
<xp:comboBox id="comboBox1"
dojoType="dijit.form.ComboBox" style="width:250.0px"
value="#{document1.Category}">
<xp:selectItems id="selectItems3">
<xp:this.value><![CDATA[#{javascript:var SetFirstValueBlank = #Text("");
return SetFirstValueBlank;
}]]></xp:this.value>
</xp:selectItems>
<xp:selectItems id="selectItems4">
<xp:this.value><![CDATA[#{javascript:#Unique(#DbColumn(#DbName(), "CategoryListView", 1));}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="table1a">
</xp:eventHandler>
</xp:comboBox>
<xp:text escape="true" id="computedField1">
</xp:text>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:viewPanel rows="10" id="viewPanel1" var="rowData">
<xp:this.data>
<xp:dominoView var="view1"
viewName="hListView">
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="ItemName"
id="viewColumn1" style="background-color:rgb(255,255,255)"
showCheckbox="true">
<xp:viewColumnHeader value="Item Name"
id="viewColumnHeader1" rendered="false">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:this.facets>
<xp:pager partialRefresh="true"
layout="Previous Group Next" xp:key="footerPager" id="pager2">
</xp:pager>
</xp:this.facets>
</xp:viewPanel>
<xp:br></xp:br>
<xp:button value="Add" id="button1"
style="height:35.0px">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var Category = getComponent("comboBox1").getValue();
var viewPanel=getComponent("viewPanel1");
var docIDArray=viewPanel.getSelectedIds();
var unidArray = new Array();
for(i=0; i < docIDArray.length; i++) {
var unid=database.getDocumentByID(docIDArray[i]).getUniversalID();
unidArray.push(unid);
}
viewScope.put("unidArray", #Implode(unidArray, ","));
for(var i=0; i< unidArray.length;i++ )
{
document1.replaceItemValue("ItemName", unidArray[i]);
document1.save();
}
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:viewPanel rows="6" id="viewPanel2">
<xp:this.data>
<xp:dominoView var="view2" viewName="CategoryItemView">
<xp:this.categoryFilter><![CDATA[#{javascript:getComponent("comboBox1").getValue();}]]></xp:this.categoryFilter>
</xp:dominoView>
</xp:this.data>
<xp:this.rendered><![CDATA[#{javascript:var value = getComponent("comboBox1").getValue();
if(value =="" || value == null)
{
return false;
}
else
{
return true;
}}]]></xp:this.rendered><xp:viewColumn id="viewColumn4" columnName="Category" rendered="false">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header" id="viewColumnHeader4" value="Category">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn id="viewColumn3" columnName="$10">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header" id="viewColumnHeader3" value="Category">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="ItemName" id="viewColumn2">
<xp:viewColumnHeader value="Item" id="viewColumnHeader2">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next" xp:key="footerPager" id="pager3">
</xp:pager>
</xp:this.facets></xp:viewPanel><xp:br></xp:br></xp:td>
</xp:tr>
</xp:table>
Would someone let me know how to save multiple values in separate documents please? Thank you.
(edit: some of previous content are removed)
I think I will focus on how to save multiple value as separate documents first because this part is quite important in the program, once I can save as separate documents, there will another function that needs the result to process.
I review the code, I think I will still use for loop but unfortunately, it still saves one document only.
I'm guessing the document1 object is bound to a on the XPage, which is only created when the XPage is opened. To cause your button to create multiple documents, the for loop needs to modified :
var oneOfMany : NotesXspDocument;
for(var i=0; i< unidArray.length;i++ )
{
oneOfMany = database.createDocument();
oneOfMany.replaceItemValue( "Category", document1.getItemValue("Category" ) );
oneOfMany.replaceItemValue("ItemName", unidArray[i]);
oneOfMany.replaceItemValue("form", "MyFormName" );
oneOfMany.save();
}
Because it no longer uses document1, this loop will need to populate the other items you need such as the form, for example MyFormName as in the example.
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.
I have an xpage that contains a repeat control. The repeat generates dynamic editable fields based on values in a view. I would like the repeat to grab the data only once so that subsequent updates to the view are not received by the repeat control.
From what I understand of repeat controls this might not be possible.
Is there anyway I would be able to do this?
For what its worth here is the code sample.
<xp:repeat id="repeat2" rows="100" value="#{view6}" indexVar="rowData" var="dataCol" repeatControls="false">
<xp:tr>
<xp:td style="width:400px">
<xc:dynamicChecklistItem
itemname="#{javascript:rowData+'itemname'}"
savedname="#javascript:rowData+'savedname'}">
</xc:dynamicChecklistItem>
</xp:td>
<xp:td>
<xc:dynamicCompleted
completedField="#{javascript:rowData+'completed'}">
</xc:dynamicCompleted>
</xp:td>
<xp:td>
<xc:dynamicVerified
verifiedField="#{javascript:rowData+'verified'}">
</xc:dynamicVerified>
</xp:td>
<xp:td>
<xc:dynamicComments dsn="document1"
fieldName="#{javascript:rowData+'Comments'}">
</xc:dynamicComments>
</xp:td>
</xp:tr>
</xp:repeat>
You can set dominoView's property dataCache="full". This would save all view entry column values at first request and restore and use them at following requests without going back to view.
For advantages and disadvantages look at page 32 here.
<xp:this.data>
<xp:dominoView
var="view6"
viewName="yourView"
dataCache="full">
</xp:dominoView>
</xp:this.data>
As an alternative, you can save the values you need from view in a viewScope variable and use it in repeat control.
<xp:this.beforePageLoad><![CDATA[#{javascript:
if (viewScope.list == null) {
var view = database.getView("yourView");
var allEntries = view.getAllEntries();
var list = new Array();
var entry = allEntries.getFirstEntry();
for (var i = 0; i < allEntries.getCount(); i++) {
var columnValues = entry.getColumnValues();
var items = [columnValues.get(0).toString(), columnValues.get(1).toString()];
list.push(items);
entry = allEntries.getNextEntry();
}
viewScope.list = list}
}]]>
</xp:this.beforePageLoad>
<xp:repeat
id="repeat1"
rows="100"
value="#{viewScope.list}"
indexVar="index"
var="listElement">
<xp:text
id="computedField1"
value="#{listElement[0]}">
</xp:text>
<xp:br />
</xp:repeat>
(You would have to add recycling of Notes objects to code.)
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