You need to sign in to do that
Don't have an account?
Greg H
File Attachment sControl
I need to attach a file to a custom object through an scontrol. I would like to be able to use code similar to the following but the code displayed here does not work. Does anyone have any ideas?
if (frmFile != "") {
var _refAttach = new Sforce.Dynabean("Attachment");
_refAttach.set("Body", frmFile);
var saveAttachment = sforceClient.Create([_refAttach]);
alert("Created ID: " + saveAttachment[0].id);
} else {
alert("Please browse for a file!");
}
The Business Requirement: Create a place within salesforce.com to store customer reference letters and make them searchable based on zip code, SIC Code and specific Employee Ranges. Users should be able to add new reference letters but the reference letters should not be made available to others unless the corporate marketing team has approved the letter and verified all the information around the letter.
All Answers
You need to encode the body as Binary 64 and set the length.
Code: (modified by hand)
Good luck, Steve.
Note, there are bugs in the 3.3 Beta regarding retrieving your data from at attachment or document. You get different behavior depending on the length of the data you've saved (< or > than 2048 bytes). Some of my other posts have a simple fix to sforceclient.js which solves them.
Thanks Steve! I am now able to save an attachment but the actual file is not being attached - only an encoded string. So when I click on the attachment it only displays characters in the browser (i.e. QzpcRG9jdW1lbnRzIGFuZCBTZXR0aW5nc1xnaGFjaWNcRGVza3RvcFxCb29rMS54bHM=)
I wonder if I am requesting the file from the form incorrectly or if I need to provide an file extension on the name of the attachment when I save it (i.e. .pdf)?
My request from the form looks like:
var frmFile = document.form.file.value;
Thanks for your help,
-greg
That was my comment in the code snippet: // I presume FrmFile is the CONTENT of your file.
You need some browser specific code to "break through" the browser/filesystem boundary.
http://www.captain.at/ajax-file-upload.php (for mozilla) gives you an idea of something that you could rip apart to get the content of your file into your client-side script to then send to salesforce through their api.
I'm sure there's something out there for IE as well, but I haven't really needed to do this for any of my projects yet.
One of the other Board contributors posted this awhile ago...
http://forums.sforce.com/sforce/board/message?board.id=ajax_toolkit&message.id=408&query.id=757#M408
but I don't see his code.
Hope this helps, Steve.
P.S. I don't know why you're not seeing the File Name being returned correctly since that's what you are saving as "content". It seems like it's being encoded twice or not decoded, etc. Also, the results of attachment_dynabean.get("Body") are different depending on the length of the body you've stored. (unless you used a modified sforceclient.js file or overrode parseVal.)
try {
// create COM object to get the unencoded string representation of the document
var fn = "C:\yourfile";
var obj = new ActiveXObject("ProgId.ProgId");
var body = obj.FileToString(fn);
// save the attachment
var attachment = new Sforce.Dynabean("Attachment");
attachment.set("ParentId", "YourObjectId");
attachment.set("OwnerId", {!User_ID});
attachment.set("Name", fn);
attachment.set("Body", body);
sforceClient.create([attachment]);
}
catch (ex) {
}
The COM C# code (registered as ProgId.ProgId) I have installed on the client to do the bytestream to char[] looks like this. Using this method may not work for you if you don't want to install client code, but I don't think this is possible in Javascript since Javascript does not support the byte[] object type:
public static String FileToString(string filename) {
try {
FileInfo fi = new FileInfo(filename);
if (!File.Exists(fi.FullName)) return "";
//create temp copy of file
string fn = fi.Name;
string fnDir = fi.DirectoryName;
string fnExt = fi.Extension;
string fnPre = fn.Substring(0, fn.Length - 4);
string fnTmp = fnDir + "\\" + fnPre + "_encoded" + fnExt;
//copy to temp file
FileInfo fiTmp = fi.CopyTo(fnTmp, true);
FileStream fs = new FileStream(fiTmp.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
//read file
byte[] data = new byte[fs.Length];
int nBytesRead = fs.Read(data, 0, (int)fs.Length);
// convert byte[] to char[]
char[] dataChars = new char[fs.Length];
for (int i = 0; i < fs.Length; i++) {
dataChars[i] = (char)(data[i]);
}
if (fs != null) fs.Close();
fiTmp.Delete();
//convert char[] to string
StringBuilder sb = new StringBuilder();
sb.Append(dataChars);
return sb.ToString();
}
catch (Exception ex) {
System.Windows.Forms.MessageBox.Show(ex.Message, "FileToString(FileInfo fi)",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop);
return "";
}
I was able to resolve this problem. Since I had to attach the file using an sControl and I couldn't perform anything on the server-side, I decided to highjack the "add attachments" page (/p/attach/NoteAttach) and redirect the user to a success page (sControl) after the attachment was saved. It was a bit of a pain to figure out but the functionality is ideal for my users. Thanks to all of you for providing feedback on this.
-greg
It's a nice thing to have "in the library".
Thanks, Steve.
The Business Requirement: Create a place within salesforce.com to store customer reference letters and make them searchable based on zip code, SIC Code and specific Employee Ranges. Users should be able to add new reference letters but the reference letters should not be made available to others unless the corporate marketing team has approved the letter and verified all the information around the letter.
<html>
<head>
<title>File Upload</title>
<script language="javascript" src="https://www.salesforce.com/services/lib/ajax/beta3.3/sforceclient.js"
type="text/javascript"></script>
<script>
function pgLoad()
{
try
{
sforceClient.init("{!API_Session_ID}", "{!API_Partner_Server_URL_70}", true);
}
catch (ex)
{
alert(ex.message);
}
}
function UploadFile()
{
var _refAttach = new Sforce.Dynabean("Attachment");
try
{
_refAttach.set("ParentId",<ContactId>);
_refAttach.set("Name","abc.txt");
var b64 = new Sforce.Util.Base64();
var b64data = b64.encode(document.getElementById("frmFile").value); // presuming that this is a variable holding the contents of your file.
_refAttach.set("Body",b64data);
_refAttach.set("BodyLength",b64data.length);
var cr = sforceClient.Create(_refAttach)[0];
if (Sforce.Util.dltypeof(cr) != "SaveResult" ) {
alert("Error creating attachment:" + cr);
}
}
catch (e)
{
alert("Exception creating attachment:" + e);
}
}
</script>
</head>
<body onload = "pgLoad();">
<input type="file" id="frmFile"/>
<input type="submit" value="Upload" onClick="UploadFile();">
</body>
</html>
This is the code which I am using in SControl (replace <ContactId> with id of actual contact in your account)
The above code saves the file with name abc.txt into Attachments Object and associated with the given contact but when i open this file ,
instead of actual text in the uploaded file I see some text string..
Can you modify and resend me the code?It needs to work on IE and FireFox