xpages: cannot compute view column using getColumnValue() - xpages

In the code below, I am trying to compute the last column using a value that is coming from another column in the view.
I can't figure out why this isn't working, returning the default value all the time:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:viewPanel rows="30" id="viewPanel1" var="varWI">
<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="WorkItem">
<xp:this.categoryFilter><![CDATA[#{javascript:"F832F30FA6C4686E85257F0E0008E964"}]]></xp:this.categoryFilter>
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="wi_Date" id="viewColumn6" displayAs="link" showCheckbox="true">
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
<xp:viewColumnHeader value="Creation Date" id="viewColumnHeader6" style="font-weight:bold">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn id="wi_Intervention1" columnName="wi_Intervention">
<xp:viewColumnHeader id="viewColumnHeader9" style="font-weight:bold" value="Intervention">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn id="wi_Category1" columnName="wi_Category">
<xp:viewColumnHeader id="viewColumnHeader10" style="font-weight:bold" value="Category">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn id="viewColumn1">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header"
id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:this.facets>
<xp:this.value><![CDATA[#{javascript:var s:string = varWI.getColumnValue('wi_Category');
if(s.equals("CATEGORY_DISCOUNT")) {
return "99. Discount"
} else if(s.equals("CATEGORY_INCOMPATIBILITY")) {
return "88. Incompatibility"
} else {
return "--. " + s.toLowerCase();
}}]]></xp:this.value>
</xp:viewColumn>
</xp:viewPanel>
</xp:view>
This part:
var s:string = varWI.getColumnValue('wi_Category');
if(s.equals("CATEGORY_DISCOUNT")) {
return "99. Discount"
} else if(s.equals("CATEGORY_INCOMPATIBILITY")) {
return "88. Incompatibility"
} else {
return "--. " + s.toLowerCase();
}
always return the value in lower case. The column values are text, and the field in the form as well.
Example: if the column value is "CATEGORY_DISCOUNT" what the column displays is "--. category_discount".
It seems it knows the column value, as it puts it in lower case, but it won't see it as equals to the value I check for in the "if" statement.
Quite confused....

Try s=="CATEGORY_DISCOUNT". You're casting it to an SSJS string, not a java.lang.String. .equals() may not work for SSJS strings.

Fellow coders, the problem had nothing to do with the code, but with the values saved in the document.
Turns out the drop down used to enter values has a formula that goes like this:
FrenchValue + " | " + Alias
Of course, on the web, the extra space is actually saved with the alias. So I had an extra space at the beginning of each value I was looking for...
I have been caught by that once or twice, and now my colleague also learned a valuable lesson!!!
Standard code started working like a charm once the extra space was removed from the view column that was used in the drop down of the form that filled the field in the view column.
Final column code was similar to this:
var s:string = viewEntry.getColumnValue('Intervention');
s = s.trim();
var col = sessionScope.lang=="en" ? 3 : 2;
#DbLookup(#DbName(), "VWL022", s, col);

Related

View Column Header cannot sort column when use Filter by category name?

I have a view in the xpage. The view will display relevant information depends on user login. In my previous post, thanks for the useful answer and comments, I was able to do the part.
However, I notice that the view cannot sort when click the column header. In Properties, I go to View Column Header, I see the Sort column has a tick in the check box.
I am not sure why the view column header cannot sort, I guess the Filter by category name effect the sort function. It is because when I remove the code in Filter by category name, I can click the column header to sort. But when I add the add code in Filter by category name, I click the column header, it cannot sort.
So my question is why the view column header cannot sort column when use filter by category name? Is there any method that I can make view column header able to sort when clicked?
I would like to post my code below because I don't know which part I did wrong.
<xp:viewPanel rows="30" id="viewPanel3"
pageName="/BookVenue.xsp" iewStyle="width:700.0px">
<xp:this.facets>
<xp:pager partialRefresh="true"
layout="Previous Group Next" xp:key="footerPager" id="pager1">
</xp:pager>
</xp:this.facets>
<xp:this.data>
<xp:dominoView var="view1"
viewName="UserBookedVenueInfo">
<xp:this.categoryFilter><![CDATA[# {javascript:var uName:NotesName = session.createName(session.getEffectiveUserName());
return uName.getCommon();
}]]></xp:this.categoryFilter>
</xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="Venue"
id="viewColumn7" displayAs="link">
<xp:viewColumnHeader value="Course Name"
id="viewColumnHeader7" sortable="true">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="ReturnDate"
id="viewColumn8" displayAs="link">
<xp:this.converter>
<xp:convertDateTime type="date"
dateStyle="long">
</xp:convertDateTime>
</xp:this.converter>
<xp:viewColumnHeader value="Remarks"
id="viewColumnHeader8" sortable="true">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="Remark"
id="viewColumn9" displayAs="link">
<xp:viewColumnHeader value="Remark"
id="viewColumnHeader9" sortable="true">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
Would someone let me know my mistakes please. Thanks a lot.
I have read the following posts and I try to use the solution in the view but it still cannot sort.
XPages "filter by category name" for View Panel Controll random error
xpages : Filtering a View Data Source using the keys parameter(filter by category name)
You may want to just ditch the View Control and use a repeat and store the data in a Java object. Then you can sort for any of the columns. I covered this in a webinar I did, see https://www.youtube.com/watch?v=Ln-meA0WXaw&feature=youtu.be
The sample database is at http://www.tlcc.com/mwlug
Howard

