xpages should I use ignorerequestParams set to true - xpages

based on these questions:
xpages UNID of documents / why it is changing
xpages why my field value isn't copied correctly
i noticed, unfortunately, some computed field which stores the UNID is changing if I hit refresh / F5.
my XPage has defined one datasource ( Cdoc ) and it contains a button which shows a dialog. this dialog has defined other datasource ( Pdoc ). The dialog contains several fields, which inherit some values from Cdoc...
Should I use ignorerequestParams property for one of these datasources? Can you explain the meaning of this property?
What happens:
The field which stores the UNID of the Cdoc after I show the dialog and create some Pdoc and list it in a viewPanel inside the XPage ( Cdoc datasource ) and then hit F5 the Cdoc UNID is changing ... even if it is computed.
Also, if the doc. isNewNote() the url is something like this:
server/Test.nsf/doc.xsp?action=newDocument
even after I call Cdoc.save(). I think this could be a reason why the computedField which stores the UNID is changing when I hit refresh => a newDoc is created.
Meanwhile, I put the ignoreRequestParams set to true just for the dialog ( Pdoc ).
Thanks for your time!

By default, the UNID and action (open, create, edit) are defined by the URL query string, i.e. the request parameters. With requestParamPrefix you can define which entry in the query string is used to find the document parameters for this datasource. By default that's documentId. But if you want to manage the UNID and action yourself through code, that's when you need to set ignoreRequestParams="true".
If you have two datasources on a page, you will need to use either ignoreRequestParams or requestParamPrefix on one of them. If not, you're editing the same document in both datasources.

Related

xpages embedded view or view panel

