NotesRichTextItem.getMIMEEntity() always returns null - xpages

I have a notes form with a rich text field on it, called "Body". I've set the "Storage" property of the field to "Store contents as HTML and MIME".
Now, I am creating a new document with that form in the Notes Client.
However, if I try to access the rich text field's value in SSJS with NotesRichTextItem.getMIMEEntity(), it always returns null.
Am I missing something?
Thank you for your help in advance.
Update 2: 02/12/2015
I did some more testing and I found the cause, why it won't recognize the rich text field as MIME Type, but rather always returns it as RICH TEXT:
The cause is me accessing the database with "sessionAsSigner" rather than just using "database".
If I remove "sessionAsSigner" and use "database" instead, making the XPage unavailable to public access users, so, I am forced to log in, the code recognizes it as MIME Type and I can get a handle on NotesMIMEEntity.
Unfortunately, the XPage has to be available to public access users and I have to use sessionAsSigner.
When I open the document properties and I look at the rich text field, I can see that the "Field Flags" are "SIGN SEAL". My guess is, that's why sessionAsSigner doesn't work, but it is just a guess.
Any ideas?
Update 1: 02/12/2015
Here is the code I am using in my SSJS:
var oDBCurrent:NotesDatabase = sessionAsSigner.getDatabase(session.getServerName(), session.getCurrentDatabase().getFilePath());
var oVWMailProfiles:NotesView = oDBCurrent.getView('$vwSYSLookupEmailProfiles');
var oVWPWResetRecipient:NotesView = oDBCurrent.getView('$vwPWPMLookupPWResetNotificationProfiles');
var oDocPWResetRecipient:NotesDocument = null;
var oDocMailProfile:NotesDocument = null;
var oDocMail:NotesDocument = null;
var sServer = session.getServerName();
oDocPWResetRecipient = oVWPWResetRecipient.getDocumentByKey(sServer, true);
oDocMailProfile = oVWMailProfiles.getDocumentByKey('.MailTemplate', true);
oDocMail = oDBCurrent.createDocument();
//Set default fields
oDocMail.replaceItemValue('Form', 'Memo');
oDocMail.replaceItemValue('Subject', oDocMailProfile.getItemValueString('iTxtSubject'));
oDocMail.replaceItemValue('SendTo', oDocPWResetRecipient.getItemValue('iNmesRecipients'))
//Get body text
var oItem:NotesItem = oDocMailProfile.getFirstItem("Body");
var entity:NotesMIMEEntity = oItem.getMIMEEntity();
//Create email body
var tmp = entity.getContentAsText();
//Replace <part2> with part 2 of the password
tmp = #ReplaceSubstring(tmp, "<part2>", sPWPart2);
//Set content of Body field as MIME type
var body = oDocMail.createMIMEEntity();
var stream = session.createStream();
stream.writeText(tmp);
body.setContentFromText(stream, "text/html; charset=iso-8859-1", 0);
//Send email
oDocMail.send();
As I mentioned before, I've also tried:
var oDBCurrent:NotesDatabase = sessionAsSigner.getDatabase(session.getServerName(), session.getCurrentDatabase().getFilePath());
var oVWMailProfiles:NotesView = oDBCurrent.getView('$vwSYSLookupEmailProfiles');
var oVWPWResetRecipient:NotesView = oDBCurrent.getView('$vwPWPMLookupPWResetNotificationProfiles');
var oDocPWResetRecipient:NotesDocument = null;
var oDocMailProfile:NotesDocument = null;
var oDocMail:NotesDocument = null;
var sServer = session.getServerName();
oDocPWResetRecipient = oVWPWResetRecipient.getDocumentByKey(sServer, true);
oDocMailProfile = oVWMailProfiles.getDocumentByKey('.MailTemplate', true);
oDocMail = oDBCurrent.createDocument();
//Set default fields
oDocMail.replaceItemValue('Form', 'Memo');
oDocMail.replaceItemValue('Subject', oDocMailProfile.getItemValueString('iTxtSubject'));
oDocMail.replaceItemValue('SendTo', oDocPWResetRecipient.getItemValue('iNmesRecipients'))
//Get body text
var entity:NotesMIMEEntity = oDocMailProfile.getMIMEEntity('Body');
//Create email body
var tmp = entity.getContentAsText();
//Replace <part2> with part 2 of the password
tmp = #ReplaceSubstring(tmp, "<part2>", sPWPart2);
//Set content of Body field as MIME type
var body = oDocMail.createMIMEEntity();
var stream = session.createStream();
stream.writeText(tmp);
body.setContentFromText(stream, "text/html; charset=iso-8859-1", 0);
//Send email
oDocMail.send();