Xpages viewPanel column looses sorting link after category filter reset

I have a Xpages page with a viewPanel control definied. It it filtered by category and contains some columns. One of them is sortable. Unfortunatelly it looses sorting capabilty in the following scenario:
Open Xpage (filter category: null) - I may click the sort column
Change filter category (filter category: 'something') - The sorting is unavailable (and that's ok thus datasource)
Change filter category back (filter category == null) - The sorting is unavailable, there is no column sorting link (sorting arrows are visible) .
I've tried partial and full refresh but it does not work. What should I do in order to have sorting enabled again?
EDIT
Here is sample code:
<xp:button value="All companies" id="button5">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="vpDocuments">
<xp:this.action><![CDATA[#{javascript:viewScope.cat = null;}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Single Company" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="vpDocuments">
<xp:this.action><![CDATA[#{javascript:viewScope.cat = 'abc';}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:viewPanel id="vpDocuments" var="rowData"
indexVar="rowIdx">
<xp:this.data>
<xp:dominoView var="view1"
databaseName="#{javascript:computeMyDb()}" viewName="xMyView"
categoryFilter="#{javascript:viewScope.cat}"></xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="$Company" id="viewColumn1">
<xp:viewColumnHeader value="Company" id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="Invoice" id="viewColumn2">
<xp:viewColumnHeader value="Invoice" id="viewColumnHeader2">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="OrderDate" id="viewColumn7"
styleClass="dateColumn">
<xp:viewColumnHeader value="Order Date" id="viewColumnHeader7"
sortable="true">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
So the last column is sortable, but after clearing category filter the header in not clickable
Please use the keys property instead of the categoryFilter property to fix your issue.

How to make the xpage can be adjusted automatically according to the size of the screen automatically displays rows?

I have created a xpage to show the domino view, and I have set the "Maximum rows per page:20", but when I review the xpage from my Iphone, I found that the view only half of the creen. So I have set the "Maximum rows per page:30", but when I review the xpage from Ipad, the view only half of the screen again.
So How to make the xpage can be adjusted automatically according to the size of the screen automatically displays rows??
Following is the xpage coding:
<?xml version="1.0" encoding="UTF-8"?><xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoView var="view1" viewName="webvwbyDept" />
</xp:this.data>
<xp:viewPanel value="#{view1}" id="viewPanel1" var="rowData"
viewStyle="width:99.0%" rows="38">
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next"
xp:key="headerPager" id="pager1">
</xp:pager>
<xp:pager partialRefresh="true" layout="Previous Group Next"
xp:key="footerPager" id="pager2">
</xp:pager>
</xp:this.facets>
<xp:viewColumn columnName="$4" id="viewColumn1"
style="text-align:center;width:65.0px">
<xp:this.facets>
<xp:viewColumnHeader value="Location" xp:key="header"
id="viewColumnHeader1" style="width:65.0px;text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="Dept" id="viewColumn2"
style="text-align:center;width:88.0px">
<xp:this.facets>
<xp:viewColumnHeader value="Department" xp:key="header"
id="viewColumnHeader2" style="width:88.0px;text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="signNO" id="viewColumn3"
style="text-align:center;width:30.0px" displayAs="link"
openDocAsReadonly="true">
<xp:this.facets>
<xp:viewColumnHeader value="Document No" xp:key="header"
id="viewColumnHeader3" style="width:30.0px;text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" id="eventHandler1">
<xp:this.action><![CDATA[#{javascript:if (!rowData.isCategory())
var url = "0/"+rowData.getUniversalID()+"?OpenDocument"
facesContext.getExternalContext().redirect(url);}]]>
</xp:this.action>
</xp:eventHandler>
</xp:viewColumn>
<xp:viewColumn columnName="BDT" id="viewColumn4"
style="width:65.0px;text-align:center">
<xp:this.facets>
<xp:viewColumnHeader value="Begin Date" xp:key="header"
id="viewColumnHeader4" style="width:65.0px;text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="EDT" id="viewColumn5"
style="width:65.0px;text-align:center">
<xp:this.facets>
<xp:viewColumnHeader value="End Date" xp:key="header"
id="viewColumnHeader5" style="width:65.0px;text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="$3" id="viewColumn7"
style="text-align:center;width:30.0px">
<xp:this.facets>
<xp:viewColumnHeader value="Reason" xp:key="header"
id="viewColumnHeader7" style="text-align:center;width:30.0px">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="F1" id="viewColumn9">
<xp:this.facets>
<xp:viewColumnHeader value="Project" xp:key="header"
id="viewColumnHeader9" style="text-align:center">
</xp:viewColumnHeader>
</xp:this.facets>
<xp:this.value><![CDATA[#{javascript:var maxLength=10;var columnValue=rowData.getColumnValue("F1");if (typeof columnValue == "java.util.Vector") {
columnValue = columnValue.toArray().join(",");
}return columnValue.length > maxLength?columnValue.substring(0,maxLength)+"...":columnValue;}]]></xp:this.value>
</xp:viewColumn>
</xp:viewPanel>
Here are two XPages snippets that I think will help you.
http://openntf.org/XSnippets.nsf/snippet.xsp?id=react-to-css-media-queries-to-invoke-dynamic-server-side-content-and-logic
http://openntf.org/XSnippets.nsf/snippet.xsp?id=react-to-css-media-queries-using-client-side-javascript
FYI: In case you never used them, a CSS media query allows you to specify certain CSS for each device based on screen size in pixels. You generally need four media queries: phone, tablet, desktop, large desktop, you might only need the first three.
For you, you want to adjust a serverside setting based on a media query which adds an extra layer of complexity. Please check out these snippets, and modify to fit your need. The first one is the one you should focus on. Both are by Tony McGuckin of IBM, who is part of the team that created XPages.
Using this example in the first snippet, I think you will need to have a different view for each device, and show the correct on based on the media query. IMO this will be the best user experience. If this is too much trouble, considering using Bootstrap and you will get responsiveness built in.
There isn't a simple way to do this because the server side cannot tell how large the screen is before the page loads. Here is an example....
To start you have to
check a sessionScope variable and if blank assume a value = 20.
have the page load to determine the size of the screen
figure out how many rows you want to show based on that
set the sessionScope value using JSONRPC
partialrefresh the view with the new number of rows displayed.
The code below shows an example of this but is not perfect. There are too many variables for CSS in the view and the size of your rows, it would have to be adapted for your individual application.
The XPage code
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<script src="jquery-1.11.2.min.js"></script>
<xp:this.data>
<xp:dominoView var="view3" viewName="vwSomeData"></xp:dominoView>
</xp:this.data>
<xe:jsonRpcService id="jsonRpcService1" serviceName="myRPC">
<xe:this.methods>
<xe:remoteMethod name="setRows"
script="sessionScope.put('numRows', rows)">
<xe:this.arguments>
<xe:remoteMethodArg name="rows" type="boolean"></xe:remoteMethodArg>
</xe:this.arguments>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
<xp:panel styleClass="viewWrapper" id="viewWrapper">
<xp:viewPanel value="#{view3}" id="viewPanel1">
<xp:this.facets>
<xp:pager partialRefresh="true"
layout="Previous Group Next" xp:key="headerPager" id="pager1"
rendered="false">
</xp:pager>
</xp:this.facets>
<xp:this.rows><![CDATA[#{javascript:
var temp = sessionScope.get("numRows");
print (temp)
//if no sessionScope value assume 10
return (temp || 10)
}]]>
</xp:this.rows>
<xp:viewColumn columnName="Record_ID" id="viewColumn1">
<xp:this.facets>
<xp:viewColumnHeader value="Record_ i d"
xp:key="header" id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="departdate" id="viewColumn2">
<xp:this.facets>
<xp:viewColumnHeader value="D e p a r t d a t e"
xp:key="header" id="viewColumnHeader2">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
<xp:viewColumn columnName="returndate" id="viewColumn3">
<xp:this.facets>
<xp:viewColumnHeader value="R e t u r n d a t e"
xp:key="header" id="viewColumnHeader3">
</xp:viewColumnHeader>
</xp:this.facets>
</xp:viewColumn>
</xp:viewPanel>
</xp:panel>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(function(){
//This is only rendered if there is no sessionScope variable
var rowFactor = parseInt($(window).height()/32);
console.log(rowFactor)
$.when(myRPC.setRows(rowFactor))
.then(function(){
var temp = $('.viewWrapper').attr("id");
XSP.partialRefreshGet(temp, {})
})
})
]]>
</xp:this.value>
<xp:this.rendered><![CDATA[#{javascript:
var temp1 = !sessionScope.get('numRows');
print (temp1);
return temp1;
}]]></xp:this.rendered>
</xp:scriptBlock>
</xp:view>

