I'm new to javascript and xpages here. I'm upgrading an old notes application to xpages. In my xpage I have a field, a save button, and an error messages control. The field is used to save the value of a nsf path/name that the user typed in to be used later on (e.g: //SAS/address.nsf). How do I validate if that path/database exist? The previous lotusscript is like this(it uses 2 field, one to get the server path, the other to get the db path. but for current xpage, the requirement is to use one field only):
svr$= source.FieldGetText("ServerPath")
dbsvr$= source.FieldGetText("DBPath")
Dim db1 As New NotesDatabase(svr$ , dbsvr$)
If Not db1.IsOpen Then
Messagebox "Cannot find the database."
Call source.GotoField("DBPath")
continue = False
Exit Sub
End If
In the field in the xpage, I've added a validateExpression validator. In the expression property, I compute the following SSJS:
var dbdir:NotesDbDirectory = session.getDbDirectory(null);
var db:NotesDatabase = dbdir.openDatabase(document1.getItemValue("dbpath"));
return db.isOpen();
In the validator's message property, I put "Cannot find database".
The error I'm keep getting is:
Expression is invalid.
Expression did not return a boolean value.
Any way to fix this? Is it the wrong use of validator? I've already test with local database and database on other server. None seems to work. All those database I tried I had access rights to them.
You should probably use sessionAsSigner in order to open the database as the signer of the XPage - instead of as anonymous (if you are not logged in). Also, consider adding try/catch around your dbdir.OpenDatabase() in order to catch errors opening a database with an invalid path.
Also, notice that the validateExpression validator must return a boolean true or false. In your case dbdir.openDatabase() will return null if the database can not be opened - which means that db.isOpen() will fail to work since it can not operate on a null object.
You could consider using the customValidator validator which must return an error message (and not a boolean true or false).
I hope this can help you complete the validation.
Use try/catch block for attempt to open database. If everything is OK, just return true in try block. Catch block will return false, what will handle most of the possible fails: wrong server, broken connection, invalid path, no access, and so on.
try {
// open database here and touch some property, doc count, for example
return true;
} catch (e) {
return false; // failed to open database
}
Related
So I have an odd issue, When I create a new transaction and save, this error in the title gets thrown. But when I edit this transaction after it was created, the getText does not throw this error. Is there something I'm doing wrong or something special needed to getText on a create new record? Here is my code. This is for the afterSubmit method on my User Event Script for Vendor Bill screen. I just noticed getValue does work on create, does not produce this error, just don't understand why? Is this the correct way to get the value on create? To use getValue and getText cannot be used on create? Only for edit?
if (scriptContext.type == scriptContext.UserEventType.CREATE ||
scriptContext.type == scriptContext.UserEventType.EDIT) {
// get bill to index
var Bill = scriptContext.newRecord;
// fails on this call below on create but works on edit
var refno = Bill.getText({ fieldId: 'tranid' });
}
This behavior is described in the API documentation here.
In dynamic mode, you can use getText() without limitation but, in standard mode, limitations exist. In standard mode, you can use this method only in the following cases:
You can use getText() on any field where the script has already used setText().
If you are loading or copying a record, you can use getText on any field except those where the script has already changed the value by using setValue().
Apparently the newRecord object falls under the second criteria. At this point, the object only has values set. tranid will have a value with the transaction's internal ID, but it won't have the transaction name stored. To get the text, you will have to use record.load() to get the full record, or use search.lookupFields() to get just the transaction name.
I get the error "Exception occurred calling method NotesDatabase.createDocument() null" for the following:
var db:NotesDatabase = session.getDatabase("", viewScope.targetDb);
if (db != null) {
if(db.isOpen()){
}else{
db.open();
}
} else {
}
var doc:NotesDocument = db.createDocument();
Comments:
The database db is available and "open".
The user has enough rights in the targetDb to create documents.
What is wrong?
I changed db.isOpen to db.isOpen(), according to Paul Stephen Withers tips.
And now db.open() gives the error "Exception occurred calling method NotesDatabase.open() null" although that I can get, in viewScope variables, the server, FilePath, etc.
Change
var db:NotesDatabase = session.getDatabase("", viewScope.targetDb);
to
var db:NotesDatabase = session.getDatabase(currentDatabase.getServer(), viewScope.targetDb);
This works on the web as well as XPinC.
XPages isn't the same as formula, it doesn't like the empty string definition for the server name, which is contrary to the documentation which states (for the server parameter of NotesSession.getDatabase - javascript):]
The name of the server on which the database resides. Use null to
indicate the session's environment, for example, the current computer
Using null or "" gives error 500, it would appear.
The code from the question will work, if :
the if block is removed entirely
the viewScope.targetDb variable has a properly specified notes database file path, which exists on the same server as the current database
the current user has access to the target database ( by the ACL ), with the Create Database right
the target database has a Maximum Internet name and password above Reader as per #Paul
I suspect the cause is you're checking db.isOpen. You should check db.isOpen().
Worth bearing in mind is session.getDatabase(String, String) doesn't return null (unless you're using OpenNTF Domino API). It returns a Database object that is not open. So that if statement is irrelevant. Also best practice is to pass a server name to session.getDatabase() - you'll get a different outcome if the application is ever used in XPiNC with your current code.
Regardless of individuals' user access, "Maximum Internet name and password" on the Advanced tab of the ACL will override that. If maximum internet access is No Access, no one will be able to create documents. But I suspect that's not a factor here.
Pro Tip -- Get the Debug Toolbar and use that to print out messages to the XPage debug toolbar to see what is going on and if your viewScope variable is being set. Also, learn to use the try catch block to catch your exceptions and print out the error message to the debug toolbar. You will find your issue that way.
https://www.openntf.org/main.nsf/project.xsp?r=project/XPage%20Debug%20Toolbar
I have a combobox on my form that loads client names from a view using the format "name | UID" - this displays the client name on the form but saves the UID in the field.
I now want to use the UID to lookup the name for the client and save it in a field on the XPage that is not visible using the following code:
// ignore when UID is null
if (getComponent("parentUID").getValue() == null)
return false;
var UID:string = getComponent("parentUID").getValue();
var doc:NotesDocument = database.getDocumentByUNID(UID);
// now set your fields
document1.setValue("nachname", doc.getItemValueString ("nachname"));
document1.setValue("vorname", doc.getItemValueString ("vorname"));
I do this in a simple action attached to a button. The next simple action is a Save.
The code crashes with the following error:
Error while executing JavaScript action expression
Script interpreter error, line=8, col=42: [TypeError] Exception occurred calling method NotesDatabase.getDocumentByUNID(java.lang.String) null
I have copied the parentUID to a field on the document and I am getting the correct UID and the document exists in the database?
Any ideas?
PS: I am adding this to an existing application and the current document is not a response document - cannot change that unfortunately :o(
OK, I have found my problem - XPages returned the UID but it included a leading space. When I concatenated the values I did the following: "name | UID" i.e. I added a leading and trailing space to the pipe symbol to make the code legible - this was causing the problems.
It looks like you are missing the get.Value() in your getComponent line
Try getComponent("parentUID").getValue() == null
My guess is that this is causing the code to run when the UID is null. This means that the code is running when it really is null, and your effort to check for that isn't working.
Thanks for checking that.
Can you put in a print() statement and ensure that you have a value in the var UID.
Another thing, please capitalize the word "String" since java classes are capitalized.
I have an XPage that is doing an #DbLookup with a user's input and trying to find that value in a view in a different database yet on the same server.
I have already verified that the view is in fact sorted by the first column and therefore #DbLookup friendly. The following code below appears in the server-side Javascript OnClick event handler for a button on my XPage.
My problem is that the an error occurs when trying to assign the value of lRep to the 'firstNameLabel'. lRep is returning a null value from the dbLookup even though the a record under the 'FirstName' field exists with the key 'P301993'. This dbLookup should be finding a returning a single 'FirstName' result. However, it is not.
var resultLabel = getComponent("firstNameLabel");
var dbName = new Array(#DbName()[0],"UKCSandbox.nsf");
var lRep = #DbLookup(dbName,"customerLookup","P301993","FirstName");
resultLabel.setValue(lRep.toString());
Unless your formatting was lost in copy and paste, your code has flaws. This is not Java, this is JavaScript. Line endings matter and functions don't act on the object, but return a value. Also #DbLookup returns a string when you have exactly one match, so checking for string doesn't help you.
Your code should look like that:
var ukcNumber = Registration.getItemValueString('UKCNumber').toUpperCase();
var resultLabel = getComponent("ukcNumberLabel");
var dbName = #DbName();
dbName[1] = "UKC\\UKCSandbox.nsf";
var lRep = #DbLookup(dbName,"customerLookup",ukcNumber,1);
resultLabel.setValue((lRep) ? "Success" : "Failed");
Does that work for you?
Update: 2 things to check:
does the lookup work in the same database using #DbName?
XPages have the same security constraints as Java agents. Do you have enough rights in the server document to do a 'get value from other database'? Default is No!
Have you tried making the dblookup work outside of xpages, i.e. with ScanEZ or in the Notes client?
Check your ukcNumber variable so it contains a value.
Edit
Check so the user has rights to do the lookup in the other database.
Also try a similar code on an old Notes Form and see if you get the same result.
Why can't you use keyword '[FAILSILENT]' in your #DBLookup call. It'll return "", if no entry matches with your key.
If you still have issues, use SSJS/java code to see where it's breaking up.
I have a repeat where the value loops through documents in the current database, these documents contain a database and view name. The repeat then opens the database and view and retrieves data from within them:
var dbOther:NotesDatabase = session.getDatabase(null, doc.getItemValueString("Database"));
if(dbOther != null){
var lookupView:NotesView = dbOther.getView(doc.getItemValueString("ViewName"));
var viewNav:NotesViewNavigator = lookupView.createViewNavFromCategory(key);
}
This works fine on all browsers but if I view the xpage in the Notes Client I get the following error: Exception occurred calling method NotesDatabase.getView(string) null
I have tested that the dbOther variable is set by writing the Server and FilePath properties to a log. I checked that it could see the views by generating a loop using getViews and getAliases, again all view aliases were written to the log without an issue.
I have manually entered the view name in case the value was not being selected from the document correctly but received the same error.
Is there a way I can connect to a view in another database in XPiNC? I have found an XSnippet which allows you to dynamically add view data sources to your page, I think this may get around my problem but wanted to find out if there was an alternative solution before I re-write everything!
Try some of these other ways of getting a handle on a database:
This one uses "" instead of the null parameter to indicate current server:
var dbOther:NotesDatabase = session.getDatabase("", doc.getItemValueString("Database"))
This one uses database.getServer() instead of the null parameter:
var dbOther:NotesDatabase = session.getDatabase(database.getServer(), doc.getItemValueString("Database"))
This one uses sessionAsSigner to get access to the database (instead of using the credentials of the current user):
var dbOther:NotesDatabase = sessionAsSigner.getDatabase(database.getServer(), doc.getItemValueString("Database"))
Are you using a Lotus Notes 8.5.3 client?