Filtering a nested repeat - lotus-notes

My application has documents for Companies, and for Clients. This is a many to many relationship; a company can have any number of clients, and a client can be a client of many companies. The relationships are stored by creating a response document to the company, with a field containing the ID of the client document.
I would like to be able to show fields from the client document on the company's XPage, and I've been trying to do this with repeat controls. I created a view of all the link documents, and used that to create a repeat, filtering it with the current document ID to collect all the links that the current company has. This allows me to list all the IDs of the client documents associated with that company.
I have been trying to work out how to pass this ID to a repeat control nested within the first one, either to use it as a filter on a view of all the client documents, or to use it as the data source document ID directly. Is this possible? If not, how would I go about showing data from the client document on the company page?

When you specify a repeat control you specify the variable that contains the instance value. This variable name is visible to anything inside the repeat control. So your variable would contain the UNID of the client documents one at a time. E.g you call it ClientDocID. You put a panel inside that repeat control. That panel can have its own DominoDocument data source. The datasource can have new, display or edit as default action. You pick "display" which requires a DocumentId to be provided. Select "computed" and simply use ClientDocID as formula.
You can suppress rendering of HTML for the panel (check the properties), so it would fit e.g. inside a xp:tr.
Hope that helps

Related

Filtered and Categorized view on Lotus XPages within Notes client

Hoping someone can point me in the correct direction for an XPages application we are writing inside the Domino Client (Notes?) viewer.
I have a view of documents which is being returned, this view has categories on it, and shows fine as this in an XPage, we now apply a filter to the view to limit it to specific owners of the documents, but as soon as we apply the filter, the categories disappear, which means we are left with a long list of documewnts, but unsorted - is there any way to display a filtered view in a categorized manner, on an XPage.
Moving further down my list, I also need to be able to select these documents (and one or many owners) to send to an Lotus Agent which will then create a JSON document to be sent to our friends at DocuSign requesting signatures from the selected owners on the selected documents. I'm not sure what an Agent is yet, but that is the goal ...
Caveat: I'm not a Domino developer, so excuse me if some of the terminology is incorrect.
Categorised views are a very "Notes" construct. When you filter a view, it will only show documents, but not categories. While they are practical in the back, they are cumbersome in the UI.
There are a few design considerations how to tame them in a webUI. However if your users love them, you might consider to flatten them out and recreate the categories in the UI (client side) only.
The actual better way for your use case: add another view that is firstly categorised by the owner and secondly by your category. Use the category filter of the view control to limit the documents to that author. This should do the trick. Eventually use one of the controls from the extension library.
For the agent: don't bother, that's "old Notes speak". An agent would be a piece of code (LotusScript or Java, but since you do web interaction: Java) that gets triggered by an event: manual, on schedule, on document create/update (with some delay).
Since you are in an XPage, you have easier options at your disposal: create a Bean that has the JSON format you need, add a method that takes a Notes document as parameter to populate it, something like public void populate(final Document doc) {...} and use e.g. the GSON library to simply marshall them to JSON (or a collection of them). The GSON library probably is on a current Domino, I put it there as part of VoP 1.0.
Then use a managed bean to talk to Dokusign. When traveling down the managed bean road is is much easier to test than trying to mess with agents.
Hope that helps and ask more questions! (Check the Learning XPages Cheatsheet too)

How to edit a record(s) with multiple form xpage?

I have an xpage that allows the user to choose a customer and then order products for that customer. It's not a simple xpage that created a document, uses a view control to view it and re-edits it. It will be used on the web and in the client. How do I fill in all the data for the various fields when the user wants to look at their order for a company since there are multiple documents that make up that xpage? Is there automatic processes or do I need to do it manually?
The best method is to use multiple datasources (the Notes documents) each with a different datasource name. When saved, be sure to save each of the datasources that have a change. Also, it is helpful to mark to "ignoreRequestParameters", so each one acts independently.
I have found that using the dynamic content control useful when doing things like this, it seems to reduce the number of replication/save conflicts.

Get recently read document in Lotus Notes Database

