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
ssurferssurfer 

Create a custom object using s-control in Opportunity... where to start?

Hi,

I've got some problem trying to figure out how the s-controls work. Basically i would like to create an s-control that will create a new custom object (a child object to Opportunity)

This is what i want to achieve:

Create opportunity > populate the fields > save > press link that calls s-controll > grab the content of the fields "Opportunity ID" and "Opportunity Name", "Pack Date" and "Pack Address" > Create new Work Order > Fill in the fields Opportunity ID, Opportunity Name, Pack Date and Pack Address > Leave the window with Work Order open in Edit Mode

I'm a bit lost as where to start, i've tried with Create sObject and i've tried modifying codes that i have found here, but i'm not getting any further. I can't even get it to open a new Work Order without the autofill function.

I would be very grateful if someone could help me get started with this.
CaptainObviousCaptainObvious
Grab the  "Opportunity ID", "Opportunity Name", "Pack Date", "Pack Address" using simple merge fields, something like:
 
var opId = "{!Opportunity.Id}";
var opPackDate = "{!Opportunity.Pack_Date__c}";
var opPackAddress = "{!Opportunity.Pack_Address__c}";
...and so on...
 
then create your SObject, and use sforce.connection.create to fill in new "Work order"...
 
For details, (and a great starting point) go to :
 
 
There's plenty of examples!
ssurferssurfer
Thank you Captain,

I really appriciate you helping me, unfortunately i'm loosing track a bit earlier. What i've done is that i've created a link, calling the javascript below. As you can see, i'm a bit of a beginner and not even s-controls for dummies and the apex ajax begin to stop me from pulling hair off my head...

Anyway, i can't get this code to work and i'm not even sure if i'm really on the right track. I'm very grateful for any assistance I can get to push this further. Thank you :)

<html>
<head>
<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script>
<head>
<body onload="setupPage();">
<div id="output"></div>
</body>
<script>
var opId = "{!Opportunity.Id}";
var opPackDate = "{!Opportunity.Pack_Date__c}";
var work_order = new sforce.SObject("Work_Order");
work_order.Name = "FILL IN WORKORDER NAME";
work_order.Pack_Date=opPackDate
var result = sforce.connection.create([work_order]);
if (result[0].getBoolean("success")) {
log("new Work Order created with id " + result[0].id);
} else {
log("failed to create Work Order " + result[0]);
}
</script>
</html>
CaptainObviousCaptainObvious
You called the setupPage() function, but you did not define it in the javascript
 
try something like this:
 
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 

<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script> 
<script language="javascript"> 

function setupPage() {
 //put here the code to execute after the page is rendered
 //then call your function, let's say "createOrder()", as an example
 createOrder();
}

function createOrder() {
 var opId = "{!Opportunity.Id}";
 var opPackDate = "{!Opportunity.Pack_Date__c}";
 var work_order = new sforce.SObject("Work_Order");
 work_order.Name = "FILL IN WORKORDER NAME";
 work_order.Pack_Date=opPackDate
 var result = sforce.connection.create([work_order]);
 if (result[0].getBoolean("success")) {
  log("new Work Order created with id " + result[0].id);
 } else {
  log("failed to create Work Order " + result[0]);
 }
}

</script> 
</head> 
<body onload="setupPage();"></body> 
</html>

 it's not complete, but it'll get you started
ssurferssurfer

 Thank you Captain,

 

I managed to download the .ppt version of the S-Controls for dummies and it is really helpful. Even if my understanding has improved ( i think ) i'm still unable to get a successful result. I can't even get the application to open up a related Work Order in edit mode. (meaning Work_Order.Opportunity.ID = OpID) The step of getting the fields filled in seems reachable, but only when i've first mastered opening up a Work Order and relating it to the Opportunity from which the s-control is executed.

 

I know i'm asking very basic questions, but i've really been sitting for 3 days trying to figure this out... below is the code that i'm working with. I'm very grateful for any help or comment that can help me get this further. Most important, and to make me feel like i'm making a progress, would be to be able to open up work_order from Opportunity.

 

Thank you very much! :)

 

 

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

 

<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script>

<script language="javascript">

 

function setupPage() {

createWork_Order();

parent.parent.frames.location.replace("/"+Work_OrderId+"/e");

 

}

 

