You need to sign in to do that
Don't have an account?
The_Fox
Resusable query and delete function in JS
Hello
Feel free to improve it and then share it with everybody
Please replace [ and ] where you normally should have < and > (that is on html or xml tags
Code guys
[!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"]
[html]
[head]
[title][/title]
[script language="JavaScript"]
[!--
var sessionid = "{!API_Session_ID}";
var apiServer = "{!API_Enterprise_Server_URL_50}";
var SoapHeader = "[?xml version=\"1.0\" encoding=\"UTF-8\"?]";
SoapHeader += "[soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"]";
SoapHeader += "[soapenv:Header]";
SoapHeader += "[ns1:SessionHeader soapenv:mustUnderstand=\"0\" xmlns:ns1=\"urn:enterprise.soap.sforce.com\"]";
SoapHeader += "[ns2:sessionId xmlns:ns2=\"urn:enterprise.soap.sforce.com\"]" + sessionid + "[/ns2:sessionId]";
SoapHeader += "[/ns1:SessionHeader]";
SoapHeader += "[/soapenv:Header]";
SoapHeader += "[soapenv:Body]";
var SoapFooter = "[/soapenv:Body]";
SoapFooter += "[/soapenv:Envelope]";
var agt = navigator.userAgent.toLowerCase();
var is_gecko = (agt.indexOf('gecko') != -1);
var is_ie = (agt.indexOf("msie") != -1);
// This will be a double dimension array of objects called Record (Record could be seen has a salesforce object)
var Results = new Array();
//here I create the XML Http Request
if (is_ie){
var xmlReq = new ActiveXObject("Microsoft.XMLHTTP");}
else { var xmlReq = new XMLHttpRequest(); }
//here I create the salesforce object with only id as property for the moment
function Record()
{
this.Id = '';
}
//You have to send an array of Ids to this function and the objects are deleted provided you have the right to do so
function deleteId(ids)
{
var delCommand = SoapHeader;
delCommand += "[delete xmlns=\"urn:enterprise.soap.sforce.com\"]";
for (var j=0;j {
delCommand += "[ids]" + ids[j] + "[/ids]";
}
delCommand += "[/delete]";
delCommand += SoapFooter;
xmlReq.open("POST", apiServer, false);
xmlReq.setRequestHeader("Content-Type","text/xml");
xmlReq.setRequestHeader("SOAPaction","delete");
xmlReq.send(delCommand);
}
/*Here you have a standard query in javascript
you have to pass the queryname as a String
fields as an Array of the field you want in your Select
sfoject as a String representing the Salesforce Object
whereclause as a string with your clause already built (without the where)*/
function query(qryname, fields,sfobject,whereclause)
{
var fieldstring = "";
for (var j=0;j if (fieldstring == "") {fieldstring = fields[j] ;}
else {fieldstring += "," + fields[j];};
}
var queryCommand = SoapHeader;
queryCommand += "[query xmlns=\"urn:enterprise.soap.sforce.com\"]";
if (whereclause=="") {
queryCommand += "[queryString]Select " + fieldstring + " from " + sfobject + "[/queryString]";
}
else {
queryCommand += "[queryString]Select " + fieldstring + " from " + sfobject + " where " + whereclause + "[/queryString]";
}
queryCommand += "[/query]";
queryCommand += SoapFooter;
xmlReq.open("POST", apiServer, false);
xmlReq.setRequestHeader("Content-Type","text/xml");
xmlReq.setRequestHeader("SOAPaction","query");
xmlReq.send(queryCommand);
// here I am going to the root element
var xmlDoc = xmlReq.responseXML.documentElement;
// I am going to the parent of the results
var objNodeList = xmlDoc.getElementsByTagName("records");
var sfid = "";
for (var j=0;j for (var k =0;k if (is_ie) {
var field = objNodeList.item(j).childNodes.item(k).text;}
else {
if (objNodeList.item(j).childNodes.item(k).childNodes.length>0)
{var field = objNodeList.item(j).childNodes.item(k).firstChild.nodeValue;}
}
switch(objNodeList.item(j).childNodes.item(k).nodeName)
{
case "sf:Id":
// Here I create a new object and the array Results[qryname] get a new entry each time an id is discovered
Results[qryname][field] = new Record;
for (var x=1;x Results[qryname][field][fields[x]]=''; //here I extend the properties of the ojbect record with all the fields
}
Results[qryname][field].Id = field;
sfid = field;
break;
default :
if (objNodeList.item(j).childNodes.item(k).nodeName.substring(0,3) == 'sf:') {
node = objNodeList.item(j).childNodes.item(k).nodeName.substring(3,objNodeList.item(j).childNodes.item(k).nodeName.length);
Results[qryname][sfid][node]= field; //here I fill the properties with the matching values coming from salesforce.com
}
break;
}
}
}
}
var fld = new Array();
// exemple for Account object: I create an array Results['Account'] to store the results send by my query on Account
Results['Account'] = new Array();
// here I create the field list
//IMPORTANT: Please always include the Id Field
fld = ['Id','Name','Site'];
//Here I am constructing my clause (AccountId here is a variable)
clause = "Id = '" + AccountId + "'";
//here I am making my query
query('Account',fld,'Account', clause);
var AcctInfo = "";
//I browse through my results
for (var x in Results['Account'])
{
AcctInfo += Results['Account'][x].Name + " " + Results['Account'][x].Site;
}
/*
In fact with this snippet and the construction of the multidimensionnal array Results you can store all the results of you query so that you can retrieve them later on in th code.
*/
// here an example of the combined use of delete and query function
var deleteids = new Array();
Results['Task'] = new Array;
clause = "WhoId='00320000002Ece0'";
fld = ['Id'];
query('Task',fld,'Task',clause);
var j=0;
for (var x in Results['Task'])
{
deleteids [j] = Results['Task'][x].Id;
j++;
}
deleteId(deleteids);
[/script]
[/body]
[/html]
Feel free to improve it and then share it with everybody
Please replace [ and ] where you normally should have < and > (that is on html or xml tags
Code guys
[!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"]
[html]
[head]
[title][/title]
[script language="JavaScript"]
[!--
var sessionid = "{!API_Session_ID}";
var apiServer = "{!API_Enterprise_Server_URL_50}";
var SoapHeader = "[?xml version=\"1.0\" encoding=\"UTF-8\"?]";
SoapHeader += "[soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"]";
SoapHeader += "[soapenv:Header]";
SoapHeader += "[ns1:SessionHeader soapenv:mustUnderstand=\"0\" xmlns:ns1=\"urn:enterprise.soap.sforce.com\"]";
SoapHeader += "[ns2:sessionId xmlns:ns2=\"urn:enterprise.soap.sforce.com\"]" + sessionid + "[/ns2:sessionId]";
SoapHeader += "[/ns1:SessionHeader]";
SoapHeader += "[/soapenv:Header]";
SoapHeader += "[soapenv:Body]";
var SoapFooter = "[/soapenv:Body]";
SoapFooter += "[/soapenv:Envelope]";
var agt = navigator.userAgent.toLowerCase();
var is_gecko = (agt.indexOf('gecko') != -1);
var is_ie = (agt.indexOf("msie") != -1);
// This will be a double dimension array of objects called Record (Record could be seen has a salesforce object)
var Results = new Array();
//here I create the XML Http Request
if (is_ie){
var xmlReq = new ActiveXObject("Microsoft.XMLHTTP");}
else { var xmlReq = new XMLHttpRequest(); }
//here I create the salesforce object with only id as property for the moment
function Record()
{
this.Id = '';
}
//You have to send an array of Ids to this function and the objects are deleted provided you have the right to do so
function deleteId(ids)
{
var delCommand = SoapHeader;
delCommand += "[delete xmlns=\"urn:enterprise.soap.sforce.com\"]";
for (var j=0;j {
delCommand += "[ids]" + ids[j] + "[/ids]";
}
delCommand += "[/delete]";
delCommand += SoapFooter;
xmlReq.open("POST", apiServer, false);
xmlReq.setRequestHeader("Content-Type","text/xml");
xmlReq.setRequestHeader("SOAPaction","delete");
xmlReq.send(delCommand);
}
/*Here you have a standard query in javascript
you have to pass the queryname as a String
fields as an Array of the field you want in your Select
sfoject as a String representing the Salesforce Object
whereclause as a string with your clause already built (without the where)*/
function query(qryname, fields,sfobject,whereclause)
{
var fieldstring = "";
for (var j=0;j if (fieldstring == "") {fieldstring = fields[j] ;}
else {fieldstring += "," + fields[j];};
}
var queryCommand = SoapHeader;
queryCommand += "[query xmlns=\"urn:enterprise.soap.sforce.com\"]";
if (whereclause=="") {
queryCommand += "[queryString]Select " + fieldstring + " from " + sfobject + "[/queryString]";
}
else {
queryCommand += "[queryString]Select " + fieldstring + " from " + sfobject + " where " + whereclause + "[/queryString]";
}
queryCommand += "[/query]";
queryCommand += SoapFooter;
xmlReq.open("POST", apiServer, false);
xmlReq.setRequestHeader("Content-Type","text/xml");
xmlReq.setRequestHeader("SOAPaction","query");
xmlReq.send(queryCommand);
// here I am going to the root element
var xmlDoc = xmlReq.responseXML.documentElement;
// I am going to the parent of the results
var objNodeList = xmlDoc.getElementsByTagName("records");
var sfid = "";
for (var j=0;j for (var k =0;k if (is_ie) {
var field = objNodeList.item(j).childNodes.item(k).text;}
else {
if (objNodeList.item(j).childNodes.item(k).childNodes.length>0)
{var field = objNodeList.item(j).childNodes.item(k).firstChild.nodeValue;}
}
switch(objNodeList.item(j).childNodes.item(k).nodeName)
{
case "sf:Id":
// Here I create a new object and the array Results[qryname] get a new entry each time an id is discovered
Results[qryname][field] = new Record;
for (var x=1;x Results[qryname][field][fields[x]]=''; //here I extend the properties of the ojbect record with all the fields
}
Results[qryname][field].Id = field;
sfid = field;
break;
default :
if (objNodeList.item(j).childNodes.item(k).nodeName.substring(0,3) == 'sf:') {
node = objNodeList.item(j).childNodes.item(k).nodeName.substring(3,objNodeList.item(j).childNodes.item(k).nodeName.length);
Results[qryname][sfid][node]= field; //here I fill the properties with the matching values coming from salesforce.com
}
break;
}
}
}
}
var fld = new Array();
// exemple for Account object: I create an array Results['Account'] to store the results send by my query on Account
Results['Account'] = new Array();
// here I create the field list
//IMPORTANT: Please always include the Id Field
fld = ['Id','Name','Site'];
//Here I am constructing my clause (AccountId here is a variable)
clause = "Id = '" + AccountId + "'";
//here I am making my query
query('Account',fld,'Account', clause);
var AcctInfo = "";
//I browse through my results
for (var x in Results['Account'])
{
AcctInfo += Results['Account'][x].Name + " " + Results['Account'][x].Site;
}
/*
In fact with this snippet and the construction of the multidimensionnal array Results you can store all the results of you query so that you can retrieve them later on in th code.
*/
// here an example of the combined use of delete and query function
var deleteids = new Array();
Results['Task'] = new Array;
clause = "WhoId='00320000002Ece0'";
fld = ['Id'];
query('Task',fld,'Task',clause);
var j=0;
for (var x in Results['Task'])
{
deleteids [j] = Results['Task'][x].Id;
j++;
}
deleteId(deleteids);
[/script]
[/body]
[/html]
We need the retrieve as well and dealing with responseXMl with faulty message just in case. I think (thanks to henry Hess) I should separate and have something like query and getqueryresults or even more broader application a get results. I will try to work on this one but I have little time to do so.
Regards
How about interacting with sforce like this in JS:
function doit() {
if (window.XMLHttpRequest) {
//Need to do some security stuff for Mozilla
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
}
//Do a login call
var loggedInOk = doLogin(document.log.usern.value, document.log.pwrd.value);
if ( loggedInOk ) {
var msg = document.getElementById("content");
msg.style.visibility = "visible";
var soql = prompt("Enter a SOQL statement:", "not");
if (soql != "not") {
//Execute a query of the user's choosing.
var records = doQuery(soql);
//The DynaBeans returned have a html output method
for (var i=0;i msg.innerHTML = msg.innerHTML + records[i].toHTMLString();
}
msg.innerHTML = msg.innerHTML + "****************************************************************<BR><BR>";
//To access the beans individually and use the properties
for (var i=0;i //write out a record number
msg.innerHTML = msg.innerHTML + "Record: " + (i + 1).toString() + "<BR>";
var spacer = " ";
// get a bean
var bean = records[i];
//get the properties
var props = bean.getProperties();
//Iterate the keys of the properties hash
for (key in props) {
//get a prop
var prop = bean.getProperty(key);
//get a value
var val = prop.getValue();
//get the name of the prop
var name = prop.getName();
//Spit out some results
msg.innerHTML = msg.innerHTML + spacer + "propName = " + name + ", value is: " + val + "<BR>";
}
}
}
if (confirm("Do you want to create 2 contacts?")) {
var contact = new Array();
contact[0] = new DynaBean("Contact");
contact[0].setProperty("FirstName", "Dave");
contact[0].setProperty("LastName", "Carroll");
contact[1] = new DynaBean("Contact");
contact[1].setProperty("FirstName", "Dave2");
contact[1].setProperty("LastName", "Carroll2");
var saveResult = doCreate(contact);
for (var i=0;i
content.innerHTML = content.innerHTML + saveResult[i].toHTMLString();
}
}
}
}
Sorry for the cryptic post. What I mean to do was give a peak at a library I'm working on the is a javascript implementation of DynaBeans. The main idea here is that you do a serialization process in javascript using user objects, sometimes called associative arrays. So when you make a query, you generate the appropriate soap message and, using DOM, put the results into a collection of "DynaBeans". This is simple since to create a key/value pair for a javascript object you just ref the object and set the value (object[sforceFieldname] = sforceValue).
Once you have the function to serialize the soap response to a "DynaBean", the next step is to serialize a "DynaBean" to a soap request such as create or update. This is pretty easy and can even be a user defined method that is a member of the "DynaBean" implementation. This would allow syntax like:
var contact = new DynaBean("Contact");
contact.setProperty("FirstName", "Dave");
contact.setProperty("LastName", "Carroll");
and so on. Since an object has a single representation in SOAP for both update and create we can code that serialization simply.
Now, combine these ideas with a wrapper that sends messages and dispatches responses to user defined handlers and we get to do something like:
contact = doUpdate(contact);
This method would run the update call and on the response if it were successful, add an Id field to the contact dynabean, and if not add an errors field instead. Then we would be able to do this:
if (contact.getPropertyValue("success") == "true") {
alert("The contact created has an id of: " + contact.getPropertyValue("Id"));
} else {
alert("There was an error with the create call: " + contact.getPropertyValue("errors").toString());
}
The wrapper also should (and does) use XmlHTTPRequest object and the activex version if it's IE making it compatible with mozilla and ie.
Cheers
Message Edited by DevAngel on 06-17-2005 08:18 AM