Xpages: Searching for documents I have no access to - security

I'm pretty sure this isn't possible but I'm going to ask anyway.
I am building a system which handles patient records. A new user needs to be able to search for a patient and once found request access to their files from the Admin.
How do I show a list of all documents even if the user has no access to them? They only appear in the view once they've been added to the Readers field, which defeats the purpose of the search.
My plan is to create 2 documents - the original patient document and a stripped-down document containing name, address used only for searching
Is there a better way of doing this, or is the 2 document approach the way to go?

Use sessionAsSigner to get database object on rights of database signer and run search on it. This will give You collection of documents that can be visualized similarly to view with use of data table.
Example (for moderate views works great - for bigger ones probably some optymalization would be necessary):
<xp:panel id="viewPanel" styleClass="usersPanel">
<xp:this.dataContexts>
<xp:dataContext var="usersList">
<xp:this.value><![CDATA[#{javascript:
var uview = sessionAsSigner.getCurrentDatabase().getView("someView");
uview.FTSearch("Some query");
return uview.getAllEntries();
}]]></xp:this.value>
</xp:dataContext>
</xp:this.dataContexts>
<xp:pager partialRefresh="true" layout="Previous Group Next"
xp:key="headerPager" id="pager2" for="usersList">
</xp:pager>
<xp:dataTable id="usersList" rows="30"
var="entry" value="#{usersList}">
<xp:column id="column1">
<xp:this.facets>
<xp:span xp:key="header"
styleClass="frameworkViewColumnHeader">
Użytkownik
</xp:span>
</xp:this.facets>
<xp:text escape="true" id="computedField1"
value="#{javascript:entry.getColumnValues().get(0)}">
</xp:text>
</xp:column>
<xp:column id="column2">
<xp:this.facets>
<xp:span xp:key="header"
styleClass="frameworkViewColumnHeader">
Instytucja
</xp:span>
</xp:this.facets>
<xp:text escape="true" id="computedField2"
value="#{javascript:entry.getColumnValues().get(1)}">
</xp:text>
</xp:column>
</xp:dataTable>
</xp:panel>

Related

Notes/Domino : Submit button is not shown in the customized search form