function createWork_Order() {

 var opId = "{!Opportunity.Id}";

 var opRecType = “”{!Opportunity.RecordType}”

 var opPackDate = "{!Opportunity.Pack_Date__c}";

 var work_order = new sforce.SObject("Work_Order");

 Work_Order.RecordType = opRecType

 Work_Order.opportunity.ID=opID

 Work_Order.Name = "FILL IN WORKORDER NAME";

 Work_Order.Pack_Date=opPackDate

 result = sforce.connection.create([work_order]);

 

 if (result[0].getBoolean("success")) {

  log("new Work Order created with id " + result[0].id);

 } else {

  log("failed to create Work Order " + result[0]);

 }

}

 

</script>

</head>

<body onload="setupPage();"></body>

</html>

ssurferssurfer

Continued....

I get a new window with the following text when i press the hyperlink opening the s-contol:

 

var opPackDate = ""; var work_order = new sforce.SObject("Work_Order"); Work_Order.RecordType = opRecType Work_Order.opportunity.ID=opID Work_Order.Name = "FILL IN WORKORDER NAME"; Work_Order.Pack_Date=opPackDate result = sforce.connection.create([work_order]); if (result[0].getBoolean("success")) { log("new Work Order created with id " + result[0].id); } else { log("failed to create Work Order " + result[0]); } }

CaptainObviousCaptainObvious
There's a typo on the following line:
 
var opRecType = “{!Opportunity.RecordType}”
 
Try using Firefox with the Firebug extension, it's great for debugging your code! Also, make use of the alert() function to see that you're getting the correct results. Something like this:
 
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 

<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script> 
<script language="javascript"> 

function setupPage() {
 createWork_Order();
}

function createWork_Order() {
 var opId = "{!Opportunity.Id}";
 var opRecType = "{!Opportunity.RecordType}";
 
 alert("Opportunity Id= " + opId + "\n Opportunity Record Type= " + opRecType );
 
 var opPackDate = "{!Opportunity.Pack_Date__c}";
 var work_order = new sforce.SObject("Work_Order");
  Work_Order.RecordType = opRecType
  Work_Order.opportunity.ID=opID
  Work_Order.Name = "FILL IN WORKORDER NAME";
  Work_Order.Pack_Date=opPackDate
 
  result = sforce.connection.create([work_order]);

  if (result[0].getBoolean("success")) {
    log("new Work Order created with id " + result[0].id);
  } else {
    log("failed to create Work Order " + result[0]);
  }
 parent.frames.location.replace("/"+Work_OrderId+"/e"); 
}

</script> 
</head> 
<body onload="setupPage();"></body> 
</html>

 
Wish I could be of more help, I've just started learning javascript myself :D
ssurferssurfer
So.... here's the conclusion.... about a week later I've now got a functional code that will create and link a custom object to an opportunity. It all seemed so easy when I started. I've recieved great help from here and the two best tools i found was the Eclipse Toolkit and Mozilla Firebug. The latter is excellent for HTML code also. Here's where you can get the EclipseToolkit: https://wiki.apexdevnet.com/index.php/Apex_Toolkit_for_Eclipse

Thank you again for all the help i got!


Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script>
<script>
var opId="{!Opportunity.Id}";
var Work_Order__c; // added global, will become the new object id

function setupPage() {
 createWork_Order();
 parent.frames.location.replace("/"+Work_Order__c+"/e");
}
 
 
 function createWork_Order() {

var wo__c = new sforce.SObject("Work_Order__c");
//alert("Opportunity Id= " + opId + " Opportunity Record Type= " + opRecType );
//var opPackDate = "{! Opportunity.Pack_Date_1__c }";
//wo__c.RecordTypeID = opRecType;
//var wo__c.Opportunity.Id=opId;
    wo__c.Opportunity__c = opId; //  added
   
try {

 result = sforce.connection.create([wo__c]);
}catch(error) {
alert("got an error: " + error);
}

  if (result[0].getBoolean("success")) {
    // alert("new Work Order created with id " + result[0].id);
    Work_Order__c = result[0].id; // added
   
  } else {
    alert("failed to create Work Order " + result[0]);
  }
 
}
 
</script>
</head>
<body onload="setupPage();"></body>
</html>

 

JetJacksonJetJackson

I am trying to do exactly the same thing. We need to be able to convert opportunities into jobs so the production manager knows which quotes have got the go ahead etc. Ultimately this is to stop the user having to input the same information twice into an opportunity and then a job. Currently when a new job is created through the opportunity tab with a master detail relationship the only thing that merges over is the opportunity name.

