Open document in new tab from xPages viewpanel? - xpages

Is there any way to open the document in a new browser tab when the link in a view panel is clicked?

You have two options. one is the way that Tim explained. And another, you can compute the view column value as link. There you can use the _new or _blank property.
Simply say, View Column can be given as a HTML. There you can compute the page with html href tag.

"target" is one of the properties of the view panel component. If you specify "_blank" (as Ferry suggested) as the value of that property, it should apply it to the link for each row. But bear in mind, you're ultimately at the mercy of the end user's browser settings. One user may get a new tab, another may get an entirely new window, and yet another might get nothing because the link was treated as a popup and blocked.

This is a browser setting only. You only have to put target="_blank" in the link.

After trying this I decided against using it for a number of reasons but want to post the procedure below to implement it.
On the view column Display tab select computed value and enter a formula as follows:
var _row:NotesXspViewEntry = viewEntry;
var _unid = _row.getUniversalID();
return "<a href='0/" + _unid + "?OpenDocument' TARGET='_new'>" + _row.getColumnValue("RequestNum") + "</a>"
On the Display Tab select HTML.

Just adding another option to the mix.
If you set Column Display as 'hidden' you can then put a standard link control in the column. E.g. if the desired column link text was a 'First Name' column, which opened a new tab to the page 'Person.xsp'
<xp:viewColumn columnName="firstName" id="vcFirstNameCol" displayAs="hidden">
<xp:viewColumnHeader value="First Name" id="vchFirstName"></xp:viewColumnHeader>
<xp:link escape="true" text="#{javascript: rowData.getColumnValue('firstName');}" id="link1" value="Person.xsp"
target="_blank">
<xp:this.parameters>
<xp:parameter name="documentId" value="#{javascript:rowData.getUniversalID();}"></xp:parameter>
<xp:parameter name="action" value="openDocument"></xp:parameter>
</xp:this.parameters>
</xp:link>
</xp:viewColumn>

Related

Use edit box value for dynamic view panel parameter

What I am trying to do is have an edit box, a button and a dynamic view panel on an Xpage and a View in the Notes database. Then input a document Id in the edit box which, when the button is clicked will use the edit box value as a parameter for filtering in the dynamic view panel. There seems to be very little on the Internet. I have tried setting the dynamic view panel's "Keys" property to the value
getComponent("inputDocumentID").getValue()
And have the button do a full refresh but this does not work. How can I use the edit box as the dynamic views parameter? The Notes View selection formula is;
SELECT ((Form = "Contract")) & (conContractStatus = "Cancelled") &
(initialstagecomplete = "1")
I usually do this using scoped variables. The idea is to use a mechanism similar to LotusScript's NotesViewEntryCollection.getEntriesByKey("keyFilter", False):
Let's assume you have a Notes view where the first column is sorted by UNID (column formula = #Text(#DocumentUniqueID)).
Inside your xpage you create your view panel as always. The vp's key property is set to listen to a requestScope variable like this:
<xp:viewPanel id="viewPanel1">
<xp:this.data>
<xp:dominoView var="view1" viewName="myView"
keys="#{javascript:requestScope.keyFilter;}">
</xp:dominoView>
</xp:this.data>
...
</xp:viewPanel>
Somewhere else on the Xpage you create an editbox and bind it to your requestScope var like this:
<xp:inputText id="inputText1" value="#{requestScope.keyFilter}">
<xp:eventHandler event="onkeyup" submit="true"
refreshMode="partial" refreshId="viewPanel1">
</xp:eventHandler>
</xp:inputText>
As you see every input is immediately stored in my scope variable, and every keyup event performs a partial refresh on the view panel thus refining the key filter as I type.
Remark:
There's a caveat in case your view panel comes with a pager: if you start filtering while your vp isn't showing page #5 applying a key filter could render an empty view. Reason is that the view still is showing page #5 but there just isn't enough data left to show on 5 pages.
Solution again is quite simple: add a few lines of server side script to your edit box's onkeyup event thus resetting the view to show page #1:
getComponent("viewPanel1").gotoFirstPage();

Can I filter an Xpages search bar

