I tried a simple date validation, but this "does nothing": I can enter any date I like.
<xp:inputText
value="#{Auftrag.MF_GebDatum_1}" id="MF_GebDatum_11"
style="width:255px">
<xp:this.converter>
<xp:convertDateTime
type="date">
</xp:convertDateTime>
</xp:this.converter>
<xp:this.validators>
<xp:validateDateTimeRange
minimum="1900-01-01T00:00:00"
message="Please enter a correct date of birth"
maximum="2100-01-01T00:00:00">
</xp:validateDateTimeRange>
</xp:this.validators></xp:inputText>
it runs on a german linux server, so I enter dates like 01.01.1811
Thanks for any help, Uwe
This example is from the Mastering XPages book. Please try this and see if that helps you:
<xp:inputText id="inputText3">
<xp:this.validators>
<xp:validateDateTimeRange message="Earliest date is 1 Jan 2011"
minimum="#{javascript:new Date(2011,0,1,0,0,0,0)}">
</xp:validateDateTimeRange>
</xp:this.validators>
<xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
Related
I have some code, see below. It's a dialog box that contains a list box for the user to select one or more choices and a text field to enter an email address.
When I put a viewScope variable as the value to capture the email address the field becomes like it's read only. If I remove the value=viewScope..... the field shows as editable with a border etc.
How can I get the field to be editable and store the value in a scope variable for use when the click the submit button?
FYI, the list box works just fine.
<?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">
<xp:panel id="panelJenarkCurrentYearReportsMain">
<xp:panel id="panelJenarkCurrentYearReportsInner">
<xe:dialog id="dialogCurrentReports" title="Fetch Current Year Reports">
<xp:div styleClass="lotusMessage lotusInfo" role="alert">
<xp:listBox id="listBoxJenarkCurrentYearReports" value="#{viewScope.jenarkCurrentYearReports}"
multiple="true" style="height:150.0px;width:98%;margin-left:5px"
required="true">
<xp:selectItems id="selectItems1">
<xp:this.value><![CDATA[#{javascript:var db = new Array( #DbName()[0], "dbWorkflow\\reference" );
result = #DbLookup(db, "($VSYSCTLKW)", "*ALL*ALL*ALLJenarkCurrentYearReports", "KWValues" );
if (result && typeof result == "string")
result = new Array(result);
return result;
}]]></xp:this.value>
</xp:selectItems>
<xp:this.validators>
<xp:validateRequired
message="Please Select one or more Current Year Reports!" />
</xp:this.validators>
</xp:listBox>
<xp:panel>
<xp:label value="Send Reports To:"
id="labelJenarkReportsEmailTo"
style="width:20%;padding-left:3.0px;margin-left:3.0px">
</xp:label>
</xp:panel>
<xp:panel>
<xp:inputText id="inputTextJenarkReportsEMailTo"
style="width:75%;padding-left:3.0px;margin-left:5.0px"
value="#{javascript:viewScope.jenarkReportEMail;}" required="true">
<xp:this.validators>
<xp:validateRequired
message="Please Enter a valid email Address!">
</xp:validateRequired>
</xp:this.validators>
</xp:inputText>
</xp:panel>
</xp:div>
</xe:dialog>
</xp:panel>
</xp:panel>
</xp:view>
Change your value definition to
value="#{viewScope.jenarkReportEMail}"
It has to be in Expression Language (EL). This way inputText control not just knows how to read viewScope variable's current value but also where to write user's input value to.
If you start your expression with "#{javascript:..." then it will execute the JavaScript code and insert the current value of viewScope.jenarkReportEMail as inputText's value. Just as a string, not as a variable where you can write to. That's why inputText can't write and shows itself as "read only".
I have an app I am build which will allow the users to enter the approvers for each document manually. I wanted to put this in a repeat control instead of hard coding all the fields in the xpage. All is working as I want, except the names are stored in the document in the Canonical format. I don't want to present this to the user, I want to just show the Abbreviated name. I can't seem to get it working. Below is my repeat. I want to put and #name around the value of ApproverName_#
Thanks in Advance
Walt
<xp:repeat
id="repeat4"
var="rowItem"
indexVar="indexVar">
<xp:this.value><![CDATA[#{javascript:["1", "2", "3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18"]}]]></xp:this.value>
<xp:panel>
<xp:repeat
id="repeat3"
var="fieldName">
<xp:label id="label31"><xp:this.value><![CDATA[#{javascript:"Approver - " + rowItem}]]></xp:this.value></xp:label><xp:label id="label33" value="Name"></xp:label>
<xp:this.value><![CDATA[#{javascript:["ApproverName_"+rowItem]}]]></xp:this.value>
<xp:inputText id="nameinputText"
value="#{document1[fieldName]}"
style="width:333.0px" rendered="#{javascript:!document1.isEditable()}">
</xp:inputText>
<xp:inputText id="inputText9" value="#{document1[fieldName]}" style="width:333.0px">
</xp:inputText>
<xe:namePicker id="namePicker1"
for="nameinputText">
<xe:this.dataProvider>
<xe:dominoNABNamePicker
nameList="peopleByLastName"
addressBookSel="db-name" groups="false"
people="true">
<xe:this.addressBookDb><![CDATA[#{javascript:#Subset(#DbName(), 1) + "!!names.nsf"}]]></xe:this.addressBookDb>
</xe:dominoNABNamePicker>
</xe:this.dataProvider>
</xe:namePicker></xp:repeat>
<xp:repeat id="repeat5" var="fieldName">
<xp:this.value><![CDATA[#{javascript:["Title_"+rowItem]}]]></xp:this.value>
<xp:label id="label32" value="Title"></xp:label>
<xp:inputText id="inputText10"
value="#{document1[fieldName]}">
</xp:inputText>
</xp:repeat>
<xp:repeat
id="repeat6"
var="fieldName">
<xp:this.value><![CDATA[#{javascript:["ApprovalFlag_"+rowItem]}]]></xp:this.value>
<xp:inputText id="inputText11" value="#{document1[fieldName]}">
</xp:inputText>
</xp:repeat>
<xp:repeat
id="repeat7"
var="fieldName">
<xp:this.value><![CDATA[#{javascript:["Reason"+rowItem]}]]></xp:this.value>
<xp:inputText id="inputText12" value="#{document1[fieldName]}">
</xp:inputText>
</xp:repeat>
</xp:panel>
</xp:repeat>
Use the Dojo Name Text Box instead of Input Field. It prevents typing, gives a better UX for removing entries, and does what you want out-of-the-box.
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 would like display photos in a window on several rows and 3 columns.
image1 image2 image3
image4 image5 image6
image7 image8 image9
image10 image11 image12
Actually I find to put photo1, 2 and 3 and the others are behind photo3 but not visible...
image1 image2 image3 [image4 image5 image6 image7 ....]
This is my code :
<xp:table>
<xp:tr>
<xp:repeat id="picturesRpt" value="#{dsvListePhoto}"
indexVar="i" var="picture" rows="3" >
<xp:panel>
<xp:this.data>
<xp:dominoDocument var="pictureDoc"
action="openDocument"
documentId="#{javascript:picture.getUniversalID()}"
ignoreRequestParams="true">
</xp:dominoDocument>
</xp:this.data>
<xp:div>
<xp:td>
<xp:div styleClass="listePhotos">
<xp:div>
<xp:image id="image1">
<xp:this.url><![CDATA[#{javascript: "http://monserveur/devpt/Xpages/xphoto/PhotoWeb.nsf/" + compositeData.vueUtilisee + "/" + pictureDoc.getDocument().getUniversalID() + "/$File/TIMBRE_image.jpg?OpenElement"}]]></xp:this.url>
</xp:image>
<xp:text
value="#{pictureDoc.Titre}" />
<xp:br></xp:br>
</xp:div>
<xp:div>
<xp:text
value="#{pictureDoc.IdNiveau1} / #{pictureDoc.IdNiveau2}" />
</xp:div>
</xp:div>
</xp:panel>
</xp:repeat>
</xp:tr>
</xp:table>
An idea ?
Thanks for your help !
As you decided to create a table with three columns finish and start a table row every three pictures. Add </tr><tr> to rendered HTML whenever a new table row shall start. That is the case when indexVar i is 3, 6, 9, and so on.
Add the </tr><tr> tags with a computed field of content type HTML and use the rendered condition
(i > 0) && (i%3 == 0)
Your code would look like this:
<xp:table>
<xp:tr>
<xp:repeat
id="picturesRpt"
value="#{dsvListePhoto}"
indexVar="i"
var="picture"
rows="1000">
<xp:text escape="false">
<xp:this.rendered><![CDATA[#{javascript:
(i > 0) && (i%3 == 0) }]]></xp:this.rendered>
<xp:this.value><![CDATA[#{javascript:
"</tr><tr>" }]]></xp:this.value>
</xp:text>
<xp:td>
... picture ...
</xp:td>
</xp:repeat>
</xp:tr>
</xp:table>
Use #Modulo or some other maths tool to work out the remainder of a division by 3. That will allow you to compute whether to add Computed Text that adds a "" or a "" tag.
I did a similar demo with two columns in the Repeats on Steroids page of my IBM Connect 2013 session with Mike McGarel. The link for the slides and demo database is on my blog, at the bottom of the article, below the youtube video http://www.intec.co.uk/session-slides-and-sample-database-from-ibm-connect/
It was also delivered as a TLCC webinar, though I can't find the link. From Niklas Heidloff's blog it looks like a video was taken http://heidloff.net/home.nsf/dx/16.04.2013093214NHEAUQ.htm
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.