Try calling sessionAsSigner.setConvertMime(false)

You get the MIMEEntity from the document, not from the Richtext item. See an example here (starting at line 103): https://github.com/zeromancer1972/OSnippets/blob/master/CustomControls/ccSnippets.xsp

You should set the session to not convert MIME to RichText.
Add this at the start of your code.
session.setConvertMime(false);

Related

How to get a list of internal id in netsuite

Is there a proper way to get a list of all internal id in a Netsuite Record?
var record = nlapiLoadRecord('customer', 1249);
var string = JSON.stringify(record);
nlapiLogExecution('DEBUG', 'string ', string );
I can get most of the id using json string but i am looking for a proper way. It prints all the data including internal id. Is there any Api or any other way ?
I actually developed a Chrome extension that displays this information in a convenient pop-up.
I ran into the same issue of nlobjRecord not stringifying properly, and what I ended up doing was manually requesting and parsing the same AJAX page NS uses internally when you call nlapiLoadRecord()
var id = nlapiGetRecordId();
var type = nlapiGetRecordType();
var url = '/app/common/scripting/nlapihandler.nl';
var payload = '<nlapiRequest type="nlapiLoadRecord" id="' + id + '" recordType="' + type + '"/>';
var response = nlapiRequestURL(url, payload);
nlapiLogExecution('debug', response.getBody());
You can have a look at the full source code on GitHub
https://github.com/michoelchaikin/netsuite-field-explorer/
The getAllFields() function will return an array of all field names, standard and custom, for a given record.
var customer = nlapiLoadRecord('customer', 5069);
var fields = customer.getAllFields();
fields.forEach(function(field) {
nlapiLogExecution('debug', field);
})

sending Email with Attachment xpages