I am developing a database on Lotus Designer 8.5 environment with LotusScript and LotusFormula.
Is there any possibilities on get a list of recently opened documents (for example last five) in a Lotus Notes database ? My purpose is to provide an embedded view showing the recent documents opened by current user on the current database, which will act like some kind of history view.
Please advise
Use a folder categorized by username. Add the current document in PostOpen event to folder with document.PutInFolder(folderName) and remove the oldest document from folder with document.RemoveFromFolder(folderName)
This way you don't need to edit the documents and can show the last visited documents for a user in an embedded view.
As an alternative you can use user specific folders with option "Shared, private on first use".
I have that functionality in one of my databases.
I just added some code in the QueryOpen event of the form to store the UNID of the document in a profile document linked to the specific user. The values are stored in a multi value field, and my code removes the oldest entry when the number of entries I want to store is exceeded.
The user can actually set that number themselves in teh applications settings, 5 is default but they can make it more or less.
I built a class for this, makes it very easy to modify later, and to implement it in different forms, for different document types.
I then built a method to expose the last documents to the user, using a dropdown box as you can see below. Since you only wwant/need the five (or perhas ten) last documents, no need to use a view.

Repeated fileDownload control each displays the same list of files?

I'm creating a student assignment submission application using xpages (8.5.3 FP3 UP1). The details are:
Student can do any number of submission. For each submission, a unique SubmitID will be created. For now,
a. The Form (Submit) - 2 fields only (SubmitID, SoftCopy-RTF type)
b. The View (Submit) - 2 column only (SubmitID, AttachmentNames)
c. Examples of SubmitID are: submit1, submit2
For each submission, student must select what course/subject that submission is for (eg: Maths, Physics etc). Therefore I've already created another form for the teacher to create the list of subject
a. The Form (Subject) - 1 field only (SubjectName)
b. The View (Subject) - 1 column only (SubjectName)
c. Say for now 2 subject has been created - Maths & Physics
I've created 2 xpage:
a. Submit.xsp - to create new submission (using form - Submit)
b. SubmitView.xsp - to display the list of submission (using view - Submit)
For Submit.xsp, here's where my problem begins:
a. The controls in here are as follows: SubmitID EditBox, Repeat Control(inside is a CheckBox, a fileUpload, and a fileDownload)
b. The repeat is based on the list of subject available. The CheckBox title will be each of the SubjectName. In the OnChange event of the fileUpload control, each time after a file is browsed, the checkbox will get checked and this worked.
c. The fileUpload should only update the accompanying fileDownload but instead the attachment that I just uploaded is reflected to every other fileDownload control. I'm doing full refresh on the fileUpload OnChange because that's the only way for the fileDownload to be updated. What is wrong here and what should I do to get the result that I wanted? Saving the document and opening it later in both read-only or edit mode is fine although each subject still display the same list of uploaded files. Both fileUpload and fileDownload are binded to the SoftCopy field.
Unless I'm not correctly interpreting your description, you're binding multiple upload / download controls to the same item ("SoftCopy"). Because these controls are always bound to an item, not to each other, a download control will show any attachments stored within the source item, regardless of how they got there. To limit display of attachments in a download control to those sent via a specific upload control, they must be stored in an item unique to that pair.
For example, if each pair were bound to a subject-specific item, such as "SoftCopy_Maths" or "SoftCopy_Physics", then each download would only display attachments stored within that specific item. You don't know what subjects will be defined, so you can't define these fields on the form, but that's okay... you don't need to. NSF has no schema, so a field need not be defined on a form for a control to be bound to it; the item will be created when the document is saved, even if the form does not define it. Strictly speaking, even the form itself need not exist.
We typically bind controls to items using dot syntax, e.g. #{currentDocument.SoftCopy}, but array syntax is equally valid, e.g. #{currentDocument["SoftCopy"]}. So if you wrap these controls in something that establishes the dynamic item name as a variable or property, you can use array syntax to target that dynamic item. Two of the best ways to do this are data contexts and custom controls.
For instance, you could surround the contents of the repeat in a panel, and define a panel-specific dataContext that associates the variable attachmentItemName with the concatenation of the item name prefix and the specific subject. Your upload and download controls can then be bound to #{currentDocument[attachmentItemName]}.
Alternatively, you can move the same content to a custom control that accepts the data source and item name as properties, in which case your value binding might look like #{compositeData.dataSource[compositeData.attachmentItemName]}.
Apart from very minor differences in runtime performance, either approach is equally valid.

creating many to many relationship between documents in different lotus notes databases

