function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Federico LarsenFederico Larsen 

Retrieve Document

Hi,

i am trying to retrieve a document (text/html) and use its content, but i cant do it yet, this is the code i am using.

Code:
function getHeadHTML(){
    var docs = sforceClient.Retrieve("Body","Document",[_tpl_doc_ID]);
    if (docs != null && docs.length > 0){
     var doc = docs[i];
     var body64 = doc.get("Body");
     var body = decode64(body64.textContent);
     return body;
    }
    else{
     alert("Error.");
    }
    
   }

 

SteveBowerSteveBower
Hi Federico, I've spent a chunk of time figuring out what was wrong with the Ajax toolkit's handling of Documents.  There are actual bugs there that you will run into if you're trying to use Documents.

The upshot of this (and there are other messages on this in the boards as I was trying to figure it out which give sample code, etc.) is that the code in this posting:

 http://forums.sforce.com/sforce/board/message?board.id=general_development&message.id=6336

fixes the document problems and does away with your need to decode the Base64 stuff yourself.  Just take that code and throw it into a script tag after the reference to sforceclient.js.  It overrides the Salesforce provided Sforce.DOM.ParseVal function with a new version with some simple fixes.

My retrieve code now looks like:

Code:
function loadDocument() {
 // Return False if the requested document doesn't exist.  
 // Return the content of the document otherwise.
 var s = "Select id, name, type, body, bodylength, description, authorid from Document where " + 
   "FolderId = '" + folderId + "' and " + 
   "Name = '" + batchName + "'";

 var d = sforceClient.Query(s);
 if (Sforce.Util.dltypeof(d) == "QueryResult" && d.size == 1 ) {
  savedBatchEntry = d.records[0];  // savedBatchEntry is a global
  return savedBatchEntry.get("Body");
 } else {
  //myAlert("Didn't find pre-existing document for " + batchName + " result type = " + Sforce.Util.dltypeof(d));
  return false;
 }
}

 And I think your code would be:

function getHeadHTML(){
var docs = sforceClient.Retrieve("Body","Document",[_tpl_doc_ID]);
if (docs != null && docs.length > 0){
//var doc = docs[0]; // change "i" to "0" ? Unless you have a loop somewhere.
//var body64 = doc.get("Body");
//var body = decode64(body64.textContent);
//return body;
return docs[0].get("Body"); // Not taking into account the possibility of multiple return docs, etc.
}
else{
alert("Error.");
}

}

Hope this helps, Steve Bower.







Federico LarsenFederico Larsen
Thanks a lot!!!

I watch the message borad you told me and I solved my problem.

my function now is like this, since I only have to retrieve one document, specified in the _tpl_doc_ID global constant

Code:
function getHeadHTML(){
    var docs = sforceClient.Retrieve("Body","Document",[_tpl_doc_ID]);
    if (docs != null && docs.length > 0){
     var doc = docs[i];
     var b64 = new Sforce.Util.Base64();
     var body64 = doc.get("Body");
     try{
      var body = b64.decode(body64.textContent);
     }
     catch(ee){
      alert(ee.toString());
     }
     return body;
    }
    else{
     alert("Error.");
    }
    
   }

 


Federico LarsenFederico Larsen
I founded this problem. In firexfox everything is alright, but in IE, textContent property of a base64 object is not defined, but i coud managed that problem, and the second problem is the performance, IE takes the 99% of CPU por 1 munute to process a 21k document, while firefox process it in 1 second.

I attach de code.

Thanks for your comments about this.Code:
function getHeadHTML(){
    var docs = sforceClient.Retrieve("Body","Document",[_tpl_doc_ID]);
    if (docs != null && docs.length > 0){
     var doc = docs[0];
     var b64 = new Sforce.Util.Base64();
     var body64 = doc.get("Body");
     try{
      var content = "";
      if (body64.textContent == null){
       // IE error
       content = body64;
      }
      else{
       content = body64.textContent;
      }
      
      var body = b64.decode(content);
     }
     catch(ee){
      alert(ee.toString());
     }
     return body;
    }
    else{
     alert("Error.");
    }
    
   }

 

ChrisMcLChrisMcL
Slow string concatenation is a known problem in IE. In the decode function, even a small 20K document can cause 40,000 string concatenations. The solution is not to use the "+" sign and use an array join instead. Here is the Sforce code with the fix. It works well in both IE and Firefox.
 
Instead of using the Sforce.Util.Base64() decode function call this function instead. Hopefully Salesforce will implement this fix. The encode function can be changed similarly.
 

function decode(input){

var output = "";

var chr1, chr2, chr3 = "";

var enc1, enc2, enc3, enc4 = "";

var i = 0;

var base64test = /[^A-Za-z0-9\+\/\=]/g;

if (base64test.exec(input)) {

alert("There were invalid base64 characters in the input text.\n" +"Valid base64 characters are A-Z, a-z, 0-9, '+', '/', and '='\n" +"Expect errors in decoding.");

}

input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

var stringBuffer = [];

do {

enc1 = keyStr.indexOf(input.charAt(i++));

enc2 = keyStr.indexOf(input.charAt(i++));

enc3 = keyStr.indexOf(input.charAt(i++));

enc4 = keyStr.indexOf(input.charAt(i++));

chr1 = (enc1 << 2) | (enc2 >> 4);

chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);

chr3 = ((enc3 & 3) << 6) | enc4;

stringBuffer.push(String.fromCharCode(chr1));

if (enc3 != 64) {

stringBuffer.push(String.fromCharCode(chr2));

}

if (enc4 != 64) {

stringBuffer.push(String.fromCharCode(chr3));

}

chr1 = chr2 = chr3 = "";

enc1 = enc2 = enc3 = enc4 = "";

} while (i < input.length);

output = stringBuffer.join("");

return output;

}