0
votes

I am using this code to copy some documents by a button click source. I would like to prevent the end user from having to select columns and would prefer simply get all the documents ids from the view panel. Not exactly sure how to do that, or if a dataview might be a better choice for me.

var viewPanel=getComponent("viewPanel1"); //get the componet of viewPanel
var docIDArray=viewPanel.getSelectedIds(); //get the array of document ids
for(i=0;i < docIDArray.length;i++){
var docId=docIDArray[i];

var doc=database.getDocumentByID(docId);
var db=session.getCurrentDatabase();
var newDoc:NotesDocument=doc.copyToDatabase(db);
newDoc.replaceItemValue("approved","No");
var id=newDoc.getUniversalID();
newDoc.save(true);

}
1
So you want to copy all documents that display in the view, rather than only the ones selected by the user?Tim Tripcony
Yes. It sounds like a simple thing so I am going to assume I a missing something simple here.Patrick Sawyer

1 Answers

5
votes

Leave the view panel out of the equation: a view panel is a component, and components are for users to interact with; if the user's interaction with the view panel (i.e. "selecting" documents) doesn't alter which documents you wish to duplicate, ignore the view panel (at least, for the purposes of this specific event).

If you simply want to duplicate all documents that display in the view to which the view panel is bound, talk to the same data source the view panel is associated with. So, assuming your data source declaration looks something like the following:

<xp:panel>
 <xp:this.data>
  <xp:dominoView var="allDocuments" viewName="($All)" />
 </xp:this.data>
 <xp:viewPanel value="#{allDocuments}">
 ...

...then just iterate through that same view:

allDocuments.setAutoUpdate(false);
var eachDoc = allDocuments.getFirstDocument();
while(eachDoc) {
 var newDoc = eachDoc.copyToDatabase(database);
 newDoc.replaceItemValue("approved", "No");
 newDoc.save();
 newDoc.recycle();
 var nextDoc = allDocuments.getNextDocument(eachDoc);
 eachDoc.recycle();
 eachDoc = nextDoc;
}
allDocuments.setAutoUpdate(true);

Since you're duplicating the documents within the same database, when the event finishes, the view panel will simply show twice as many documents, since you duplicated all of them. Unless, of course, the item value you're replacing disqualifies them from the view you're displaying.

NOTE 1: The reason the code above toggles the autoUpdate property is because, unless you toggle that to false prior to the iteration, when you duplicate each document, if the new document does display in the view you're iterating, the indexer will become aware of it, and you might end up in an infinite loop, because each time you try to get the next document, it's actually returning a handle on the duplicate you just created... so you would essentially be infinitely duplicating the same document until some exception is thrown (i.e. stack overflow, out of memory, etc.). Disabling autoUpdate prevents that by only allowing iteration of entries the index was aware of when your routine began.

NOTE 2: If the data source is only defined inside the view panel, move it to a parent (panel, Custom Control, or XPage) that also contains whatever component will trigger the duplication (i.e. button, link) and reference the data source within the view panel. That way both the view panel and the button can talk to the same data; otherwise, only the view panel is aware that the data source exists.