I know it is a very simple question , but I'm trying to see the difference between a view panel ( that I drag from the Container Controls ) and an embedded view.
How can I add an embedded view on my xpages?
Or the 2 items are one and the same.
The reason why I'm asking this question: I have a view panel on my xpage ( I thought it is like an embedded view in clasic lotus notes programming ) where I have listing some docs. The first column is categorized based on the UNID document.
I noticed if I compose again another document, this view contains all the previous docs., and all the UNID categorized. The view panel isn't empty.
In lotus notes programming:
If I have a main form and a computed text field with #Text(#DocumentUniqueId) and some button for composing another form ( of course, when clicking the button I saved the main form to obtain the UNID ), and this form has the same text field name as the previous - I'm passing the UNID to this second form. If the main form contains an embedded view listing all documents saved from the second form I will use the first column categorized and hidden with the name of the field from the second form ( which will contain the UNID ). If I save and close the 1st main, and then I'll compose another main form, the embedded view is not listing the previous documents already saved.
Well, this view is already created.
I did drag and drop this view in myxpage. I have a button inside myxpage that shows a dialog. Here a datasource is declared, the dialog containing some fields. In the main xpage ( where is defined another datasource ) there is a computed field which takes the UNID of the document. Before I click the dialog I save the first datasource, to pass the value UNID to other field inside the dialog.
I save the datasource from the dialog & close the dialog, and then the view panel ( which is the view from the lotus notes classic presented above ) lists the doc. If I close the main xpage ( save it if is a new one ) and then open another main document, the view isn't empty, it contains the previous document lists. ( I tried also to hide it, if the xspDoc is new. But when I try adding other docs. from the dialog, the view panel lists also the previous documents from the previous doc., even if the UNIDs are distinct )
Thanks in advance.
To explain this best, it's good to consider what a view and an embedded view in Notes Client is. A view determines the look and feel, like a View Panel and by default will show all documents found by the selection criteria. So in this case the documents available correspond to a dominoView datasource bound to the underlying view with no additional criteria defined.
An embedded view still uses the view to determine the look and feel, but will not display the first column (that's effectively a property of the embedded view "control" in Notes Client). In the View Panel you choose which columns display, so you would need to code that yourself on the View Panel, where you choose which columns to display. The embedded view also has a property to define the single category. But the View Panel and other repeating containers (like Data Table and repeat control) don't restrict the data available, that's done by the datasource - a dominoView or e.g. a ViewEntryCollection for anything other than the View Panel. So in that you set the filter.
However, a new document does not have a UNID, so it cannot restrict what is displayed. Instead, I think a good approach is to set the visibility so the View Panel is only displayed if it's not a new document. You can use loaded, if you fully reload the page after save, or else rendered.
First off, this is not a stupid question.
I am assuming you are using a self implemented parent response system and have a view sorted by the parent UNID. Under the data source of the view panel, find the the "filter by category name" option. there compute the UNID value, or category value you are searching for.
Steps:
insure that the background view is categorized (ascending order is best to insure that this works, though I doubt it is needed)
drag (my favourite is the dynamicViewPanel) a view control onto the xpage.
Under Properties/Data there is a place to calculate the value of the category to show. If you want an exact match, check the exact match check box.
If you mistype the category value or the value is not there, then no documents will be shown.
if you put in an empty value all documents are shown (at least in the tests that I can remember)
if documents are returned, the categorized column is automatically hidden.
EDIT
If you are reading the value from a field, you can use the code:
xspDoc.getItemValueString("fld");
If you are searching based on the UNID, again, hide the viewPanel if the document is new. If the value is not yet set, also hide the panel.
If you have two custom controls, even if a custom control is embedded in the second, you cannot easily have one custom control access the values of the datasource in another. I am sure there are ways to trick this into working, but in this case, use a viewScope variable to access the values and possibly an onLoad, onChange or onSave event to update the viewScope variable. Make sure to verify that the result is not null or empty by either printing it out to the server log or another field.
Final Edit after question edit/expansion
These are the steps that I would take to do what you described.
You have your parent document XPage. Insert all fields for this Xpage.
Drag a dynamicViewPanel onto the XPage. If parentDoc is New, then hide.(this could be a custom control in theory, but if you are having trouble, try it without for the sake of trouble shooting.
Set dynamicViewPanel datasource to ignoreReqeustParams.
Calculate the datasource and setting the "Filter by category name" filter. When computing this, for the sake of ease and troubleshooting, print this value out to the server, or other logging mechanism. You can delete it later.
Verify that the correct UNID/Value is being inserted into the document you create in the dialog.
If you are using a scoped variable to hold the filter value, be sure you are using viewScope and not appliationScope or sessionScope.
if you are using a custom control and standard parameters (not scopedVars), verify that the compositeData variable is being updated with a log or server print.
Consider setting Dialog Properties/AllProperties/basics/refreshOnShow to true
Play with the partial refresh option for the dialogOpen action, test a full vs partial refresh.
Remember to set the ignoreRequestParams for the document you are creating in the dialog to true
Consider making the new document data source created in the Dialog to request scope.
And of course consider and test all datasources being defined on the XPage on not some here, some there.
Verify that you are taking the value of the UNID from the main document and not the new dialog document by mistake!
Those are all of the tips I can think of right now, pretty much in the order I'd try them in. If that does not help, then I suspect there is a piece of this puzzle that you are not including in the question. Remember, try to keep things as simple as you can. You can over think things, make things harder than they need be.

xpages passing the UNID to other field

I have an input field:
<xp:inputText value="#{Cdoc.txt_UNID}" id="txt_UNID1"></xp:inputText>
The field txt_UNID is computed having the value: #Text(#DocumentUniqueID).
What I noticed is that even I just compose the xpage containing the document content the inputText already contains some UNID even if the xpage containing the doc content wasn't saved.
There is a button which is showing a dialog containing a field. I want this field to have the value of txt_UNID
Cdoc.save(); // I must save first the Cdoc datasource ?
getComponent('exampleDialog').show()
And the code for the field:
<xp:inputText value="#{Pdoc.txt_CompanieUNID}"
id="txt_CompanieUNID1" defaultValue="#{Cdoc.txt_UNID}">
</xp:inputText>
Thanks for your time.
If your question is whether or not you must first save the document in order to get the UNID, my answer is yes. In my tests, the UNID has changed from a new document to a freshly saved document. So, yes if the current document is new, save before getting the UNID. At least when it was a NotesXspDocument.
I also generally use JavaScript for this,
cdoc.getDocument().getUniversalId();
Otherwise, I am unsure what you are asking.
If PDoc is available at the same level of the hierarchy as CDoc, e.g. both are datasources assigned to the XPage / Custom Control or the same Panel, you could update PDoc on save, using PDoc.replaceItemValue("txt_CompanieUNID",Cdoc.getDocument().getUniversalID()). setValue should also work. Then you would not need the default value.
It just helps keep all business logic in one place. You could also check whether a value has already been set.

Multiple data sources in XPages

I have 2 xpages that interact together. The first acts as a homepage and allows the user to create a new document and fill out some basic header information. The button to create the new document, sets a sessionScope var with the NoteID. It then saves document1 and opens the same document using another xpage.
The second xpages is bound to document1, and uses the sessionScope to edit the document. This xpages contains and editPanel bound to document2. I want to create a child document to document2. This works but what happens is document1 is also saved as conflict. It is also saved as a second main document.
I DO NOT want to save document1 at all, but can't seem to prevent it. The button that creates document2 uses the simple action save document, and specfies document2.
HELP, I have tried everything, and have been stuck on this for 2 days.
Thanks!
Steve
To bind to multiple datasources, on your XPage, under Properties expand Data and set "Ignore Request Params" to TRUE
If you change the type of your buttons, to a simple button instead of a submit button, and handle the doc.save() yourself should solve your problem.
The Save Document simple action accepts the name of the data source to save as a String argument. If supplied, it will only save that specific data source.

Xpages- Create New copy of saved document and open it without saving it

I have a document that I want to create a new version/copy of, so I am trying to do server-side javascript to
Create a new document
copy all items from the current document
open the new document that I have created, without saving it
I am not able to open the newly created document, is this possible?
code I am using is:
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 newDoc = database.CreateDocument
doc.CopyAllItems (newDoc)
var docUNID = newDoc.getUniversalID ()
// need something here to open copied document
}
You need to store the IDs in the session scope and then open the page and do the copy inside in one of the data source events:
var viewPanel=getComponent("viewPanel1");get the componet of viewPanel
var docIDArray=viewPanel.getSelectedIds(); get the array of document ids
sessionScope.alltheDocs = docIDArray;
then open the page where you want to have the new document. Inside that page you need to have a repeat control that matches the element count of alltheDocs. I probably would design it using a DojoTab container (one tab per document). Inside the repeat place a panel with a data source (or a custom control). Then in the queryNewDocument event you copy the fields using the variable name of your datasource.
You could save these docs, then show them and add them to a deletion queue by marking a field on those docs. On save remove them from deletion queue as a work around possibly.
1) Do not store Notes object to scope lasting longer than request.
2) If XPage has to inherit some values, it needs to read them from some source.
3) You can not inherit data from Notes document - according to (1) in memory object must not be stored in sessionScope (simplest way to pass objects between two pages), and you can not retrieve it by UNID/key (it is not saved, as requested).
So, (possibly) the only option is:
Make copy of source document - copy every field you are interested in into Map[String,Object]. Fields must be converted into "raw" objects String, Double, Date (java, not Notes) or their vectors for multivalues. You must not copy special (Notes objects) fields - names, dates, rich text! Names can be converted to strings, Dates can be retrieved as Java dates, rich text might be treated as MIME (String) (but with possible loss of formatting). I think you don't want to pass attachments.
In target XPage, define queryNewDocument event to lookup and initialize fields from this Map object. Delete the sessionScope object to prevent duplicates.
I needed very similar thing in my application. I have XPage with a source document opened in read mode. There is a button that creates a new document and set few values (using the source document). I wanted the XPage to open this new document in Edit mode after it was created.
Note: I could not use redirect with URL parametr action as I needed to open it in a same XPage and preserve a view scope variables and beans.
Solution:
Add View Scope variables NewDocAction and documentId (on button click),
Partial refresh of XPage (on button)
Compute document data source using viewScope variable documentId
Check presence of View Scope variable NewDocAction (in onClienLoad event)
javascript code in the button:
var travelDoc = xpBean.createTravelDoc(requestDoc);
if (travelDoc != null){
viewScope.put("content","travelForm"); //to render proper CC on XPage
viewScope.put("documentId", travelDoc.getUniversalID());
viewScope.put("NewDocAction", "ToEditMode");
}
javascript code in a onClientLoad event of a travelForm custom control:
if (viewScope.containsKey("NewDocAction") && viewScope.get("NewDocAction").equals("ToEditMode")){
context.setDocumentMode("travelDoc","edit");
viewScope.remove("NewDocAction");
}

