I have two forms project(Document) and comment(Response to Response) I want to create a view that displays all comments of selected Project
Any help would be appreciated.
I love doing this type of stuff in xPages.
For a moment, don't think about project and response. Think uniqueID. In order to make the project document reference the comment you add a unique ID to each of them that will reference each other. Don't use response docs in xPages, there is no need I see. When you save the comment, save the unique ID of the parent document to a field on the comment document by referencing this value where document1 is the datasource of the parent and document3 is the document of the child.
<xp:modifyField name="uid"
value="#{javascript:document1.getDocument().getUniversalID()}"
var="document3">
</xp:modifyField>
Now that you have a bunch of parent and children docs, you create a categorized view where you are only capturing the comments. Use a view selection formula to exclude the parent form. Make the first column the uniqueID that you previously captured. You now have a view that will keep all the comments categorized by the unique id of the parent.
Now in the xpage you now need to filter on the key value. You filter by computing the keys to the value of the parent document. Here document1 is the parent.
<xp:dominoView var="view2" viewName="rejections"
keys="#{javascript:document1.getDocument().getUniversalID()}">
</xp:dominoView>
The great thing about doing this is it will work in a viewPanel, dataView, or a repeat control since you are referencing the data not the UI.
If you wanted to do comments of comments there are a couple of approaches but I think they would all have the same structure. If you made it this far start looking at repeat controls they will let you break free of the normal notes views.
I moved away from using Parent and response documents in Notes years ago because they were just too much trouble. I also moved away fro using the UNID as the 'link' for several reasons. The first is that the UNID can change (resolve a save/rep conflict) Second archiving is all but impossible because again the UNID changes when the document is copied to another DB. So when I create a 'parent' document I store #Unique into a field I call LinkKey, and store that value in all 'response' documents. When I create the response then I store a new #Unique into a field rLinkKey. This way a response to a response knows it's originator (LinkKey) and it's direct parent (rLinKey). Now you can extend this any number of levels deep fairly easily.
This worked OK in native Notes with some kludge, but now in XPages with repeat controls the real power comes from nested Repeat Control. Something I have always wanted to do in Notes but was never able to is now a piece of cake.
The down side is that getDocumentByUNID() is going to be faster that getDocumentByKey(LinkKey, true) but the other advantages far out weigh the unnoticeable time difference (IMHO)
Related
I filtered out XPages view with 'search' option. Then I'd like to access all of the documents by SSJS.
If I access the bound Notes view by database.getView("ViewName"), the view is not searched and could not get the searched result.
How can I access the document collection?
The dominoView data source is just a wrapper that runs calls on the underlying view to return a subset of entries to display in a view component (Data Table, View Panel, Repeat, Data View etc). Consequently, unless the rows property is set to a large enough value to get a handle on all responses, you’re unlikely to be able to access what you want that way.
The best approach will be to run the search on the backend view in SSJS / Java.
See https://www.intec.co.uk/understanding-xpages-views/ for a more detailed explanation of the different elements involved and their inter-relationships.
In my application, i would like to replace a viewpanel with a repeat control.
However, part of the functionality is there is a UI aspect that allows users to select certain fields (that correspond to the view), and only display the documents that match. The view is doing a filter that allows users to select aspects of the view to create a search (the code is under search of the view) that allows the view panel to be updated with the results of the search.
one of the things that is curious is that the viewpanel has a value of "#{javascript:view2}" vice an actual view name.
The viewpanel defines the search view and the ...
I'd like to be able to apply that same functionality to the repeat control. I don't see those attributes on the repeat control... Any pointers? Its been a while since i've worked with xpages... long enough that I've forgotten a lot already....
TIA !
Read this blog post I did a while back, it should explain what you need.
The view panel doesn't filter anything, it just displays rows from a datasource, same as a repeat control. Indeed you can add components to a ViewPanel's column, pulling from the current row by adding a var property to the dominoView datasource.
The view is bound to #{javascript:view2} (which would be better done by binding to #{view2} - there's no need to call SSJS here). view2 is a dominoView datasource somewhere on your page. The datasource is a wrapper that has properties to capture the settings for filtering and searching that you want to do. At runtime, they are calculated and changes the ViewEntries in the datasource.
Finally there's is the underlying Domino View object available also to LotusScript. This holds and will always hold all entries. The dominoView datasource queries that using the filtering and searching properties and retrieves a ViewEntryCollection or a ViewNavigator.
So whether you use a View Panel, Repeat Control, Data View or whatever else, those are just components to visually represent a collection of ViewEntries or Documents. All can be bound to a dominoView datasource. Where repeat controls and Data Views give you extra power is you can bind them to any kind of collection, not just a dominoView datasource (e.g. DocumentCollection, ViewEntryCollection, multi-value field, Java collection, etc).
I often find that doing the searches in Java and then passing the results to the repeat as a List work better and allow more options. I can get all the information I need in Java and load that into a Map or Tree. This gives me the ability to do custom sorting in the Java class and also to combine data from other views/databases easily. Since the data is now in memory it gets reloaded fast. The only thing you have to watch for is the size of the data. If you have a view with many entries (10K?) you might not want to load everything into memory...
Howard
I'm not sure if you've found a solution yet, but consider using jQuery dataTables. Oliver Busse wrote a very detailed blog post about integrating dataTables into XPages.
To get the specific formatting, I used a repeat control to include the "td", "tr" and "thead" attributes Oliver listed in his blog post.
I have a view defined on an xpage. I also have several filters (based on the columns) that the user can select and combine to filter the results in the view. I generate a query string based on this that I construct in dominoView.search (doing a complete refresh). What I would like to do is get the results of the search so that I can then update some counts displayed elsewhere on the page. I'm having a hard time figuring out where I can perform this logic, though. I'm trying to use view.getAllEntries() and then iterating over the collection. Sometimes it seems like it works, but other times I seem to be getting the unfiltered view. Someone suggested I explicitly call view.FTSearch inside one of the events (beforePageLoad?) and immediately after do my getAllEntries call, saving the results in viewScope, but I get an "Error while browses Notes view" runtime error when I try to do that. Any pointers? TIA!
EDIT: After studying the xpages lifecycle a bit (which is still a little confusing), I think I can fine-tune my question. This is my first stackoverflow question, so I hope this is okay to do and productive....
As I described, I have a dominoView defined on my xpage. A repeat iterates over the rows of the view, displaying certain fields from the documents. If I define a query in the search property, then the repeat correctly displays the reduced set of documents rather than the complete set. (The query is computed in the search property via SSJS from some variables defined in the viewScope in a combobox's eventHandler.) However, if I try to access the current entries in the view inside of the repeat's rendered section (with SSJS) using myView.getAllEntries (where myView is what's defined as the "value" of the repeat), I am still getting all of the documents, even if a query has been done. It seems like at that point, the view variable has already had its search applied (since the repeat works), so why the differing results? Is there another way to access the view's rows? To complicate this further, this is just a simple experiment that might clarify the problem; as I indicated earlier, I don't actually want to access the view data within the repeat, I want to access it in the rendered or value sections of some comboboxes defined before the repeat in the xpage file.
I hope that makes more sense now....
EDIT #2: I forgot to add that if I manually call FTSearch (or FTSearchSorted) before calling myView.getAllEntries, then I think I can make this work. It just seems unnecessary to have to do that in addition to the view's built-in search.
From what I get you want to iterate over the entries in a view that before has been filtered, i.e. whose resulting entry collection is smaller than the the view itself.
What I don't get (yet) is what you want to do with the result, or what you're axpecting to get from the iteration over your filtered view (you're mentioning some counts to be displayed somewhere else).
Probably a good way is to use the view's .getAllEntriesByKey method which returns a NotesViewEntryCollection object which then can be used for your iteration.
Don't forget to recycle the resulting NotesViewEntry objects; reason for this has been explained several times here at stackoverflow.
I have a strange thing, I'm using dynamic field binding in a custom control.
The field binding is created like this.
XPage (Datasource "document" is placed here)
Custom Control (String passed in)
(to get errors if there are any)
Repeat (CompositeData is passed to a bean that returns the strings for Rows,columns)
Repeat (repeat 1 variable used for Columns)
Custom Control (fieldname is passed in)
field binding is done like this
#{document[compositeData.fieldName]}
The problem is that when I save the XPage I get an error in the messages control
Document has been saved by another user - Save created a new document as a response to that modified document.
And all fields are cleared.
Any ideas how to debug this or is there something I'm missing?
The "Document has been saved by another user" error is only tip of the iceberg - there are some really strange problems with reapeats that repeats fields that are bound and repeatControls property is set to false. The decoding part of xpages lifecycle cannot handle it properly - the controls will be losing data. You should use repeatControls set to true as Martin suggests.
"Repeat control variable doesn't exists" is probably caused by the property that removes repeats set to true. You can solve this by either changing it to false or by adding additional data context that will keep repeated value.
And finally for this to have add/remove functionality You can use Dynamic Content Control and show(null) hack to rebuild the repeat content.
To manage this complexity better I would advise You to stop using document data source and start creating some managed beans.
If You will follow my suggestions I guarantee that You will get the functionality You are looking for as I have few apps that works great and have this kind of complex data editors in them.
I don't know if it'll help you, but I pass both the document datasource and the field name as parameters to a DynamicField control, and use it like this:
compositeData.dataSource[compositeData.fieldName]
The type of the datasource is com.ibm.xsp.model.DataSource, it's listed as dataInterface under Data Sources.
Do you have repeatControls="true" set for the repeat control?
It sounds like you've got the datasource defined multiple times on the XPage (plus custom controls). Either that or the save button has save="true" but the code saves the document back-end, or code in multiple places saves the same document. I've used the same method of passing the datasource down to the custom control, but that may just be because that was what I saw on a blog.
I have core data app with an entity OBSERVATION that has as one of its attributes DEALNAME.
I want to reference through Interface Builder or by making custom modifications to an NSArrayController a list of unique sorted dealnames so that I can use them in a pop-up.
I have attempted to use #distinctUnionOfSets (and #distinctUnionOfArrays) but am unable to locate the proper key sequence.
I can sort the ArrayController by providing a sort descriptor, but do not know how to eliminate duplicates.
Are the #distinct... keys the right methodology? It would seem to provide the easiest way to optimize the use of IB.
Is there a predicate form for removing duplicates?
Or do I need to use my custom controller to extract an NSSet of the specific dealnames, put them back in an array and sort it and reference the custom array from IB?
Any help would be appreciated. I am astounded that other have not tried to create a sorted-unique pop-up in tableviews.
You need to take a look at -[NSFetchRequest returnsDistinctResults]. That is the level you need to be handling the uniquing of data.
Although I do not have a definitive answer for you, I think there are two ways you can go about it.
The way you already started. You need to bind the contents array of the PopUp button, not just against the arrayController.arrangedObjects, but continue on the path and somehow filter only objects with distinct "DealName"s. This means - the arrayController presents ALL the entities (and may sort them for you) but the PopUp button will have its contents filter via some sophisticated binding to the array controller.
Make your filtering at the ArrayController level (as suggested in another answer here). Here it depends how you set up the array controller. If It is set up to use an "Entity" (vs. "Class") which means the array controller will fetch CoreData entities directly - you can modify its "Fetch" to only bring a subset of the "OBSERVATION" entities with distinct values of "DEALNAME". I don't know how to control WHICH entities are filtered out in this case. Otherwise, you can setup the arrayController to work with "Class" objects, and then you can fetch the entities yourself (in code) and populate the arrayController programmatically, with just the entities you like.
In the second option, the Popup button should be bound normally to the arrayController's arrangedObjects.