XPages ViewPanel setStartKeys with date value does not work - xpages

i got a simple code sniped to jump to a specific entry in a viewPanel control
var c:com.ibm.xsp.component.xp.XspViewPanel = getComponent("viewPanel1");
var ds:com.ibm.xsp.model.domino.DominoViewData = c.getDataSource();
ds.setStartKeys(MYVALUETOSEARCH);
c.gotoRow(c.getRowIndex());
This works perferct when the sorted column is a string but it did not work when the column is a date.
It seems it is not allowed to pass MYVALUETOSEARCH as NotesDateTime
Any Ideas to solve the problem?
EDIT:
I use Domino 9.0.1 FP7
Here is the complete sample
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:inputText
id="filter">
<xp:dateTimeHelper
id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime
type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<xp:button
value="Label"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="viewPanel1">
<xp:this.action><![CDATA[#{javascript:var c:com.ibm.xsp.component.xp.XspViewPanel = getComponent("viewPanel1");
var ds:com.ibm.xsp.model.domino.DominoViewData = c.getDataSource();
var filter = getComponent("filter").getValue();
var dt:NotesDateTime = session.createDateTime(filter);
ds.setStartKeys(dt);
ds.refresh();}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:viewPanel
rows="30"
id="viewPanel1"
viewStyle="width:100%">
<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="test">
</xp:dominoView>
</xp:this.data>
<xp:viewColumn
columnName="date"
id="viewColumn1">
<xp:this.converter>
<xp:convertDateTime
type="date"></xp:convertDateTime>
</xp:this.converter>
<xp:viewColumnHeader
value="date"
id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
The view "test" just contains 1 sorted column that contains a date value

Providing NotesDateTime start key for the ViewPanel would work fine if you make sure the key is of NotesDateTime type. Using component value as a key without converter may give you String instead of expected NotesDateTime value.
The following code works in my 9.0.1 environment:
var c:com.ibm.xsp.component.xp.XspViewPanel = getComponent("viewPanel1");
var ds:com.ibm.xsp.model.domino.DominoViewData = c.getDataSource();
var filter = viewScope.get("date");
var dt:NotesDateTime = session.createDateTime(filter);
ds.setStartKeys(dt);
ds.refresh();

Related

Get selected documents from a view and save as separate document

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.

MultipleField Value in repeat Control with Pager

what i want to do is If a field has more than 20 values How can i list values in a repeat control with pager component and editBox or computedField.
Only 20 records should be listed for per page. a Pager should help me to show all values page by page..
this field is listed in a dialogBox. here is the my Code below. If someoen did it and it is possible to share it. Appreciate that..
<xe:dialog id="dialogHistory" title="Tarihçe">
<xp:panel>
<xp:pager id="pager1" for="repeat1">
<xp:pagerControl type="First" id="pagerControl1"></xp:pagerControl>
<xp:pagerControl type="Previous" id="pagerControl2"></xp:pagerControl>
<xp:pagerControl type="Group" id="pagerControl3"></xp:pagerControl>
<xp:pagerControl type="Next" id="pagerControl4"></xp:pagerControl>
<xp:pagerControl type="Last" id="pagerControl5"></xp:pagerControl>
</xp:pager>
<xp:repeat id="repeat1" rows="1" first="1" var="col" indexVar="index">
<xp:this.value><![CDATA[#{javascript:var cVal = document1.getValue("history"); return cVal;}]]></xp:this.value>
<xp:inputText id="inputText1" multipleSeparator="#{javascript:#NewLine();}">
<xp:this.value><![CDATA[#{javascript:var cVal = document1.getValue("history");
return cVal;}]]>
</xp:this.value>
</xp:inputText>
</xp:repeat>
</xp:panel>
</xe:dialog>
The trouble is that you're referring back to the document, not the values of the field in the inputText.
<xp:repeat id="repeat1" rows="20" var="col" indexVar="index">
<xp:this.value><![CDATA[#{javascript:var cVal = document1.getValue("history"); return cVal;}]]></xp:this.value>
<xp:inputText id="inputText1" value="#{col}">
</xp:inputText>
</xp:repeat>
However, I think this will only display them in inputText. I don't think that it binds them to the field, so I don't think it would allow you to change the values.
Exactly according to the code,It is difficult to Point the issue but the same xpage code,If it would help you in any case.
Code:
<?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="testing">
</xp:dominoDocument>
</xp:this.data>
<xp:br></xp:br>
<xp:repeat id="dateRepeatControl" rows="5" var="r" indexVar="i"
first="0">
<xp:this.value><![CDATA[#{javascript:var v:java.util.Vector = new java.util.Vector();
v.add('Date1');v.add('Date2');v.add('Date3');v.add('Date4');v.add('Date5');v.add('Date6');
v.add('Date7');v.add('Date8');v.add('Date9');v.add('Date10');v.add('Date11');v.add('Date12');
;v.add('Date13');v.add('Date14');
return v;}]]></xp:this.value>
<xp:br></xp:br>
<xp:div id="checkDiv">
<xp:text escape="true" id="computedField1"
value="#{javascript:r}">
</xp:text>
</xp:div>
<xp:br></xp:br>
</xp:repeat>
<xp:pager partialRefresh="true" id="pager1"
for="dateRepeatControl">
<xp:pagerControl id="pagerControl1" type="First"></xp:pagerControl>
<xp:pagerControl id="pagerControl2" type="Previous"></xp:pagerControl>
<xp:pagerControl id="pagerControl3" type="Next"></xp:pagerControl>
<xp:pagerControl id="pagerControl4" type="Last"></xp:pagerControl>
<xp:pagerControl id="pagerControl5" type="Separator"></xp:pagerControl>
</xp:pager>
</xp:view>
This is an xpage having a repeat control with 5 values of a vector to be repeated at one page and pages helps it to go next.You can use this xpage to get the working repeat control with the pager.

xpages full text searching

I've been following Dave's Notesin9 video on full text searching.
My source code is:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
defaultLinkTarget="_blank">
<xp:br></xp:br>
<xp:inputText id="inputText1" value="#{requestScope.variant}"></xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:text escape="true" id="computedField1" value="#{javascript:requestScope.variant}"></xp:text>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button id="button3" value="Search"><xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="false" save="true"></xp:eventHandler></xp:button>
<xp:br></xp:br>
<xp:viewPanel id="viewPanel1" pageName="/p_form.xsp" rows="20">
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next"
xp:key="headerPager" id="pager1" style="width:40.0px">
</xp:pager>
<xp:viewTitle xp:key="viewTitle" id="viewTitle1"
value="List of documents"
style="width:153.0px;background-color:rgb(64,128,128);color:rgb(255,255,0)">
</xp:viewTitle>
</xp:this.facets>
<xp:this.data>
<xp:dominoView var="view1" viewName="vijay"
search="#{javascript:requestScope.variant}">
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="name" id="viewColumn1"
showCheckbox="true" displayAs="link">
<xp:viewColumnHeader value="name" id="viewColumnHeader1"
style="background-color:rgb(192,192,192)">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="age" id="viewColumn2">
<xp:viewColumnHeader value="age" id="viewColumnHeader2"
style="background-color:rgb(192,192,192)">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="email" id="viewColumn3">
<xp:viewColumnHeader value="email" id="viewColumnHeader3"
style="background-color:rgb(192,192,192)">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn id="viewColumn4" style="width:89.0px"
displayAs="link" columnName="$6">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header"
id="viewColumnHeader4" value="Attch">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
</xp:viewPanel>
<xp:button value="New Topic" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:openPage target="newDocument" name="/p_form.xsp"></xp:openPage>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Delete selected" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:deleteSelectedDocuments view="viewPanel1"
message="Are you sure to delete it('em)?">
</xp:deleteSelectedDocuments>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
here, included a textfield to input the search term,
computed field to view the queried term,
a button labelled search as a submit button.
Entered value in the textfield and
when i press the search button, i get error 500.
Where lies the mistake?
Pls help.
Naveen's almost certainly spot on, that the database is not full text indexed. Check the \data\IBM_TECHNICAL_SUPPORT folder on the server, for the latest modified file starting xpages_exc_###. This will give the full detailed error, including the stack trace. The XPages Log Reader project on OpenNTF can be used to view those files from a browser.
I'd recommend using sessionScope instead of requestScope for the search value. If you use requestScope, it's only available during that partial refresh. So when the user uses a pager or opens a document and goes back to the view, the requestScope variable is null again, so the search criteria are lost.

xPage with multiple datasources has the second datasource always opened in edit mode

I have an xPage with 2 datasources. I open the page and the first datasource is readonly, while the second datasource is in edit mode. Adding ignoreRequestParms=true seems to cause this behavior, but its the only way that the document will save to a different datasource.
I have found this link that someone has found similar behavior.
http://www-10.lotus.com/ldd/nd85forum.nsf/7756aedc25e6d81285256324005ac76c/5e2f855ea18ff802852576e3007c34f2?OpenDocument
There is something going on that I don't understand. If someone could explain this to me I would appreciate it.
Here is the code for the data source and the fields in the tab panel
<xp:dominoDocument var="document2" action="createDocument"
formName="software" ignoreRequestParams="true">
</xp:dominoDocument>
<xp:tabbedPanel id="tabbedPanel1">
<xp:tabPanel id="tabPanel1" label="Checklist Items">
<xp:checkBoxGroup id="checkBoxGroup1" layout="pageDirection"
value="#{document1.checklist}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var dbName = new Array("","");
var Rep = #Unique(#DbColumn(dbName,"checklistitems",3));
Rep}]]></xp:this.value>
</xp:selectItems>
</xp:checkBoxGroup>
</xp:tabPanel>
<xp:tabPanel label="Software" id="tabPanel2">
<xp:button value="Edit Software list" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="panelsoft">
<xp:this.action>
<xp:changeDocumentMode mode="edit"
var="document2">
</xp:changeDocumentMode>
</xp:this.action></xp:eventHandler></xp:button>
<xp:button value="Save Software list" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panelsoft">
<xp:this.action>
<xp:actionGroup>
<xp:modifyField name="uid"
value="#{javascript:document1.getDocument().getUniversalID()}"
var="document2">
</xp:modifyField>
<xp:executeScript script="#{javascript:document2.save()}">
</xp:executeScript></xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br>
<xp:panel id="panelsoft"><xp:table rendered="#{javascript:document2.isEditable()}"><xp:tr><xp:td><xp:br></xp:br>
Software Name
</xp:td>
<xp:td>
<xp:inputText id="inputText1"
style="width:300px" value="#{document2.Softwarename}">
</xp:inputText></xp:td>
</xp:tr>
<xp:tr>
<xp:td></xp:td>
<xp:td></xp:td>
</xp:tr>
</xp:table>
<xp:viewPanel rows="30" id="viewPanel1">
<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="view2" viewName="CustomSoftware"
categoryFilter="#{javascript:document1.getDocument().getUniversalID()}">
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="uid" id="viewColumn1">
<xp:viewColumnHeader value="uid"
id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="Softwarename"
id="viewColumn2">
<xp:viewColumnHeader value="Software Name"
id="viewColumnHeader2">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="comments" id="viewColumn3">
<xp:viewColumnHeader value="Comments"
id="viewColumnHeader3">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
</xp:panel>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:panel>
</xp:panel>
<xp:br></xp:br>
</xp:tabPanel>
</xp:tabbedPanel>
Because action is set to createDocument (which you could omit, since that's the default value), this causes a new document to be created in memory. This is why the document is in edit mode: you're composing a new record. If you don't want to create a new document, then change the action attribute to one of the other options: openDocument or editDocument. Either of these require that the documentId attribute be set as well, because the data source needs to know which document you wish to, respectively, open or edit.
If you omit the ignoreRequestParams attribute, then this data source doesn't ignore the URL request parameters. Instead, it looks for parameters named databaseName, formName, documentId, and action. If any of these parameters are included in the URL, the value of each overrides what is defined on the data source. This is why if you open an instance of document1, but don't set ignoreRequestParams on document2, then both documents will have the same mode (read/edit): because neither data source is ignoring the URL, so both data sources are doing what the URL is telling them to.
Generally, when defining multiple data sources on the same XPage, you'll have one that can be considered the "primary" data source; any other data has some relationship to that data, but the primary data is the user's context for viewing all the data on that page. So you want that data source to respect URL parameters to allow navigation (from a Data View, View Panel, Repeat, etc.) to be able to indicate which document is being opened, and in what mode. But all data sources related to that document should explicitly specify what data they're bound to, and the action being taken on that data, and use ignoreRequestParams to ensure that the URL doesn't override this information.

Show only Unread document current View?

anyone have a suggest to realize #Command([ViewShowOnlyUnread]) in XPages ViewPanel?
And is possibile realize the function "Next Unread" and "Previus Unread"?
Instead of binding the view panel to a standard view data source, try setting its value attribute to the following expression:
importPackage(com.ibm.xsp.model.domino);
var targetView = database.getView("Some View");
var unreadEntries = targetView.getAllUnreadEntries();
var unreadModel = new DominoViewEntryCollectionDataModel(unreadEntries);
return unreadModel;
The view panel should then behave exactly as it would if it were bound to a true data source, but only display the unread entries.
Excellent answer from Tim..
Here's other version with Repeat Controls -
<xp:repeat id="repeatUnreadEntries" var="viewEntry" indexVar="index" rows="30">
<xp:this.value><![CDATA[#{javascript: return database.getView('viewName').getAllUnreadEntries()}]]></xp:this.value>
<xp:this.facets>
<xp:panel id="repeatHeader" xp:key="header">
<xp:text disableTheme="true" escape="false">
<xp:this.value>
<![CDATA[<TABLE><THEAD><TH>Cell1</TH><TH>Cell2</TH></THEAD><TBODY>]]>
</xp:this.value>
</xp:text>
</xp:panel>
<xp:panel id="repeatFooter" xp:key="footer">
<xp:text disableTheme="true" escape="false">
<xp:this.value><![CDATA[</TBODY></TABLE>]]></xp:this.value>
</xp:text>
</xp:panel>
</xp:this.facets>
<TR>
<xp:repeat var="entryColVal" indexVar="colIndex" value="#{javascript:viewEntry.getColumnValues()}">
<TD>
<xp:text value="#{entryColVal}" />
</TD>
</xp:repeat>
</TR>
</xp:repeat>
The code provided by Tim Works if you set data and value attributes to view panel, like below.
<xp:viewPanel rows="30" id="viewPanel1">
<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="vwSrc"></xp:dominoView>
</xp:this.data>
<xp:this.value><![CDATA[#{javascript:importPackage(com.ibm.xsp.model.domino);
var targetView = database.getView("vwSrc");
var unreadEntries = targetView.getAllUnreadEntries();
var unreadModel = new DominoViewEntryCollectionDataModel(unreadEntries);
return unreadModel();}]]></xp:this.value>
<xp:viewColumn columnName="col1" id="viewColumn1">
<xp:viewColumnHeader value="Column1" id="viewColumnHeader1"></xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>

Resources