Dialog Control Cannot See Second Data Source on the XPage

I have a custom control with a field where the user will enter a document ID (not a note ID or UNID, just a unique number). This data source is named document1. When they exit the field, I perform a lookup and display either the document with that ID or a new document in an extlib Dialog control (data source bundleDoc). When bundleDoc is saved, I want to update a log field on document1 to indicate that a bundle document was added.
I can save bundleDoc and close (hide) the dialog but the code in my Save & Close button in the dialog can't "see" document1. I can't refer to it using document1.getItemValueString or by getComponent. The getItemValueString returns and empty string and getComponent throws an error because the return value is null.
I would have posted an image to help visually but I don't have enough reputation yet. :(
What am I missing? Shouldn't I be able to get to document1 from the dialog control since it is on the same XPage?
UPDATE: Two fields on the dialog form have computed default values that use getComponent to get their values from document1. So, at least when the dialog is loaded, it can see document1. Also, bundleDoc is not defined as a data source for the dialog control. I will try that tomorrow to see if it makes a difference.
UPDATE 2: Still not enough reputation to post a picture, but here is some code. This is one custom control that contains a dialog control. document1 is defined as the data source for the custom control and bundleDoc is defined as the data source for the panel in the dialog control that contains the table of fields for the bundle document.
The BundleID field in the dialog control has a computed default value using this:
if (bundleDoc.isNewNote()) {
getComponent("inputBundleID").getValue();
} else {
bundleDoc.getItemValueString("BundleID");
}
The formula for StorageLocationID is similar except that the component is inputStorageTrayID.
This is the code in the Save & Close button:
bundleDoc.save();
var newArr = new Array(document1.getItemValue("WorkLog"));
newArr.push("Added bundle " + document1.getItemValueString("BundleID") + " - " + session.getCommonUserName());
document1.setValue("WorkLog",newArr);
document1.save();
getComponent("dialog1").hide();
The error happens on the document1.save line but it does not get the BundleID from document1 (I set a sessionScope variable to the value of newArr and it showed 'Added bundle - Anonymous'.
It depends on where you have added the datasources. If document1 is set as the datasource of custom control 1 and bundleDoc is the datasource of custom control 2 you can't access them outside of the custom control they're defined in.
If you add document1 as the datasource of your custom control and create the xe:dialog control (containing a panel with the bunleDoc datasource) in the same custom control you should be able to access document1 (and update/ save it) from a button on the dialog.
I think the problem was initially caused by caching issues because it started working the day after I posted the question.
However, I had to do one more thing to get the page to work the way I wanted to. This is the XPage in Designer:
To write a value from the Save & Close button back to the WorkLog field, I had to save the document1 data source before opening the dialog. Then document1 was recognized throughout the Save & Close code and it was saved properly at all times.

Resources