I have the gotten a certain result from the Notes tab.
The link you see inside the iframe is the name of the file.
I have the DocumentBody from the annotation in some format that looks like base64.
How do I download it?
Thanks,
Fabio
Perform a JQuery request to a URL like this
Xrm.Page.context.getServerUrl() + "XRMServices/2011/OrganizationData.svc/ActivityMimeAttachmentSet(guid'abc...')?$select=Body"
By specifying the select you will request only what you want.
Assign the result to a variable and prepend
data:application/pdf;base64,
From there you could display it inline as an HTML object or try to open it as a new window with
window.location or window.open or document.location.href
I had already the base64 documentbody string extracted like this:
function getSla() {
// Define SOAP message
var objectId;
if (typeof crmForm === "undefined") {
objectId = parent.crmForm.ObjectId;
}
else {
objectId = crmForm.ObjectId;
}
var xml =
[
"<?xml version='1.0' encoding='utf-8'?>",
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ",
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ",
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">",
GenerateAuthenticationHeader(),
"<soap:Body>",
"<RetrieveMultiple xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>",
"<query xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' ",
"xsi:type='q1:QueryExpression'>",
"<q1:EntityName>annotation</q1:EntityName>",
"<q1:ColumnSet xsi:type='q1:AllColumns' />",
"<q1:Distinct>false</q1:Distinct><q1:Criteria><q1:FilterOperator>And</q1:FilterOperator>",
"<q1:Conditions><q1:Condition><q1:AttributeName>objectid</q1:AttributeName><q1:Operator>Equal</q1:Operator>",
"<q1:Values><q1:Value xsi:type=\"xsd:string\">",
objectId,
"</q1:Value></q1:Values></q1:Condition></q1:Conditions></q1:Criteria>",
"</query>",
"</RetrieveMultiple>",
"</soap:Body>",
"</soap:Envelope>"
].join("");
var resultXml = executeSoapRequest("RetrieveMultiple", xml);
var result = filter(resultXml.getElementsByTagName("q1:filename"), function (element) {
return /master.*sla/i.test(element.text);
});
if (result.length == 0) {
return null;
}
else {
return result[0].parentNode;
}
}
function getSlaDocumentBody(sla) {
return sla.getElementsByTagName("q1:documentbody")[0].text;
}
window.open("data:application/pdf;base64," + getSlaDocumentBody(sla));
It opened a new window with the string data:application/pdf.......... in the address bar but did nothing. I would prefer that solution indeed.
Ended up using srasmussen solution in here: http://social.microsoft.com/Forums/en/crm/thread/05134277-dd76-4fbb-8f6e-89b1a2a45af1.
var URL = serverUrl + "/userdefined/edit.aspx?etc=5&id=" + slaId;
$.get(URL, function (data) {
var WRPCTokenElement = $(data).find("[WRPCTokenUrl]");
if (WRPCTokenElement) {
var WRPCTokenUrl = WRPCTokenElement.attr("WRPCTokenUrl");
if (WRPCTokenUrl) {
URL = "/Activities/Attachment/download.aspx?AttachmentType=5&AttachmentId=" + slaId + "&IsNotesTabAttachment=undefined" + WRPCTokenUrl;
window.open(URL);
}
}
return false;
});
Related
I am using the formatter:"link" url callback to generate a hyperlink for a certain column in my Tabulator table
tabulatorTable.addColumn({
title: "Value",
field: "JSONDoc.Path.To.Property",
formatter: "link",
formatterParams: {
url: getHyperLink,
target: "_blank"
}
});
Then in my callback function:
function getHyperLink(cellComp) {
var cellData = cellComp.getData();
var propValFromJSONSource = cellData.SomeProperty;
if( propValFromJSONSource != 0) {
return "http://hostname/report/showLog.php?prop=" + propValFromJSONSource;
}
else {
// If here, I can't generate a valid link, so I want to not have a hyperlink and just show the data
return ???;
}
}
Is there anything that I can do in the else statement to return from the formatter to instruct Tabulator to not create a hyperlink?
I've tried:
return ""; // This makes the hyperlink go to "<currentURL>"
return null; // This generates a relative hyperlink to "<currentURL>/null"
return undefined; // This generates a relative hyperlink to "<currentURL>/undefined"
I suspect I might not be able to use the link formatter and will need to switch to a custom formatter callback that returns "
I also have the problem of not being able to left-click on the hyperlink (even though it appears correctly down in the status bar); I can only center click or right-click and choose "Open in new tab". I'm not sure if this a bug within Tabulator, or Chrome not understanding it for some reason, but that shall be another SO question...
For now, I'm recommending the use of a custom formatter:
tabulatorTable.addColumn({
title: "Value",
field: "JSONDoc.Path.To.Property",
formatter: getHyperLink,
});
Then have the callback return the html code for a hyperlink or just text:
function getHyperLink(cellComp, formatterParams, onRendered) {
var cellData = cellComp.getData();
var cellValue = cellComp.getValue();
var propValFromJSONSource = cellData.SomeProperty;
if( propValFromJSONSource != 0) {
var hrefString = "http://hostname/report/showLog.php?prop=" + propValFromJSONSource;
return "<a href='" + hrefString + "' target='_blank'>" + cellValue + "</a>";
}
else {
return cellValue;
}
}
I'm trying to create a central function for dynamic web requests.
function makeWebRequest(remoteURL, requestString, callBackFunction) {
var myWebRequest = new SMF.Net.WebClient({
url : remoteURL,
httpMethod : "POST",
requestString : requestString,
requestHeaders : [
"Content-Type: application/x-www-form-urlencoded"],
onSyndicationSuccess : callBackFunction,
onServerError : function (e) {
alert(e);
}
});
myWebRequest.run(false);
}
While calling makeWebRequest, passing a callBackFunction to it like;
var remoteURL = "http://parse.com/12/test";
var requestString = "category=news&type=world";
function callBackFunction(e) {
responseText = this.responseText;
if (responseText != null) {
parsedJSON = JSON.parse(responseText);
}
}
makeWebRequest(remoteURL,requestString,callBackFunction);
Application raises an error at line
responseText = this.responseText;
How can I pass myWebRequest itself to a function like that?
I used your codeLines. I just add a textButton to Page1, and it works fine both for Android and iOS .
In Global.js;
function makeWebRequest(remoteURL, requestString, callBackFunction) {
var myWebRequest = new SMF.Net.WebClient({
url : remoteURL,
httpMethod : "POST",
requestString : requestString,
requestHeaders : [
"Content-Type: application/x-www-form-urlencoded"],
onSyndicationSuccess : callBackFunction,
onServerError : function (e) {
alert(e);
}
});
myWebRequest.run(false);
}
var remoteURL = "http://parse.com/12/test";
var requestString = "category=news&type=world";
function callBackFunction(e) {
var responseText = this.responseText;
alert(responseText);
if (responseText != null) {
parsedJSON = JSON.parse(responseText);
}
}
function Global_Events_OnStart(e) {
changeLang(Device.language, true);
include("BC.js"); //included for future BC support. Removing is not advised.
// Comment following block for navigationbar/actionbar sample. Read the JS code file for usage.
// Also there is a part of code block in Page1, which should be copied to every page for HeaderBar usage
load("HeaderBar.js");
header = new HeaderBar();
// Uncomment following block for menu sample. Read the JS code file for usage.
/*
load("Menu.js");
/**/
}
function Global_Events_OnError(e) {
switch (e.type) {
case "Server Error":
case "Size Overflow":
alert(lang.networkError);
break;
default:
SES.Analytics.eventLog("error", JSON.stringify(e));
//change the following code for desired generic error messsage
alert({
title : lang.applicationError,
message : e.message + "\n\n*" + e.sourceURL + "\n*" + e.line + "\n*" + e.stack
});
break;
}
}
In Page1.js;
function Page1_Self_OnKeyPress(e) {
if (e.keyCode === 4) {
Application.exit();
}
}
function Page1_Self_OnShow() {
//Comment following block for removing navigationbar/actionbar sample
//Copy this code block to every page onShow
header.init(this);
header.setTitle("Page1");
header.setRightItem("RItem");
header.setLeftItem();
/**/
}
function Page1_TextButton1_OnPressed(e){
makeWebRequest(remoteURL,requestString,callBackFunction);
}
it works fine. Check your makeWebRequest function, must be on Global.js. Also define "responseText" variable with "var".
I'm working on an Archiving Application with this code in it:
var arcName:String = "Archives/" + aDBName + "-Backup-" + toDay + "-" + thisTime.slice(0,5);
var server:String = appDB.getServer();
var arcDB:NotesDatabase = appDB.createCopy(server, arcName);
arcDB.setTitle("This is a Test");
but it fails at the arcDB.setTitle - the new copy of the Database is created so there is no issue to that point.
This is from the IBM Knowledge base:
var db2:NotesDatabase = db.createCopy(null, "names2");
db2.setTitle("Copy of names");
I can't see the difference between these two pieces of code.
Am I missing something?
Usually when something doesn't work with XPages that relates to database or design objects the first thing I check is the Maximum Internet Name and password Access https://stackoverflow.com/a/23045860/1187943
Or change so I do the work using sessionAsSigner or sessionAsSignerWithFullAccess
If you don't care about the effectiveUser's access to the source database, their permissions to make a copy, and their access rights to create a NotesDatabase on the target Domino server, I'd absolutely second Fredrik's suggestion to use sessionAsSigner/WithFullAccess.
Additionally, I find it's best practice to use try/catches (helps with troubleshooting and errorHandling), object testing (.isOpen() when accessing a NotesDatabase), and returning an Object that can be read by the calling function.
Here's some example code that might help:
var copyNotesDatabase = function(dbName) {
var isSuccessful = true;
var responseMessage = "";
try {
//set appDB using dbName from function arguments
var appDB = session.getDatabase(session.getServerName(),dbName);
//var appDB = sessionAsSigner.getDatabase(session.getServerName(),"sourceDb.nsf");
//var appDB = sessionAsSignerWithFullAccess.getDatabase(session.getServerName(),"sourceDb.nsf");
if(appDB.isOpen()) {
var arcName:String = "Archives/" + aDBName + "-Backup-" + toDay + "-" + thisTime.slice(0,5);
var server:String = appDB.getServer();
//arcDB will be created based on appDB permissions, ie effectiveUser, or sessionAsSigner, etc.
var arcDB:NotesDatabase = appDB.createCopy(server, arcName);
if(arcDB.isOpen()) {
arcDB.setTitle("This is a Test");
responseMessage = "Successfully copied NotesDatabase!"
} else {
isSuccessful = false;
responseMessage = "Unable to open copied NotesDatabase.";
}
} else {
isSuccessful = false;
responseMessage = "Unable to open source NotesDatabase.";
}
} catch(e) {
print("Error from SSJS: " + e);
isSuccessful = false;
responseMessage = e;
}
return { status : isSuccessful, message : responseMessage };
}
With this function, you could do something like this:
function makeCopy(appName) {
var fObj = copyNotesDatabase(appName);
if(fObj.status) {
return "Successfully copied " + appName;
} else {
return fObj.message;
}
}
... at the very least, using a try/catch and returning your error will at least tell you why your current code isn't working. Hope this helps!
function clickButtonHandler(event:MouseEvent):void
{
var message:Object = new Object();
message.text = txtMessage.text;
message.userName = txtUser.text;
//Posts to this swf
showMessage(message);
//Posts to ALL OTHER swf files..
group.post(message);
}
function showMessage(message:Object):void
{
output_txt.appendText(message.userName+": "+message.text + "\n");
}
function jsalertwindow(event:MouseEvent):void
{
var alert:URLRequest = new URLRequest("javascript:alert('Please enter your User name')");
navigateToURL(alert, "_self");
}
As you can see there are two function which are contain mouseevent. I want to send those function with an if-else statement. If user write something in text input component which name is txtUser and,
send_btn.addEventListener(MouseEvent.CLICK, clickButtonHandler);
will work, else(if the user forget writing anything)
send_btn.addEventListener(MouseEvent.CLICK, jsalertwindow);
will work.
And one more question should i use MouseEvent.CLICK or MouseEvent.MOUSE_DOWN? Thanks for your advice.
Assign a single handler to the button click (MouseEvent.CLICK is the right event to use) and check the field is populated in the handler:
function clickButtonHandler(event:MouseEvent):void
{
var message:Object = new Object();
// Check the field is populated
if (txtUser.text != "")
{
message.text = txtMessage.text;
message.userName = txtUser.text;
showMessage(message);
//Posts to ALL OTHER swf files..
group.post(message);
}
else
{
// Nothing in the input field, show the alert
showAlert();
}
}
function showMessage(message:Object):void
{
output_txt.appendText(message.userName+": "+message.text + "\n");
}
function showAlert():void
{
var alert:URLRequest = new URLRequest("javascript:alert('Please enter your User name')");
navigateToURL(alert, "_self");
}
I'm trying to enter a notes document by using the getDocumentByUNID function. Running the following code snipped outputs an error:
var unid = (function() {
for (var x in e.row.children) {
if (e.row.children[x].content == "id") {
return e.row.children[x].text;
}
}
})();
if (!unid) {
YN.exception("Function displayGeraet: Document ID could not be found!");
} else {
var Geraete_db = app.notes_db_geraete;
YN.log("Unid: "+unid); //Output: Unid: 22EC92ED5AF33138C1257BA30053E753
YN.log("URL: "+Geraete_db.baseURL); //Output: URL: http://MT04.wd.isernhagen/HKMT/Ticket/Geraete.nsf
var Geraete_doc = Geraete_db.getDocumentbyUNID(unid); //EXCEPTION: openGeraet, TypeError: 'undefined' is not a function (evaluating 'db.getDocumentbyUNID(unid)')
Any suggestions what I'm missing?
do you have "Geraete_db.getDocumentByUNID(unid)" with "By" in uppercase or with lower case as in your code sample?
It should be getDocumentByUNID().