I found steps to customize Notes Web search form but the submission button in the search form is not shown. In the below question, questioner also says the same thing. He seemed it was solved but did not write the cause.
http://www-10.lotus.com/ldd/nd6forum.nsf/0/cad751696e7486ef852571d300478a5c?OpenDocument
Perhaps I have a mistake something but I'm not idea how to solve this. Please advise me!
Old-style web forms are often very difficult to handle in Domino. Luckily there's something much better, really: XPages. If you have a fairly recent server, R9.0.x or better, try to make a simple XPage:
Create a new XPage
Add a Edit Box from the Core Controls (don't worry about the layout)
In the Properties, set the Data to Advanced/Use Scoped Variable, viewScope, and type a name, e.g. ftquery
Add a View from the list of Container controls
Select an existing view from the current database
In the View/Data Properties, set Search in view results to Computed, EL and viewScope.ftquery
Attach the Pager to the viewPanel...
Here's a sample, you can paste it in the Source tab of the new XPages and modify it to your liking.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:label value="FT Query" id="label1" for="inputText1"></xp:label>
<xp:inputText id="inputText1" value="#{viewScope.ftquery}">
</xp:inputText>
<xp:viewPanel rows="30" id="viewPanel1">
<xp:this.facets>
<xp:pager partialRefresh="true" layout="Previous Group Next" xp:key="headerPager" id="pager1" for="viewPanel1"></xp:pager>
</xp:this.facets>
<xp:this.data>
<xp:dominoView var="view1" viewName="Put-here-your-view" search="#{viewScope.ftquery}"></xp:dominoView>
</xp:this.data>
<xp:viewColumn columnName="$2" id="viewColumn1">
<xp:viewColumnHeader value="$2" id="viewColumnHeader1"></xp:viewColumnHeader>
</xp:viewColumn>
<xp:viewColumn columnName="Tournament" id="viewColumn2">
<xp:viewColumnHeader value="Name" id="viewColumnHeader2"></xp:viewColumnHeader>
</xp:viewColumn>
</xp:viewPanel>
</xp:view>
Don't forget to enable Full-Text search on your database!
The XPage can be opened from a browser using http;//yoursite/database.nsf/your-xpage.xsp

Accessing value of Editable field in repeat control

How can I access the value of an computed field in a repeat control?
In the example below, I have cfT5Budget in a repeat control. I want to be able to access the value of each of the cfT5Budget control (repeat1:0:cfT5Budget, repeat1:1:cfT5Budget, etc..)
I want to be able to have that same value replicated into my second repeat control. I will be doing other stuff in the second control but for this example, it's just a simple code.
<xp:table>
<xp:repeat id="repeat1" var="rowItem1" indexVar="indexVar1">
<xp:this.value><![CDATA[#{javascript:['a', 'b', 'c']}]]></xp:this.value>
<xp:tr>
<xp:td>
<xp:text escape="true" id="cfT5Budget" value="#{javascript:5 + indexVar1}">
</xp:text>
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table>
<xp:table>
<xp:repeat id="repeat2" var="rowItem2" indexVar="indexVar2">
<xp:this.value><![CDATA[#{javascript:getComponent('repeat1').getValue()}]]></xp:this.value>
<xp:tr>
<xp:td>
<xp:text escape="true" id="cfT5Budget2" value="#{javascript:VALUE OF cfT5Budget GOES HERE}">
</xp:text>
</xp:td>
</xp:tr>
</xp:repeat>
</xp:table>
Thank you in advance :)
The short answer: use data binding.
The long answer:
In MVC your code should not interact with the View (a.k.a the fields), but rather the model (a.k.a the data). So instead of computing the values like in your example, you bind them using the variable name provided in the repeat.
You interact with that collection (Array) not the fields. This makes code easier and more robust since the code doesn’t need to care what UI element is used.
Hope that helps

REST services and Xpages Server side validation

I am new to extension library REST services and xpages, I need to find out a way where I can validate user input data with servers data, to avoid server round trip, I am planning to use REST services.
I tried using something below but no luck, can any one please correct me where the below code is failing.
<?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:this.data>
<xp:dominoDocument var="document1" formName="NavConfig"></xp:dominoDocument>
</xp:this.data>
<xe:restService id="restService1">
<xe:this.service>
<xe:documentJsonService compact="true"
formName="NavConfig">
<xe:this.querySaveDocument><![CDATA[#{javascript:var cmp=getComponent('menuItem1').getValue();
if (cmp=""){
getComponent('msg').setValue("Validation Failed")
}}]]></xe:this.querySaveDocument>
</xe:documentJsonService>
</xe:this.service>
</xe:restService>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:text escape="true" id="msg"></xp:text>
<xp:panel style="margin-left:20.0px;margin-top:20.0px">
<xp:table>
<xp:tr>
<xp:td>
<xp:label value="Menu item:" id="menuItem_Label1"
for="menuItem1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText value="#{document1.MenuItem}"
id="menuItem1">
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Link address:"
id="linkAddress_Label1" for="linkAddress1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText value="#{document1.linkAddress}"
id="linkAddress1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table></xp:panel>
<xp:panel style="margin-top:20.0px;margin-left:20.0px">
<xp:button value="Save" id="button2"><xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:save></xp:save>
</xp:this.action></xp:eventHandler></xp:button></xp:panel>
</xp:view>
REST by nature is a "dumb" API. I would rather say: elegant in its simplicity. You GET data from a server and you PUT/POST it back or DELETE it. So every time you talk to REST, you have a server round trip - that is REST how it is build.
In XPages when your client (JavaScript) is requesting data via REST, that service doesn't interact with any of the components on the page, so checking a menu or setting a component's text has no impact on the REST call.
When you want to do client side validation you need to implement that in client side script otherwise you do have a server round trip (which might not be that bad actually).
I would, to be most flexible, use a custom REST service (also provided by the rest control) to create your own JSON that contains only
the items you actually need but adds info for your local validation code like {'requiredFields' : [{'name' : 'subject', 'message' : 'hey sorry, I need a subject to process this'}, {...}]} and a status reply when you POST data back.
Check the sample database and the book.

Xpage Custom Control / Repeaters Data Save Issue

This is a continuation of a previous question that I asked last week.
I have an XPage. On this XPage I have a repeater. In this repeater, I have a custom control that I am using to display the contents of its own datasource - a NotesXspDocument. This control is repeated 5 to 10 times, maybe up to 15 times. I do not want to make the user press on save for each and every repeated control, so I am using the submit button feature as described in the above linked question.
When the user presses the submit button, I am using the querySaveDocument and the postSaveDocument actions on the events tab (I also tried the properties with the same name in the Data tab with the same result). My issue is the following:
The validation is executed one control instance after another until the validation fails immediately saving the datasource before moving on to the next instance. When a NEW document is saved, it seems like the XspDocument is gone and the fields are emptied. I have checked, and I have set the datasource scope to view, as this behavior somehow resembles requestScope. As soon as I reload the page, the information is correctly presented.
I could use "context.reloadPage()" to just get the updated information, but this has the nasty side effect of removing all unsaved information (for example if validation failed on the xth line). How might I best go about solving/troubleshooting this issue? What should I be paying attention to? Has anyone else seen such a behavior?
I would love to call a validate function on all rows from the Containing XPage and then if all rows succeeded, then call the saveDataSources function. Any help is greatly appreciated!
A simple button outside your repeat control will do. I created this example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:repeat id="repeat1" rows="30" value="#{javascript:4}">
<xp:panel id="dataPanel" disableOutputTag="true">
<xp:this.data>
<xp:dominoDocument var="document1" formName="Demo2">
</xp:dominoDocument>
</xp:this.data>
<xp:table>
<xp:tr>
<xp:td>
<xp:label value="Subject!" id="subject_Label1" for="subject1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText value="#{document1.Subject}"
id="subject1" required="true">
<xp:this.validators>
<xp:validateRequired
message="Say something">
</xp:validateRequired>
<xp:validateLength minimum="5"
message="Say 5 characters or more">
</xp:validateLength>
</xp:this.validators>
</xp:inputText>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label value="Color!" id="color_Label1" for="color1">
</xp:label>
</xp:td>
<xp:td>
<xp:comboBox value="#{document1.Color}"
id="color1" defaultValue="red">
<xp:this.validators>
<xp:validateExpression
message="We don't like red">
<xp:this.expression><![CDATA[#{javascript:value != "red"}]]></xp:this.expression>
</xp:validateExpression>
</xp:this.validators>
<xp:selectItem itemLabel="red"></xp:selectItem>
<xp:selectItem itemLabel="yellow"></xp:selectItem>
<xp:selectItem itemLabel="green"></xp:selectItem>
<xp:selectItem itemLabel="blue"></xp:selectItem>
<xp:selectItem itemLabel="white"></xp:selectItem>
<xp:selectItem itemLabel="black"></xp:selectItem>
</xp:comboBox>
</xp:td>
</xp:tr>
</xp:table>
</xp:panel>
</xp:repeat>
<xp:messages layout="table" style="color:red" id="messages1">
</xp:messages>
<xp:button value="Save?" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" immediate="false" save="true"></xp:eventHandler>
</xp:button>
</xp:view>
It will not save any of the data unless all validations are satisfied and it will not remove any entered data either. Don't get into the way what XPages does automatically (you also don't brush a cat against her fur). Your validation should happen in the validator and let the data source be saved by the button. As you see: no Query/Post event code is needed here.
I really don't get what you're trying to do so I'll just comment on a piece.
If you want data to survive a context.reloadPage() I think you would need to bind your controls to sessionScope. ViewScope is probably wiped out during the reload but sessionScope should still be available.
Good Luck!

Xpages - Conflict is created everytime a document is saved

I have a xpage, with multiple tabs. First tab contains a panel, whose content are editable only when isNewNote() is true. So I computed readonly attribute for the panel.
But everytime I save the document, it is creating a new conflict document.
At the sametime,if I uncheck read-only property, it is saving properly without any conflict.
Can anybody help me to solve this issue?
CODE - Xpage
<?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="frmOnboardingRequest">
</xp:dominoDocument>
</xp:this.data>
<xp:panel>
<xp:this.readonly><![CDATA[#{javascript:if(document1.isNewNote()){
return false;
}else{
return true;
}}]]></xp:this.readonly>
<xp:table>
<xp:tr>
<xp:td>
<xp:label value="O n_ e d_ form completed by:"
id="oN_ED_FormCompletedBy_Label1" for="oN_ED_FormCompletedBy1">
</xp:label>
</xp:td>
<xp:td>
<xp:inputText
value="#{document1.ON_ED_EmployeeName}"
id="oN_ED_FormCompletedBy1">
</xp:inputText>
</xp:td>
</xp:tr>
</xp:table></xp:panel>
<xp:button value="Submit" id="button1"><xp:eventHandler event="onclick" submit="true" refreshMode="complete" immediate="false" save="true"></xp:eventHandler></xp:button></xp:view>
Check for multiple datasources pointing to the same document.
Some posts before with the same problem
xpage creates save conflict on save/submit
Multiple data sources in XPages
Lotus Notes: Replication conflict caused by agent and user running on the document at same time
=================================================
Edit
I had to change the button code to this to get the same problem
<xp:button value="Submit" id="button1"><xp:eventHandler event="onclick" refreshMode="complete" submit="true">
<xp:this.action>
<xp:saveDocument></xp:saveDocument>
</xp:this.action></xp:eventHandler></xp:button>
After some more testing, try this.
Add this field to the end of the xpage
<xp:inputText id="inputText1"
value="#{document1.temp}"
style="visibility:hidden;display:none">
</xp:inputText>
Then no conflicts are created.
Strange indeed - but also not. Your data source is bound to the page and not to the panel. So if you want to set read mode only for that panel, consider to calculate the panel's datasource from the page's datasource:
<xp:panel>
<xp:this.data>
<xp:dominoDocument var="document1" action="openDocument"></xp:dominoDocument>
</xp:this.data>
</xp:panel>
Of course you have to calculate the document mode and the docid instead of using the readonly property.
In addition to the other suggestions, when working with tabbed tables you will want to follow this blog post carefully. I have been through similar issues on a previous project and Tommy Valand's redirectToCurrentDocument() fixed them.
http://dontpanic82.blogspot.com/2010/06/xpages-avoid-saving-duplicate-documents.html

Resources