this is my sample coding for sending email with attachment. The content of word is not send correctly.
attachment is using "file upload"
// write mail
var setdoc:NotesDocument = database.getProfileDocument("System Setting", "");
var server = setdoc.getItemValueString("MailDBSvr");
var dname = setdoc.getItemValueString("MailDbPath");
var web = setdoc.getItemValueString("InternetAddress");
var maildoc:NotesDocument = database.createDocument();
maildoc.replaceItemValue("Form", "Memo");
maildoc.replaceItemValue("Subject","Test Send Mail");
session.setConvertMime(false);
var stream = session.createStream();
stream.writeText("<html><body>");
stream.writeText("<p>Dear " + "[person]" + ",</p>");
stream.writeText("<p>Attached item is an image of </p>");
stream.writeText("<p> ***THIS IS AN AUTOMATED MESSAGE - PLEASE DO NOT REPLY DIRECTLY TO THIS EMAIL***</p>");
stream.writeText("</body></html>");
var body = maildoc.createMIMEEntity("Body");
var Att= document1.getDocument(true).getFirstItem("Attachment");
maildoc.copyItem(Att,"Body") // try adding an item
body.setContentFromText(stream, "text/html;charset=UTF-8", 1725);
stream.close();
maildoc.closeMIMEEntities(true);
session.setConvertMime(true);
maildoc.replaceItemValue("SendTo","TestUser1#devsvr1.pcs.com.my");
maildoc.send();
The result come out is only the attachment field without any text value inside. I not sure which part of it is wrong.
sample Result screen:
Recommended Mime style
var HTMLMail = function() {
...
}
var mail = new HTMLMail();
mail.setTo("TestUser1#devsvr1.pcs.com.my")
//mail.addFileAttachment(result);
mail.setSubject("Test Send Mail");
mail.addHTML("<h1>Hi!</h1>");
mail.addHTML("<table><tbody><tr><td>contents in a table here</td></tr></tbody></table>");
mail.send();
IBM Notes/Domino has 2 ways to show 'pretty words and pictures'
RichText
MIME
You should only use one or the other, but here you are actually mixing both the different types.
Above, when you copy the Attachment Item, you are actually adding the first 'Body' item, you can see it's type 'RichText'.
Then we you createMimeEntity you are creating the second 'Body' item, and it's type is 'MimePart' (it is probably showing second because the Mime is not applied until CloseMimeEntities)
So now you have 2 Body items with different parts. You are seeing the 'RichText' attachment in Notes because it is first listed item.
What you actually need to do is create the correct multipart mime structure.
If you want a bit more information about mime, I a blog post on my site which explains it a little bit more, including some info about the correct mime structure.
http://camerongregor.com/2016/04/21/webmail-ui-you-must-learn-about-mime/
If you haven't seen it yet there is an XSnippet by Mark Leusink which has a demo of creating a mime email using SSJS. I don't use this myself as I don't use SSJS but it might be useful to you as it should handle most of this mime manipulation for you.
https://openntf.org/XSnippets.nsf/snippet.xsp?id=create-html-mails-in-ssjs-using-mime
My coding with reference using rich-text style :
var setdoc:NotesDocument = database.getProfileDocument("System Setting", "");
var server = setdoc.getItemValueString("MailDBSvr");
var dname = setdoc.getItemValueString("MailDbPath");
var web = setdoc.getItemValueString("InternetAddress");
var maildoc:NotesDocument = database.createDocument();
maildoc.replaceItemValue("Form", "Memo");
maildoc.replaceItemValue("Subject","Test Send Mail");
session.setConvertMime(false);
var stream = session.createStream();
stream.writeText("<html><body>");
stream.writeText("<p>Dear <b>" + "person" + "</b>,</p>");
stream.writeText("<p> ***THIS IS AN AUTOMATED MESSAGE - PLEASE DO NOT REPLY DIRECTLY TO THIS EMAIL***</p>");
stream.writeText("</body></html>");
var tmpDoc:NotesDocument = maildoc.getParentDatabase().createDocument();
var mime:NotesMIMEEntity = tmpDoc.createMIMEEntity("myBody");
var addRt:NotesMIMEEntity = maildoc.getMIMEEntity("addBody");
var Att:NotesRichTextItem = document1.getDocument(true).getFirstItem("Attachment");
if(addRt != null && #Length(addRt.getContentAsText().trim()) > 28) {
stream.writeText('<font size="2" face="sans-serif">'); // Enforce "simiilar" font type/size...
stream.writeText(addRt.getContentAsText());
stream.writeText('</font>');
}
mime.setContentFromText(stream, "text/html", NotesMIMEEntity.ENC_NONE);
var prevMime = session.isConvertMime();
session.setConvertMime(true);
tmpDoc.closeMIMEEntities(true,"myBody");
var rt:NotesRichTextItem = maildoc.getFirstItem("Body");
var body = null;
if (rt != null) {
body = rt.copyItemToDocument(tmpDoc,"Body");
rt.remove();
}
rt = maildoc.createRichTextItem("Body");
var rtMime:NotesRichTextItem = tmpDoc.getFirstItem("myBody");
rt.appendRTItem(rtMime);
if(Att != null) {
if(addRt == null) rt.addNewLine(1);
rt.appendRTItem(Att);
Att.remove();
}
if(body != null) {
rt.addNewLine(2);
rt.appendRTItem(body);
}
if(addRt != null) {
addRt.remove();
addRt.recycle();
}
stream.close();
maildoc.closeMIMEEntities(true);
session.setConvertMime(true);
maildoc.replaceItemValue("SendTo","TestUser1#devsvr1.pcs.com.my");
maildoc.send();

How to set multiple values into a client side people picker

i have a list with a people picker column which takes multiple inputs.I have a form created using content editor web part in which i have a client side people picker how to set multiple values into a client side people picker using jsom
Normally you define client people control in HTML:
<div id="control" title="Users" spclientpeoplepicker="true"></div>
Then you need to initialize it.
To initialize it properly you need to assure that these javascripts files are loaded: autofill.js, clienttemplates.js, clientforms.js, clientpeoplepicker.js
JavaScript set control value code:
Entities are validate automatically with function AddUserKeys
var userField = $("input[id$='ClientPeoplePicker_EditorInput']").get(0); // simplified user control search, real word scenario, first search proper row in your form
var peoplepicker = SPClientPeoplePicker.PickerObjectFromSubElement(userField);
peoplepicker.AddUserKeys("Login1"); // or display name
peoplepicker.AddUserKeys("Login2");
JavaScript init control code:
SP.SOD.loadMultiple(['autofill.js', 'clienttemplates.js', 'clientforms.js', 'clientpeoplepicker.js'], registerControls);
function registerControls() {
initPeoplePicker('control');
}
function initPeoplePicker (id, user) {
// Create a schema to store picker properties, and set the properties.
var schema = {};
schema['PrincipalAccountType'] = 'User'; //,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '311px';
// use code below to init controls with selected user
/*
var users = new Array(1);
var defaultUser = {};
defaultUser.AutoFillDisplayText = user.Value;
defaultUser.AutoFillKey = user.get_loginName();
defaultUser.Description = user.get_email();
defaultUser.DisplayText = user.get_title();
defaultUser.EntityType = "User";
defaultUser.IsResolved = true;
defaultUser.Key = user.get_loginName();
defaultUser.Resolved = true;
users[0] = defaultUser;
*/
// Render and initialize the picker.
// Pass the ID of the DOM element that contains the picker, an array of initial
// PickerEntity objects to set the picker value, and a schema that defines
// picker properties.
SPClientPeoplePicker_InitStandaloneControlWrapper(id, null/*users*/, schema);
}