I have been given an XPages project which I did not develop. The project has a OneUILayout that includes a Search Bar "facet". Is it possible to code a filter into the search bar facet so that retrieved records are omitted that have a field with a certain value. I have very little experience with XPages. The search results are output to a OneUI_searchpage.xsp where an edit box displays the search string then a dynamic View Panel shown the retrieved records. I have attached the source code for these two items below. Thank you
<xp:label value="Search String:" id="label1"></xp:label>
<xp:inputText id="inputText1" value="#{param.search}"></xp:inputText>
<xp:panel id="maincontentpanel">
<xe:dynamicViewPanel rows="30" id="dynamicViewPanel1"
width="100%">
<xe:this.data>
<xp:dominoView viewName="ContractsFlatByYear"
var="view">
<xp:this.search><![CDATA[#{javascript:return
param.search;}]]></xp:this.search>
</xp:dominoView>
</xe:this.data>
</xe:dynamicViewPanel>
After some consultation with stwissel below, I amended the application to have a check box on the search results xpage with it checked by default and created an additional view for the same output. One view to show cancelled contracts and one to omit cancelled contracts. The relevant Xpage section now looks like as follows;
<xp:checkBox text="Omit Cancelled Contracts"
id="OmitCancelled" defaultChecked="true" checkedValue="True"
uncheckedValue="False" style="padding-left:5.0em" value="#
{viewScope.viewSel}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="dynamicViewPanel1"></xp:eventHandler>
</xp:checkBox>
<xp:panel id="maincontentpanel">
<xe:dynamicViewPanel rows="30" id="dynamicViewPanel1"
width="100%" partialRefresh="true">
<xe:this.data>
<xp:dominoView var="view">
<xp:this.viewName>
<![CDATA[#{javascript:var cancelledYesNo = viewScope.viewSel
= getComponent("OmitCancelled").getValue();
if(cancelledYesNo == "True"){
viewName = "ContractsFlatByYear"}
else {
viewName = "ContractsFlatByYearandCancelled"}}]]>
</xp:this.viewName>
<xp:this.search><![CDATA[#{javascript:return param.search;}]]
></xp:this.search>
</xp:dominoView>
</xe:this.data>
</xe:dynamicViewPanel>
This appears to work but I have the check box onChange event to apply a partial refresh on the dynamicviewpanel but only refreshes when I click on the dynamicviewpanel itself
The search bar facet only captures what you want to search and sends it to the specified XPages for processing.
You have 2 options:
Alter the facet to send the additional condition to the search page
Alter the search function in the search page (the one the query gets posted to) to filter that (if it is static).
Be aware: filtering in code is not a security feature (in case you were intending that). There's reader and author fields for that.
XPages in its core is JSF with some specialities around Domino. You might want to check out my article series on them.
Update
Based on the code snippet, your can get the desired result quite fast. Edit the view selection formula and add & conContractStatus <> "cancelled". You need to check first if that view is used elsewhere to show canceled contracts too. If that is the case, copy the view (eg add Active behind the name) and make the changes there.
Update 2
Your code doesn't return a value and you don't need to get to the component
<xp:this.viewName>
<![CDATA[#{javascript:return (viewScope.viewSel=="True") ? "ContractsFlatByYear" : "ContractsFlatByYearandCancelled";}]]>
</xp:this.viewName>
Let us know how it goes

Xpages Link Open New Browser Tab

I have found a few similar questions to this in stackoverflow but nothing exactly matches. I am attempting to amend an Xpages project where the search results are shown in a Dynamic View Panel. The first column of the search results is a link that opens the record in the same page. What I want to do is have this link open the record in a seperate page. It is the "Dynamic" part of the view that is confusing I think as there is no "Column Name" or "Column View" to add in a window.open or a target="_blank" that I can see. How would I go about this please?
The relevant section of the XPage only has the following;
<xp:panel id="maincontentpanel">
<xe:dynamicViewPanel rows="30" id="dynamicViewPanel1" width="100%">
<xe:this.data>
<xp:dominoView viewName="(keywordsUser)" var="view">
</xp:dominoView>
</xe:this.data>
</xe:dynamicViewPanel>
</xp:panel>
When viewing the source in HTML the clickable column shows the following;
<tr>
<td class="xspColumnViewStart">
<a id="view:_id1:cc4cconeuilayout:OneUIMainAreaCallback:dynamicViewPanel1:0:_id6:_internalColumnLink"
href="*routetoourrecord*";action=editDocument"
class="xspLinkViewColumn">2014</a>
</td>
Dynamic View Panel has a property "target" in All Properties where you can select "_blank". This should add the attribute target="_blank" to the links in first column. But, unfortunately, this works in Notes client only.
So, there is no property we just can set. Luckily, rendered links have an own class "xspLinkViewColumn" (see your source HTML example). With dojo.query we can get all elements with this class and add the target attribute on client side.
Just add following event code to your XPage:
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
dojo.query(".xspLinkViewColumn").attr("target", "_blank");
]]></xp:this.script>
</xp:eventHandler>
All links will get the attribute target="_blank" this way and documents will be opened in a new browser tab.
Just to let know the code does not to work with the Bootstrap theme.
Instead you can use
dojo.query('[id$="_internalColumnLink"]').attr("target", "_blank");

Set readonly property inside a nested panel

If I have an outer panel in which the readonly property is true, is there any way to created inner panels in which the content can be editable?
The use case is a mobile page with a number of fields plus multiple RoundedRectLists. I would like to add a search control to each RoundedRectList to filter the content of those lists. I do not want the fields to always be editable. I need the search control to be editable so I can enter a search value without toggling the entire form. At the moment I have readonly=false set for the inner panel but the search control only becomes editable when the readonly for the outer panel is also set to false.
I know I can created separate panel that are not nested, but this design pattern of nested panels is quite common and I am sure there is n XPages guru out there that has solved this...
I am not the XPage guru you are searching for but i have a workaround, =)
As far as i know if you set the outer panel to readonly="true" all your inner inputText boxes will output no <inputField> in your html just a <span>. Thats also very anoying if you want to have a field that looks like a input but is just disabled for input. That is achieved if you set the to disabled="true" and showReadonlyAsDisabled="true".
I would recomend setting all readonly="false" and use dojo.query to set the disabled propertie on page load like:
<xp:scriptBlock>
<xp:this.value><![CDATA[dojo.ready(function(){
dojo.query(".input").forEach(function(node, index, array){
node.disabled = true;
}
)
});]]></xp:this.value>
</xp:scriptBlock>
<xp:panel>
<xp:inputText id="inputText1" value="#{viewScope.in1}" styleClass="input"
defaultValue="Txt0" >
</xp:inputText>
<xp:inputText id="inputText2" value="#{viewScope.in2}" styleClass="input"
defaultValue="Txt1">
</xp:inputText>
<xp:inputText id="inputText3" value="#{viewScope.in3}" styleClass="input"
defaultValue="Txt2">
</xp:inputText>
</xp:panel>
Another benefit of this solution you can set them editable on clientSide without any Server calls.
Hope it helps.

XPages: Add a button to a data view custom control

I'm using the Extension Library for creating XPages and I want to use a view, where i can use some inline buttons (buttons in every row of the view) and I also want to use the functionality of the data view where I can expand the content of the current row.
I want to use one of those inline buttons, to expand the content of this row, because before the functionality of this button can be executed, the user has to enter some data in an inputText-field.
So the questions are?
- How can I add inline buttons (using SSJS) to a data view?
- Do you know any other way to solve my problem?
Thanks!
In the Extlib database the expansion with a custom form was done using a link. I would stick to the links -> gives you the most options (client side, server side). Stick to those. If you really need that "buttony" look (which does IMHO not look very much like a web application), use CSS to style the link to look like a button. The OneUI has instructions for that (or steal them from Twitter bootstrap).
The OneUI is worth another look suggesting a different visual clue for expand/collapse.
You should be able to do this within the confines of a dataView by adding a facet for "detail" and using collapsible detail.
For the dataView, set collapsibleDetail="true", add in a panel to the detail facet, then put the elements you want to display when they click to expand in that panel.
<xe:dataView id="dataView1" collapsibleDetail="true" detailsOnClient="true">
<xp:this.facets>
<xp:panel xp:key="detail">
<xp:button id="Mybutton" value="My button"></xp:button>
<xp:label value="This is the label" id="label1" for="Mybutton"></xp:label>
</xp:panel>
</xp:this.facets>
<xe:this.summaryColumn>
<xe:viewSummaryColumn columnName="lastname"></xe:viewSummaryColumn>
</xe:this.summaryColumn>
<xe:this.extraColumns>
<xe:viewExtraColumn columnName="city"></xe:viewExtraColumn>
<xe:viewExtraColumn columnName="state"></xe:viewExtraColumn>
<xe:viewExtraColumn columnName="zip"></xe:viewExtraColumn>
</xe:this.extraColumns>
<xe:this.data>
<xp:dominoView var="view2" viewName="ByName-First"></xp:dominoView>
</xe:this.data>
</xe:dataView>
Now, I'm not positive on how to bind it to the contents of the documents displayed, but I'm sure there's a way. I know how to access the document in a repeat, but not in a dataView, so I would probably do it in a repeat (unless you figure it out and post it to us here!)
Hopefully, that moves you in the right direction.

Resources