I have a view with some data, and a column with the creation date of each document.
I want to make a search feature with 3 input fields:
Name, StartDate, EndDate.
The result of the search should be all the documents with the same name and within the 2 dates.
Can anyone help me?
Thanks
Use the search property of DominoView data source. It does a full text search on all documents in view. Create a search string like
[Name]="Meier" AND [_creationDate]>=12-01-2013 AND [_creationDate]<=30-08-2014
Your data source code would look like this:
<xp:this.data>
<xp:dominoView
var="view1"
viewName="YourView">
<xp:this.search><![CDATA[#{javascript:
var search = "";
var formatter = new java.text.SimpleDateFormat("dd-MM-yyyy");
if (viewScope.Name) {
search += ' AND [Name]="' + viewScope.Name + '*"';
}
if (viewScope.StartDate) {
search += ' AND [_creationDate]>=' + formatter.format(viewScope.StartDate);
}
if (viewScope.EndDate) {
search += ' AND [_creationDate]<=' + formatter.format(viewScope.EndDate);
}
return search.substring(5);}]]></xp:this.search>
</xp:dominoView>
</xp:this.data>
This code assumes that there are editable search fields which value is bound to viewScope.Name, viewScope.StartDate and viewScope.EndDate e.g.
<xp:inputText
id="inputText1"
value="#{viewScope.Name}">
</xp:inputText>
<xp:inputText
id="inputText2"
value="#{viewScope.StartDate}">
<xp:this.converter>
<xp:convertDateTime
type="date"
dateStyle="short">
</xp:convertDateTime>
</xp:this.converter>
<xp:dateTimeHelper></xp:dateTimeHelper>
</xp:inputText>
Related
Last month, I created a view that is indexed for full text search and I could perform in Louts client and on the web page.
Until today, I test all the functions in the web application and I notice the full text search is not working.
After I created the view and the search function, I did not "touch" that part for while, so I assume it should work. But in the web application, when I perform the search function, the view does not show any result. Then I search in Lotus client, it displays "0 results found in the view matched your search.".
I start to find out the problem, and I usually create a database backup when a function is completed. Therefore I use the latest backup database and see whether the full text search is working or not.
I feel strange that the search function in the backup database works well in web application and Lotus client.
In the current database, I delete the index and create it again, it cannot search. Even I ask my colleague to restart the server ( because I am not the administrator), the full text search is not working. I ask my colleague if there any log files in the server for diagnose. My colleagues gives me a log file that is on 30/06/2016 start with "xpages_ex_servername_date#time.log", he said it is the newest log file and no log files in July.
I don't have any idea to solve this problem.
And here is the code I used to test to search in Lotus client:
FIELD dateYYYYMM >=201601 & FIELD dateYYYYMM <= 201612
All the code work properly in the backup database but the current database is not working even the whole design from the backup database and paste to the current database, the full text search is not working.
Is there any way that I can fix the problem? Grateful your advice please. Thank you.
Update: I removed some content in the previous version and add new information below for your advice please.
In the xpage, there is a table for use's selection for searching
<xp:table style="width:1100.0px" id="criteriaTable">
<xp:tr><xp:td><xp:label value="ID" id="label2"></xp:label> </xp:td>
<xp:td style="width:200.0px">
<xp:comboBox id="idField" style="width:200.0px" dojoType="dijit.form.ComboBox" value="#{sessionScope.idSearch}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var SetFirstValueBlank = #Text("");
return SetFirstValueBlank;
}]]></xp:this.value>
</xp:selectItems>
<xp:selectItems>
<xp:this.value><![CDATA[# {javascript:#DbColumn(#DbName(),"staffinfo",1);
}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="criteriaTable"></xp:eventHandler></xp:comboBox>
</xp:td>
<xp:td style="width:597.0px">
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:174.0px"><xp:label value="Department" id="label1"></xp:label></xp:td>
<xp:td style="width:200.0px">
<xp:comboBox id="departmentField" style="width:200.0px" dojoType="dijit.form.ComboBox" value="#{sessionScope.departSearch}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var SetFirstValueBlank = #Text("");
return SetFirstValueBlank;
}]]></xp:this.value>
</xp:selectItems>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript://get id
var getValue = getComponent("idField").getValue();
//lookup in staffinfo view
#DbLookup(#DbName(),"staffinfo",getValue,2);
}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox></xp:td>
<xp:td style="width:597.0px"></xp:td>
</xp:tr>
<xp:tr>
<xp:td><xp:label value="Name" id="label3"></xp:label> </xp:td>
<xp:td style="width:200.0px">
<xp:comboBox id="nameField" style="width:200.0px" dojoType="dijit.form.ComboBox" value="#{sessionScope.nameSearch}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var SetFirstValueBlank = #Text("");
return SetFirstValueBlank;}]]></xp:this.value>
</xp:selectItems>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript://get id
var getValue = getComponent("idField").getValue();
//lookup in staffinfo view
#DbLookup(#DbName(),"staffinfo",getValue,3);}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox></xp:td>
<xp:td style="width:597.0px"></xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:149.0px">
<xp:label value="Start Year and Month for search" id="label28">
</xp:label>
<xp:br></xp:br>
<xp:label value="yyyymm" id="label29"></xp:label> </xp:td>
<xp:td style="width:200.0px">
<xp:inputText id="inputText1" value="# {sessionScope.startDateSearch}" style="width:200.0px">
</xp:inputText></xp:td>
<xp:td style="width:597.0px">
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:149.0px">
<xp:label value="End Year and Month for search" id="label31">
</xp:label>
<xp:br></xp:br>
<xp:label value="yyyymm" id="label32"></xp:label> </xp:td><xp:td style="width:200.0px">
<xp:inputText id="inputText2" value="# {sessionScope.endDateSearch}" style="width:200.0px"></xp:inputText></xp:td>
<xp:td style="width:597.0px">
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:149.0px"></xp:td>
<xp:td style="width:200.0px">
</xp:td>
<xp:td style="width:597.0px">
</xp:td>
</xp:tr>
<xp:tr>
<xp:td style="width:149.0px">
<xp:button value="Clear Selection" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="complete" immediate="false"
save="false" id="eventHandler2">
<xp:this.action><![CDATA[# {javascript:sessionScope.divisionSearch = "";
sessionScope.rankSearch = ""
sessionScope.postSearch = "";
sessionScope.officerNameSearch = ""
sessionScope.startDateSearch = "";
sessionScope.endDateSearch = ""
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:br></xp:br></xp:td>
<xp:td style="width:200.0px">
<xp:button value="Execute" id="button2">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
</xp:eventHandler></xp:button>
<xp:br></xp:br>
<xp:br></xp:br><xp:text escape="true" id="computedField2" rendered="false"><xp:this.value><![CDATA[#{javascript://use to check the query in text format
var qstring= "";
if ((sessionScope.idSearch != null && sessionScope.idSearch != "" )||
(sessionScope.departSearch != null && sessionScope.departSearch != "")&&
(sessionScope.nameSearch != null && sessionScope.nameSearch != "")||
(sessionScope.startDateSearch != null && sessionScope.startDateSearch != "")||
(sessionScope.endDateSearch != null && sessionScope.endDateSearch !=""))
{
qstring = "FIELD id contains \"*" + sessionScope.idSearch + "*\"" +
" | FIELD department contains \"*" + sessionScope.departSearch + "*\"" +
" | FIELD name contains \"*" + sessionScope.nameSearch + "*\"" +
" & FIELD dateYYYYMM >=" + sessionScope.startDateSearch +
" & FIELD dateYYYYMM <=" + sessionScope.endDateSearch;
}
return qstring;
}]]></xp:this.value></xp:text></xp:td>
<xp:td style="width:597.0px">
<xp:text escape="true" id="computedField1" value="# {sessionScope.queryString}">
</xp:text>
</xp:td>
</xp:tr>
</xp:table>
And the view is to display the search result.
<xp:viewPanel rows="30" id="viewPanel2" viewStyle="width:600.0px">
<xp:this.data>
<xp:dominoView var="view1" viewName="staffallocation"
expandLevel="4">
<xp:this.search><![CDATA[#{javascript:var qstring= "";
if ((sessionScope.idSearch != null && sessionScope.idSearch != "" )||
(sessionScope.departSearch != null && sessionScope.departSearch != "")&&
(sessionScope.nameSearch != null && sessionScope.nameSearch != "")||
(sessionScope.startDateSearch != null && sessionScope.startDateSearch != "")||
(sessionScope.endDateSearch != null && sessionScope.endDateSearch !=""))
{
qstring = "FIELD id contains \"*" + sessionScope.idSearch + "*\"" +
" | FIELD department contains \"*" + sessionScope.departSearch + "*\"" +
" | FIELD name contains \"*" + sessionScope.nameSearch + "*\"" +
" & FIELD dateYYYYMM >=" + sessionScope.startDateSearch +
" & FIELD dateYYYYMM <=" + sessionScope.endDateSearch;
}
return qstring;}]]></xp:this.search>
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="name" id="viewColumn4">
<xp:viewColumnHeader value="Officer"
id="viewColumnHeader4">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="allocationDate" id="viewColumn5">
<xp:viewColumnHeader value="Allocation Date"
id="viewColumnHeader5">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="department" id="viewColumn6">
<xp:viewColumnHeader value="Allocated Department"
id="viewColumnHeader6">
</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>
Description of the code: combo boxes are used for search staff id or department or staff name. User needs to to type the start date and end date use YYYYMM format. When click the button the view will display the result depends on the criteria. The result will show the officer name, officer allocation date and the allocated deartment.
Use the Notes Client view search options, selecting those fields to build up the search criteria. Do not just copy and paste your search criteria, because that will not give you the information you need. Check each field provides the correct options - id, department and name give "contains"/"does not contain", dateYYYYMM provides "is equal to"/"is less than" etc. (assuming it's supposed to be a number field).
If the same field name is used with different datatypes in a database, or a field's datatype is changed, this can affect full text searching. The search settings are held in the UNK table, which holds a mapping between a specific field name and its datatype. So dateYYYYMM field name has to be consistent across all Forms and all documents in the database. Otherwise, the data type of the first document created is what is stored and used for all full text queries. Restoring the design has no effect - it is the first document created which is the key to what datatype is stored in UNK table.
See http://www.intec.co.uk/full-text-search-musings/ for more information and resolving by updating all documents and using an offline compact.
Two suggestions.
Log the string in qstring so you can pick it up and paste it in the search bar in the Notes client.
I assume that when you execute the search, Notes will complain that it cannot use <= or => on text values. These operators are only defined "for numbers or dates in numeric or date fields only". See "How can I refine a search query using operators?" in the Notes Help database. So you have to build your search string or parameters differently.
I created a simple repeat control, having inside it 2 simple inputTexts. Outside this repeat control, there is an editable inputText3 ( binded to dataSource ). I'm using it to make some calculations inside the repeat control. The calculations are displayed correctly. I have 2 buttons, for newLine and delete/hideLine. For the moment, those 2 fields inside the repeat control are not binded to the datasource.
i have a button which save the doc., and list it inside a viewPanel, having the first column inputText3, clickable. I noticed that if I open the document ( in edit or read mode ) this editable field value is correctly displayed, but the fields inside the repeat control are all null, even if I add some values before using the save method.
I try also to create 2 fields inside the form ( / datasource ) and binding this inputTexts to them, but again the repeat control fields are empty.
<xp:repeat id="repeat1" var="varRepeat" indexVar="index">
<xp:this.value><![CDATA[#{javascript:parseInt(sessionScope.dField)
}]]></xp:this.value>
...
<xp:inputText id="inputText1"></xp:inputText>
<xp:inputText id="inputText2"></xp:inputText>
The editable field outside the repeat:
<xp:inputText id="number" value="#{docrepeat.valtotala}"
defaultValue="100">
</xp:inputText>
.
<xp:this.data>
<xp:dominoDocument var="docrepeat" formName="docrepeat"></xp:dominoDocument>
</xp:this.data>
I'm definitely missing something here, hope to reach to a functional solution.
Should I bind the 2 inputText using the var property of the repeat?
Or how can I achieve this?
repeat control code:
<xp:repeat id="repeat1" var="test" indexVar="index" rows="8">
<xp:this.value><![CDATA[#{javascript:parseInt(sessionScope.DField)
}]]></xp:this.value>
<xp:panel>
<xp:table >
<xp:tr>
<xp:td>
<xp:inputText id="inputText1">
<xp:eventHandler event="onchange"
submit="false">
<xp:this.script><![CDATA[try
{
var idx="view:_id1:inputText3";
var index=document.getElementById(idx).value;
var number="view:_id1:number";
var val=document.getElementById(number).value;
var sum = val;
for(var i=0;i<index;i++) {
var input1="view:_id1:repeat1:"+i+":inputText1"
var nr1=document.getElementById(input1).value;
sum-=nr1;
document.getElementById("view:_id1:repeat1:"+i+":inputText2").value = sum;
}
// calculating some %
document.getElementById("view:_id1:test").value = parseInt((sum*100)/val);
}
catch(e)
{
alert("not working");
}]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
<xp:inputText id="inputText2"></xp:inputText>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xp:repeat>
My little scenario was described here: Xpages how to obtain/create this calculations module
I think your datasource inside the repeat is a view. You need to add a datasource of object data inside the repeat. The way to do this is to create a panel inside the repeat and give that panel a datasource as follows.
<xp:repeat id="repeat1" rows="30" value="#{view1}"
var="rowData">
<xp:panel>
<xp:dominoDocument var="objectData1"
formName="Item"
documentId="#{javascript:return rowData.getNoteID();}"
ignoreRequestParams="true" action="openDocument">
</xp:dominoDocument>
!!!put your stuff in the panel!!!
</xp:panel>
</xp:repeat>
So what is going on is the repeat grabs the datasource which is a view. So it will iterate through all of the entries in the view. But the view datasource does not know what to do with documents. So you create the objectData which will grab the noteID of that specific document and make that available to the repeat as a document(referenced by noteID). Making it available as a document will allow it to save values. You probably won't be able to use the value picker but just type in the field names and it will work.
Not sure I am completely understanding your problem. But you also need to save the datasource. So you could either put a save button in the panel to save that specific document or make the save button save all data sources. I prefer being able to save each document separately as it allows for applications that multiple can edit at the same time.
I've setup a repeater and am reading the value from the multivalue field using GetItemValueArray. This returns the array and If I use a listbox it displays. I want to cross reference some other data with it though so I need to use a repeater. But I'm not sure how to have the repeater use an index that increments for each row. The code below "return rowdata[i]" doesn't recognize i.
<xp:repeat id="repeat1" var="rowdata" rows="30">
<xp:this.value>
<![CDATA[#{javascript:var myArray:Array = myDataSource.getItemValueArray("MyMultiValueFld")}]]>
</xp:this.value>
<xp:label id="lbl">
<xp:this.value><![CDATA[#{javascript:return rowdata[i];}]]></xp:this.value>
</xp:label>
</xp:repeat>
rowdata is not a reference to the myArray value as a whole, but the iterated entry in myArray. In other words... you already have what you need.
<xp:label value="#{rowdata}" />
Maybe you can simplify your code by naming using just the "rowdata" as value for your text item. You then should only change the repeat source to
myDataSource.getItemValue("myValueFld")
as this returns always an array of data. It's just depending on the datatype that this item stores, so you might have to convert in the text control.
Hi there your code has another issue, you do not have any return statement in this line:
<xp:this.value>
<![CDATA[#{javascript:var myArray:Array = myDataSource.getItemValueArray("MyMultiValueFld")}]>
</xp:this.value>
so the code does not return your myArray it only Returns the name of it as a string wich gets repeatet one time. Use this a valueBinding:
value="#{myDataSource.MyMultiValueFld}"
or add a return:
<xp:this.value>
<![CDATA[#{javascript:var myArray:Array = myDataSource.getItemValueArray("MyMultiValueFld");
return myArray;}]>
</xp:this.value>
Then you should be able to use Chris Tooheys Answer:
<xp:label value="#{rowdata}"/>
Use the indexVar property of the repeat control to setup a var containing the index.
Got it. The final piece of code is that I did have to create an indexVar="I" in my repeat1 tag but then I also had to change my label to a computed field. The final piece of code looks like:
<xp:table>
<xp:repeat id="repeat1" var="rowdata" rows="30" indexVar="i" first="0">
<xp:this.value><![CDATA[#{javascript:myDataSource.getItemValueArray("myMultivalueFld");}]]>
</xp:this.value>
<xp:tr><xp:td>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:var repeat1:com.ibm.xsp.component.xp.XspDataIterator = getComponent("repeat1");
repeat1.getValue()[i];}]]></xp:this.value>
</xp:text>
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table>
don't think I could have gotten it without the tidbit on the indexVar. Thanks
You can trim that code further. If all you need is the values, you don't need the indexvar and you don't need to reference the repeat as an XspDataIterator. Just use the rowdata as a variable.
<xp:table>
<xp:repeat id="repeat1" var="rowdata" rows="30">
<xp:this.value><![CDATA[#{javascript:myDataSource.getItemValueArray("myMultivalueFld");}]]>
</xp:this.value>
<xp:tr><xp:td>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:rowdata;}]]></xp:this.value>
</xp:text>
</xp:td>
</xp:tr>
</xp:repeat>
Each value in the multi-value field is a "row" as referenced by rowdata. Similarly, if the data source were a view, each row would reference a document object. Don't dispose of the framework available to you by accessing the repeat as a component from inside the component itself.
I have a repeat control inside another repeat control. The concept is to create something like a calendar. So i want to create a 2 dimension repeat and i used one repeat to create "rows" vertically and inside it another one to create columns horizontally. The second repeat control has an input text control inside a div control. The code is below:
<xp:repeat id="repeat4" rows="30">
<xp:this.value>
<![CDATA[#{javascript:var projects2 = new Array("Project 1","Project 2");
return projects2;}]]>
</xp:this.value>
<xp:repeat id="repeat3" rows="31">
<xp:this.value><![CDATA[#{javascript:var inBoxes = new java.util.Vector();
for(i=1;i<=5;i++){
inBoxes.add(i);
}
return inBoxes;}]]>
</xp:this.value>
<xp:div id="DivInputs" styleClass="DivInputs">
<xp:inputText id="inputText1"
style="width:100%">
</xp:inputText>
</xp:div>
</xp:repeat>
</xp:repeat>
I want now to get the value of an input field so if i use this it works:
repeat4.setRowIndex(0);
repeat3.setRowIndex(0);
sum = sum + inputText1.getValueAsString();
But when i do this loop it only gets only the first row cell value:
for(i=0;i<2;i++){
repeat4.setRowIndex(i);
repeat3.setRowIndex(0);
sum = sum + inputText1.getValueAsString();
}
Any ideas?
You need to change your approach. Going after values should be done using bindings, not getValue. So do something like
var x = [[0,0,0,0,0,0,0],[...],....];
viewScope.calendar = x;
Then bind the controls to the variable. This removes the need to check for the exact position or variable name.
I am trying to use an xpages datatable and set the cell colour of the cells in a column to be different based on the cell value. What I am finding is that although the datatable is bound to a view and the collection is specified (to get the row value) this seems to not be available to the style section.
Here is an example:
<xp:dataTable id="dataTable8" rows="30" var="doc1">
<xp:this.value><![CDATA[#{javascript:var View:NotesView = DivisionsView;
View.getAllEntriesByKey("ViewName")}]]></xp:this.value>
<xp:column id="column1" style="width:75px;font-family:Tahoma">
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:doc1.getColumnValues()[1]
}]]></xp:this.value>
<xp:this.style><![CDATA[#{javascript:v=doc1.getColumnValues()[1];
if(v=="Yes"){"background-color:rgb(255,0,0)"}}]]></xp:this.style>
</xp:text>
<xp:this.facets>
<xp:label value="Header" id="label1" xp:key="header">
</xp:label>
</xp:this.facets>
</xp:column>
</xp:dataTable>
This just shows a doc1 not found error. Does this mean the data bound to the datatable is not available to the style part of it? Is there a way to do this?
Any suggestions would be appreciated!
Edit: I cannot change the table cell style based on the view entries value, here is an exmaple that throws the doc1 not found error:
<xp:column id="column1">
<xp:this.style><![CDATA[#{javascript:v=doc1.getColumnValues()[1];
if(v=="Yes"){"background-color:rgb(255,0,0)"}}]]></xp:this.style>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:doc1.getColumnValues()[1]
}]]></xp:this.value>
</xp:text>
<xp:this.facets>
<xp:label value="Header" id="label1" xp:key="header">
</xp:label>
</xp:this.facets>
</xp:column>
The stylesheet property is rendered not only for every value in the column, it is calulated for each row. This incudes the facet too.
This means if your column has a header and/or a footer, the stylesheet property is calculated for these invisible rows, but there is no row value (doc1).
If you change your code and add a try/catch you can see the result.
<xp:column id="column1">
<xp:this.style>
<![CDATA[#{javascript:
try{
v=doc.getColumnValues()[1];
if(v=="Yes"){"background-color:rgb(255,0,0)"}
}catch(e){
return "background-color:rgb(255,0,255)";
}}]]>
</xp:this.style>
...
...
</xp:column>
There are a few things I would like you to check in your code.
First the code to bind data:
var View:NotesView = DivisionsView;
View.getAllEntriesByKey("ViewName")
What is DivisionsView? The actual code to bind would look something like this:
var View:NotesView = database.getView("ViewName");
View.getAllEntriesByKey("KeyName")
Second, in your code to add style you have used single = rather than == in if condition. So the code would be something like this:
v = doc1.getColumnValues()[1];
if (v=="Yes") {
"background-color:rgb(255,0,0)"
}
Do these suggestions make it work?
I have given up on a datatable and got things to work using a repeat on a table row. That way I can control the style of the entire row and therefore each cell, it appears you cannot do this in a datatable as the options are all data column based. Thanks for your help though