I am doing "traditional" lotus notes programming (same since R5) and need to implement linking between 2 document types (forms) residing in different databases.
Document of type (A) in database (A) can reference several documents of type (B) in database (B).
And document (B) should also display its relationships with document (A), as document (B) can be related to different documents (A).
We have Many to Many relationship.
At the moment it is implemented on one side only (one to many):
Form of Document (A) contains embedded view of special
"link" documents residing in database A. This link documents are created by lotusScript when user selects documents from database (B). When user clicks on an item in this embedded view, it opens document (B).
Client wants to be able to edit this relationship on any side, so that if he edits it in form (A), form (B) is updated.
Form (B) is supposed to have the same kind of embedded view or a list of associated documents of type (A)
What is the best way to implement it?
Client's infrastracture is Lotus Domino 8.5.2 + Lotus Notes 8.5.2, so theoretically, composite applications approach may be an option.
The reason why I ask this question is that as far as I understand there is no good way in Notes to embed a view from another database.
The requirement is that the database should be present on workspace to be displayed in some sort of dodgy list.
It would be great to be able to specify target database for embedded view by server and replicaID, but instead we have a weird list of random workspace databases.
The main problem is that Notes wasn't designed to handle relationships like that between databases (nor anything besides parent child relationships for that matter). So the solution will have to be a creative one.
A couple of (off-the wall, potentially awful) ideas come to mind. One is to store the references in the documents themselves, and update them whenever the document is saved. That could all be done in LotusScript, and would require searching through the other database's documents to update their references.
Upside is that the performance when reading the documents would be excellent. There'd be no issues while reading Database A if Database B was unavailable. It keeps data local to each database. The downsides include the likelihood of save conflicts and the danger that references could get out of sync if documents aren't "saved" but instead are updated via agents, etc.
Another thought is to use agents to manage the links on a scheduled basis. If you don't need real-time up-to-date references, you could run an agent that scans Database B and updates the references in Database A. With this method you could choose either to update the Database A documents themselves - or - as it sounds like you've already done, create a set of link documents that show up in an embedded view. The latter eliminates the save conflict problem.
One more idea is to hide any references when you open a document in Database A, but provide a button to "show" or "update" references. When you click that button, it fires off LotusScript to search Database B and build a list on the fly. This would probably work quickly with less than 10,000 documents. That function could update the link documents you store on the same database which feed the embedded view.
Hope this helps!
What is the best way to implement it?
As you mention creating a composite application may allow you to do this, but would be restricted to windows rather then design level in the form.
eg.
[Window A] --- trigger ---> [Window B]
If you are not familiar with this system I did a tutorial which explains the basics.
http://www-10.lotus.com/ldd/compappwiki.nsf/dx/ibm-my-first-wire
Although the tutorial calls back to the same database, it is easy enough to point to a different one.
Personally I'd do it through XPages. I personally find it much easier to implement then through classic style notes design/comp apps. It will also allow you to display design elements within the same screen area.
As you've already heard, Lotus Notes has no referential integrity constraints built-in, you have to do it yourself.
I wouldn't be relying on document links as they're geared around UNID's which can change if you cut and paste the same document, thus losing the link. Try this,
1/ Create an "ID" field on each document. You can populate it by using #Unique in a computed field to generate an ID, and save that to the documents in both databases. You can create an agent to do this in lotusScript (LS), or formula. (Consider using the evaluate statement if doing in LS)
2/ Create a lookup view in each database that lists the documents by the new ID (don't forget to set the "sort order" of the ID column.
3/ Using an action button that can be configured for both databases, you can create a LS function that will open the the opposing databases view and return the ID field. (NotesUIWorkspace.pickliststrings would be the simplest way to pick the documents, otherwise you could build a dialogbox. Store the list of results in a field called "linkedID" as multi-value list.
4/ There may be more info that you want to store like document title or author, so you'll need to then get a handle to those documents using getdocumentbykey and then interrogating the fields you'll need to display information on screen.
5/ You can then also add a new field on the target documents you're referring to, call it "referrerID", which is a list of documents that reference the current document. This will maintain the two-way relationship.
The field that stores links must be a multi-valued field, otherwise it gets quite cumbersome to loop through list of linked document ID's and manage them.
This approach uses a static key so you can copy databases around without losing the relationships between documents the user has invested time in producing. You can (and probably will) lose those relationships if you rely on document universal ID's (described well in the #documentUniqueID documentation), if you cut and paste the document, or copy the database somewhere else they become new documents despite copying the same fields, and will be assigned a new universal ID, any document links for the old document will be invalid.
If the information you're displaying from the other database changes, you'll need to be able to refresh that data regularly, so consider writing a scheduled agent that can do the look up and refresh the relevant fields.
If the user intends to un-link or change the relationships between documents, then you'll need to add functions that loop through the key fields and keep the lists consistent with what the user is doing. So, like I said, Lotus Notes' flat data structure requires you manage all integrity constraints yourself.
If you want to get a little fancy you can use embedded views as they do support references from another database on the same server. Some tips about handling it in LotusScript here. And use an additional view that categorises your data by the referring ID. Embedded views are ok, as long as the view they're based on is not too big, otherwise it may affect the performance of the form that it is embedded into.

Resources