open blank page (new page) on clicking calculated page url in a view

I've got following viewPanel. I would like to open a new page when the users clicks on the calculated page url. I just don't seem to figure this out.
<xp:viewPanel rows="30" id="viewPanel9" showColumnHeader="false" var="rowData"viewStyle="width:auto" disableTheme="true">
<xp:this.data>
<xp:dominoView var="view9" databaseName="product/picture.nsf"
viewName="pictures3" keysExactMatch="true"
keys="#{javascript:sessionScope.SelectedProduct;}">
</xp:dominoView>
</xp:this.data>
<xp:this.rendered><![CDATA[#{javascript:getComponent("viewPanel9").getRowCount() > 0}]]>
</xp:this.rendered>
<xp:viewColumn columnName="picDescr" id="viewColumn9" displayAs="link" openDocAsReadonly="true">
<xp:this.iconSrc><![CDATA[#{javascript:thisid = rowData.getColumnValue("unid");
thisdocument = rowData.getColumnValue("picName");
calculatedlink = "servername/product/picture.nsf/O/"+thisid+"/$FILE/"+thisdocument;
return calculatedlink}]]>
</xp:this.iconSrc>
<xp:this.pageUrl><![CDATA[#{javascript:thisid = rowData.getColumnValue("unid");
thisdocument = rowData.getColumnValue("picName");
picturename = thisdocument.replace("th_","");
calculatedlink = "servername/product/picture.nsf/O/"+thisid+"/$FILE/"+picturename;
return calculatedlink}]]></xp:this.pageUrl>
<xp:viewColumnHeader value="Description" id="viewColumnHeader9">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
Some time back I was grappling with same issue. I created a workaround for it which works, but I don't know if it is the best way to go about it.
First set the displayAs attribute of xp:viewColumn to hidden. So it looks something like this:
<xp:viewColumn columnName="picDescr" id="viewColumn9" displayAs="hidden" openDocAsReadonly="true">
Now put a Link control in the column, you would have to do this in Source tab. You can then set the target attribute to _blank for the Link control. So your code would look something like this:
<xp:viewColumn columnName="picDescr" id="viewColumn9" displayAs="hidden" openDocAsReadonly="true">
<xp:link escape="true" target="_blank">
<xp:this.text><![CDATA[#{javascript:rowData.getColumnValue("picDescr");}]]></xp:this.text>
<xp:this.value><![CDATA[#{javascript:thisid = rowData.getColumnValue("unid");
thisdocument = rowData.getColumnValue("picName");
picturename = thisdocument.replace("th_","");
calculatedlink = "servername/product/picture.nsf/O/"+thisid+"/$FILE/"+picturename;
return calculatedlink}]]></xp:this.value>
</xp:link>
...
...
...
</xp:viewColumn>
I think I would use a repeat control instead.
Up near the top establish the linkage to the data as you did:
<xp:this.data>
<xp:dominoView var="contactsView"
viewName="TeamDirectoryNameLU">
</xp:dominoView>
</xp:this.data>
and then, where you want your "view":
<ul>
<xp:repeat id="contactRepeat" rows="30" value="#{contactsView}" var="dataRow" disableOutputTag="true">
<li>
<xp:link escape="true" id="link1">
<xp:this.value><![CDATA[#{javascript:return "m_ContactDetails.xsp?action=OpenDocument&documentId=" + dataRow.getDocument().getUniversalID();}]]></xp:this.value>
<xp:this.text><![CDATA[#{javascript:return dataRow.getColumnValue("Name");}]]></xp:this.text>
</xp:link>
</li>
</xp:repeat>
</ul>
I got the basics of that from TeamStudio in their recent video on mobile apps. It's part of a jQuery-powered contacts list that opens the contact details XPage for the contact you click on.

Filtering categorized View Panel in xPages

I have a view panel with a categorized view as it source. The data I am viewing can have various statuses (Status='Submitted' , Status = 'Approved') etc.
I have a combo box on my page that lets me to select the status to display in the view. That all works great with the exception that the xPages view does the same annoying thing as in the client when displaying a categorized view. And that is, it does not display the categorized columns then a full text index search filter is in place.
Other than creating a view and a corresponding xpage for each status, is there any way to filter by status and still display the categorized field?
I don't think you need 2 views or 2 view panels on XPage.In the view that was categorized by Status, put the below formula for the categorized Status column :
Status : "All"
The above formula will add category 'All', and shows all documents irrespective of status.
If I understand right:
You want to use "single category" to select by "Status" (e.g. "Draft") and still want to show the column with "Draft"?
.... besides that you probably would be better off to just show it at a header above the view, since it saves you a full column, you simply add another column to your view (unsorted) that repeats the field "Status". If you don't want to add a view column, you can create a computed column that uses the status field.
I went with two view panels / views. If "All" is selected then the view that is categorized by client is displayed. Otherwise the view categorized by status then client is displayed. The category filter is then used for that view.
<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="vwRequestsAllByClientsName">
</xp:dominoView>
</xp:this.data>
<xp:this.rendered><![CDATA[#{javascript:var v = getComponent("comboBoxFilterBy").getValue();
return (v=="All" || v==null);
}]]></xp:this.rendered>
<xp:viewColumn columnName="ClientName" id="viewColumn1">
<xp:viewColumnHeader value="ClientName"
id="viewColumnHeader1">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="RequestNum" id="viewColumn2">
<xp:viewColumnHeader value="Request #"
id="viewColumnHeader2">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="APPSNo" id="viewColumn3">
<xp:viewColumnHeader value="APPS Number"
id="viewColumnHeader3">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="LoanType" id="viewColumn4">
<xp:viewColumnHeader value="Loan Type"
id="viewColumnHeader4">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="LoanAmount" id="viewColumn5">
<xp:viewColumnHeader value="Loan Amount"
id="viewColumnHeader5">
</xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="Term" id="viewColumn6">
<xp:viewColumnHeader value="Term" id="viewColumnHeader6">
</xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
<xp:viewPanel rows="30" id="viewPanel2">
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next"
xp:key="headerPager" id="pager2">
</xp:pager>
</xp:this.facets>
<xp:this.data>
<xp:dominoView var="view2"
viewName="vwRequestsAllByStatusClientsName">
<xp:this.categoryFilter><![CDATA[#{javascript:var v = getComponent("comboBoxFilterBy").getValue();
v}]]>

Resources