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
MsKnightMsKnight 

Apex Button - Enhanced List View Error

Before the Summer '08 release we created a custom list button that executes Javascript and calls an Apex class. It was working perfectly until we turned on the enhanced list view. Below is the code and the error:


Code:
{!REQUIRESCRIPT("/soap/ajax/11.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/11.0/apex.js")}

var errnum = 0;
var errmsg = "";

var idArray = {!GETRECORDIDS($ObjectType.SFDC_Purchase_Requisition__c)};

if (idArray[0] != null) {
var records = sforce.connection.retrieve("Name,Purchase_Order__c", "SFDC_Purchase_Requisition__c", [idArray]);
if (records.length > 0) {
for (var i = 0; i < records.length; i++) {
if (records[i].SFDC_Purchase_Order__c != null) {
errnum++;
errmsg += records[i].Name + "\n";
}
}
if (errnum == 0) {
var result = sforce.apex.execute("POButton", "createPO", {
reqsId: idArray
});
alert("PO Created!");
window.parent.location.href = "/" + result[0];
}
else {
alert("A PO already exists for: \n" + errmsg);
}
}
}
else {
alert("Please select at least one record.");
}

 
Code:
{faultcode:'sf:MALFORMED_ID', faultstring:'MALFORMED_ID: bad id function (B){
 var A = this.indexOf(B);
 if(A != -1) {
    this.splice(A,1);
 }
 return this;
}

 
I have narrowed it down to the point where it tries to retrieve the Name and Purchase_Order__c from the records. I haven't been able to find any documentation on this function changing. Any thoughts?

Thanks!






Message Edited by MsKnight on 06-16-2008 03:57 PM
Ron HessRon Hess
I've seen this before

some javascript libraries override or extend the array object

ajax.js does not know this has occured and skips a check for function when seralizing the array

the following does check

Code:
// needed to override so that we will not seralize functions, otherwise is same same
sforce.Connection.prototype.writeOne = function (writer, name, value, sobjectNs) {

   if (typeof(value) === 'function') { return ; } 
    if (value === null) {
        writer.writeNameValueNode(name, null);
    } else if (value.toXml) {
        value.toXml(sobjectNs, name, writer);
    } else {
        writer.writeNameValueNode(name, value);
    }
}

 

you must add this after you include ajax.js

note the check for typeof() == function

this avoids seralizing a function that is attached to the idArray

so the complete code should look something like this


Code:
{!REQUIRESCRIPT("/soap/ajax/11.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/11.0/apex.js")}

// needed to override so that we will not seralize functions, otherwise is same as ajax.js
sforce.Connection.prototype.writeOne = function (writer, name, value, sobjectNs) {

    if (typeof(value) === 'function') { return ; } 
if (value === null) { writer.writeNameValueNode(name, null); } else if (value.toXml) { value.toXml(sobjectNs, name, writer); } else { writer.writeNameValueNode(name, value); } } var errnum = 0; var errmsg = ""; var idArray = {!GETRECORDIDS($ObjectType.SFDC_Purchase_Requisition__c)}; if (idArray[0] != null) { var records = sforce.connection.retrieve("Name,Purchase_Order__c", "SFDC_Purchase_Requisition__c", [idArray]); if (records.length > 0) { for (var i = 0; i < records.length; i++) { if (records[i].SFDC_Purchase_Order__c != null) { errnum++; errmsg += records[i].Name + "\n"; } } if (errnum == 0) { var result = sforce.apex.execute("POButton", "createPO", { reqsId: idArray }); alert("PO Created!"); window.parent.location.href = "/" + result[0]; } else { alert("A PO already exists for: \n" + errmsg); } } } else { alert("Please select at least one record."); }

 



Message Edited by Ron Hess on 06-16-2008 08:39 PM
MsKnightMsKnight
Hi Ron,

I added the code you suggested to the button and I still receive this error:

Code:
{faultcode:'sf:MALFORMED_ID', faultstring:'MALFORMED_ID: bad id function (B){
 var A = this.indexOf(B);
 if(A != -1) {
    this.splice(A,1);
 }
 return this;
}', detail:{InvalidIdFault:{exceptionCode:'MALFORMED_ID', exceptionMessage:'bad id function (B) {
 var A = this.indexOf(B);
 if(A != -1) {
    this.splice(A,1);
 }
 return this;
}',},},}

 Any thoughts?


Thanks!

Ron HessRon Hess
Yes, one more thing to add, forgot to mention this one is needed along with the other snippet, clearly the toolkit is still sending the body of a function inside the soap message, which is not cool...

Code:
/*
 * custom version of this to avoid serializing functions
 */ 
sforce.internal.Parameter = function (n, v, a) {
 if(typeof(v)==="object" ) {  
  if (v.name) n = v.name;
  if (v.value) v = v.value;
 } 
 this.name = n;
 this.value = v;
 this.isArray = a;
};

 


again, this must be after the library is included, and before it is used.
MsKnightMsKnight
Hi Ron,

After much digging around, we figured out that it was simply an issue with how it was seeing the array. To fix it, we changed the code from:
Code:
var records = sforce.connection.retrieve("Name,Purchase_Order__c", "SFDC_Purchase_Requisition__c", [idArray]);

 to:

Code:
var records = sforce.connection.retrieve("Name,Purchase_Order__c", "SFDC_Purchase_Requisition__c", idArray);


That seemed to clear it up.


Thanks for all of your help!

- J Knight