So the only difference is I have created a custom object called Jobs. I want to simply be able to click a custom link in the opportunities tab which will open up the Jobs tab with the data already filled in.

Field Name: Required_Completion_Date   |   Merge to:   Due_Date

Field Name: Type_of_Service    |   Merge to:  Service_Type

Field Name: Description    |   Merge to: Job_Description

Field Name: Contact   |    Merge to:  Contact      (I read somewhere that it may not be possible to merge the contact from the Opportunity object to the Custom Object in this process as the contact is a part of another object) 

Field Name: Account   |   Merge to: Account      (in Job object)

Field Name: Opportunity   |   Merge to: Opportunity      (In job object)

So Account and Contact fields in Job object both have a lookup relationship to Account and Contact objects respectively. Opportunity field in Job object has a Master-Detail relationship with Opportunity object.

With no knowledge of Java, bar cutting and pasting, a small amount of knowledge of HTML I have attempted to modify ssurfer's code below to suit the Job Object field names etc.

Code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script>
<script>
var opId="{!Opportunity.Id}";
var Job__c; // added global, will become the new object id

function setupPage() {
 createJob();
 parent.frames.location.replace("/"+Job__c+"/e");
}
 
 
 function createJob() {

var Job__c = new sforce.SObject("Job__c");
//alert("Opportunity Id= " + opId + " Opportunity Record Type= " + opRecType );
// Job__c.Due_Date__c = "{! Opportunity.Required_Completion_Date__c }";
// Job__c.Service_Type__c = "{! Opportunity.Type_of_Service__c }";
// Job__c.Job_Description__c = "{! Opportunity.Description }";
// Job__c.Account__c = "{! Opportunity.Account }";
//var Job__c.Opportunity.Id=opId;
    Job__c.Opportunity__c = opId; //  added
   
try {

 result = sforce.connection.create([Job__c]);
}catch(error) {
alert("got an error: " + error);
}

  if (result[0].getBoolean("success")) {
    // alert("new Job created with id " + result[0].id);
    Job__c = result[0].id; // added
   
  } else {
    alert("failed to create Work Order " + result[0]);
  }
 
}
 
</script>
</head>
<body onload="setupPage();"></body>
</html>


 

With this I get an error saying that fields are missing. It says the Due_Date__c is missing or something.. I dont know how to fix this up.

Any help would be greatly appreciated.

CaptainObviousCaptainObvious
Are you getting a "Due_Date__c is an invalid field" error?
 
If so, go to your custom field in Setup, and click the Set Field-Level Security button to check that the field is visible in the profile you're using.
 
Do that for all the custom fields you want to be able to populate.
JetJacksonJetJackson

All the profiles that we are using have view and editing rights to those custom fields. The error that I get is:

Failed to create Work Order {errors:{fields:’Due_Date__c’, message:’Required fields are missing: [Due_Date__c]’, statusCode:’REQUIRED_FIELD_MISSING’, }, id:null, success:’false’, }

 

So I have changed the code to:

Code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<script src="/soap/ajax/8.0/connection.js" type="text/javascript"></script> 
<script> 
var opId="{!Opportunity.Id}"; 
var Job__c; // added global, will become the new object id 

function setupPage() { 
createJob(); 
parent.frames.location.replace("/"+Job__c+"/e"); 
} 


function createJob() { 

var Job__c = new sforce.SObject("Job__c"); 
//alert("Opportunity Id= " + opId + " Opportunity Record Type= " + opRecType ); 
// Job.Due_Date__c = "{! Opportunity.Required_Completion_Date__c }"; 
// Job.Service_Type__c = "{! Opportunity.Type_of_Service__c }"; 
// Job.Job_Description__c = "{! Opportunity.Description }"; 
// Job.Account__c = "{! Opportunity.Account }"; 
//var Job.Opportunity.Id=opId; 
Job.Opportunity__c = opId; // added 

try { 

result = sforce.connection.create([Job__c]); 
}catch(error) { 
alert("got an error: " + error); 
} 

if (result[0].getBoolean("success")) { 
// alert("new Job created with id " + result[0].id); 
Job__c = result[0].id; // added 

} else { 
alert("failed to create Work Order " + result[0]); 
} 

} 

</script> 
</head> 
<body onload="setupPage();"></body> 
</html>


 
The difference being that I am not referring to Job__c.Due_Date__c instead referring to Job.Due_Date__c and I no longer get this error. Now I get the error that Job is undefined on line 26.

 

In the mean time, im going to go and do a crash course in Java.