SharePoint JSOM Parsing values in a hyperlink field

I have a value that looks like "mailto:a#b.com, mailto:a#b.com'. This is basically a hyperlink field and I want to parse this properly using SharePoint JSOM. I tried SP.FieldUrlValue, but it does not seem to have a method that lets you parse.
You can use the .get_url() function on the actual item value to get the hyperlink URL, or the .get_description() function to get the hyperlink's display text.
var linkField = "internalColumnName";
var listName = "List Title";
var clientContext = new SP.ClientContext();
var list = clientContext.get_web().get_lists().getByTitle(listName);
var camlQuery = new SP.CamlQuery();
var items = list.getItems(camlQuery);
clientContext.load(items);
clientContext.executeQueryAsync(Function.createDelegate(this,function(){
var itemEnumerator = items.getEnumerator();
while(itemEnumerator.moveNext()){
var item = itemEnumerator.get_current();
var url = item.get_item(linkField).get_url(); // <-- Get URL
var text = item.get_item(linkField).get_description(); // <-- Get Text
alert(url + ", " + text);
}
}),Function.createDelegate(this,function(sender, args){alert(args.get_message());}));

Xpages java script server side does not update the field in form

case : Update field after select the customer name:
setting : 1 setting view that consist of database path :
DbServer: ServerOne/pcs
Directory: office
Database name : Customer.nsf
this xpages have a datasource inside, it call "document1"
// get the database path :
var vw3:NotesView=database.getView("Setting Path");
var doc3:NotesDocument=vw3.getFirstDocument();
var server:string = doc3.getItemValueString("DbServer");
var DName:string=doc3.getItemValueString("DbName");
var Directory:string=doc3.getItemValueString("Directory");
var DBName:string= Directory+"\\" +DName;
var db:NotesDatabase = session.getDatabase(server, DBName, false);
var vw:NotesView = db.getView("All Customer");
var doc:NotesDocument=vw.getDocumentByKey(document1.getValue("Customer"),true);
if (doc !=null) {
document1.setValue("Contact", doc.getItemValueString("Contact"));
document1.setValue("Telephone", doc.getItemValueString("Phone"));
document1.setValue("Fax", doc.getItemValueString("Fax"));
document1.setValue("Email", doc.getItemValueString("Email"));
}
Problem :
The field doesn't update and get the value from "customer" database.
I see a series of problems in your code:
Bind your input field to a scope variable, not to the document itself. It is a search string in the beginning, not part of the new document.
You don't check for the case that the customer wasn't found, so you never know if that was the issue.
I would rather use an URL and resolve instead of server / path / database (but that's a little style
So something like (typed off my head, will contain typos):
var vw3:NotesView=database.getView("Setting Path");
var vwe3 = vw3.getFirstEntry();
var db = session.resolve(vwe.entries[0]);
var vw:NotesView = db.getView("All Customer");
var doc:NotesDocument=vw.getDocumentByKey(viewScope.customer,true);
if (doc !=null) {
viewScope.result = doc.getUniversalID();
document1.setValue("Contact", doc.getItemValueString("Contact"));
document1.setValue("Telephone", doc.getItemValueString("Phone"));
document1.setValue("Fax", doc.getItemValueString("Fax"));
document1.setValue("Email", doc.getItemValueString("Email"));
doc.recycle()l
} else {
viewScope.result = "Not found!";
}
// ADD recycle() calls here!!!
Bind a display only field to viewScope.result, so you have a better idea what is happening. Your view must be sorted and indexed by customer name.
Of course you could use the OpenNTF dialog list control instead.

Resources