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
tsalbtsalb 

JS Onclick Button: Query to update other child records? (Detail Page Button)

Is it possible to update multiple records from a detail page button with the help of a query? I know it's possible to do this with a list, but here's the scenario:

 

User recommends child record - changes a status and a boolean. Other child records also need to have their boolean(s) toggled to true. However, the button is on the detail page - NOT a list. 

 

The following works great:

 

{!REQUIRESCRIPT("/soap/ajax/23.0/connection.js")}

var newRecords = [];

var thisP = new sforce.SObject("Proposal__c");
thisP.id = "{!Proposal__c.Id}";
thisP.Status__c = "Awarded";
thisP.test__c = true;
newRecords.push(thisP);

result = sforce.connection.update(newRecords);

location.reload(true);

 

 

However, I'm trying to introduce this, where Ideally i'd like to update other child records (with the same parent (Order__c) lookup)

 

{!REQUIRESCRIPT("/soap/ajax/23.0/connection.js")}

var newRecords = [];

var otherP = sforce.connection.query("Select Id from Proposal__c where Order__c = '{!Proposal__c.OrderId__c}'  ");
otherP.test__c = true;
newRecords.push(otherP);  //Add all other records to array?

var thisP = new sforce.SObject("Proposal__c");
thisP.id = "{!Proposal__c.Id}";
thisP.Status__c = "Awarded";
thisP.test__c = true;
newRecords.push(thisP);   //Add current detail page record to array

result = sforce.connection.update(newRecords);

location.reload(true);
 

 

Best Answer chosen by Admin (Salesforce Developers) 
tsalbtsalb

Actually, I had posted this in the wrong board - I got much more clarification in the AJAX board - here is the working solution. This is targetted for a customer portal user - and there is a custom prefix in the URL (hence the need for the serverUrl line)

 

Basically, for all child records for the same parent, i want a boolean toggled upon click (including one that button click is originating from).

However, for ONLY the record where the button click is originating, I want a picklist value change.

 

{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}
sforce.connection.serverUrl = '{!$Site.Prefix}/services/Soap/u/24.0';

try {
	var strQuery="Select Id from Proposal__c where Order__c = '"+'{!Proposal__c.OrderId__c}'+"'";
	var newRecords = [];
	var otherP = sforce.connection.query(strQuery);
	var records = otherP.getArray("records");
	for(var i=0; i < records.length ; i ++) {
		var ob = new sforce.SObject("Proposal__c");
		ob.Id = records[i].Id;
		ob.View__c = true;
		newRecords.push(ob);
	}
	var thisOb = new sforce.SObject("Proposal__c");
	thisOb.Id = "{!Proposal__c.Id}";
	thisOb.Status__c = "Awarded";

	var result = sforce.connection.update([thisOb]);
	result = sforce.connection.update(newRecords);

	window.location = "/a0D?fcf=00BA00000073XCw";
} 
catch(er) {
	alert(er);
}

 

All Answers

DevAngelDevAngel

Hi tsalb,

 

This looks like a good candidate for an after update trigger written in Apex code. This code is not tested, so should have some bugs, but this is the general approach. Note the <TestField__c> in the code. I don't know what fields to compare to determine if the trigger should fire. I assume you don't want it to fire unless certain fields have changed.

 

 

trigger MyTrigger on Proposal__c (after update) {
  if (!Trigger.isExecuting) {

    List<Proposal__c> newRecords = new List<Proposal__c>();
    // Map to store the trigger (child) records that have changed
    Map<Id, Proposal__c> orderIds = new Map<Id, Proposal__c>();
    Map<Id, Proposal__c> oldRecords = new Map<Id, Proposal__c>(Trigger.old);

    // Create map keyed on parent id
    for (Proposal__c thisP : Trigger.new) {
      // This would be a good place to see if you care about what was updated
      if (thisP.<TestField__c> != oldRecords.get(thisP.Id).<textField__c>) {
        // Go ahead an update the status of the user-changed record
        thisP.Status__c = 'Awarded';
        thisP.test__c = true;
        orderIds.put(thisP.OrderId__c, thisP);
        // Add the trigger (child) record to the list of records to update
        newRecords.add(thisP);
      }
    }

    // Handle the siblings
    List<Proposal__c> siblings = [Select Id, test__c From Proposal__c Where Order__c in :orderIds.keySet()];
    
    // Add the siblings to the list of records to update
    for (Proposal__p sibling : siblings) {
      sibling.test__c = true;
      newRecords.add(sibling);
    }
    
    // Commit the changes to the db
    update newRecords;
  }
    
}

 

In your js, are you certain that you are only returning a single object from your query?

 

Cheers,

tsalbtsalb

Actually, I had posted this in the wrong board - I got much more clarification in the AJAX board - here is the working solution. This is targetted for a customer portal user - and there is a custom prefix in the URL (hence the need for the serverUrl line)

 

Basically, for all child records for the same parent, i want a boolean toggled upon click (including one that button click is originating from).

However, for ONLY the record where the button click is originating, I want a picklist value change.

 

{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}
sforce.connection.serverUrl = '{!$Site.Prefix}/services/Soap/u/24.0';

try {
	var strQuery="Select Id from Proposal__c where Order__c = '"+'{!Proposal__c.OrderId__c}'+"'";
	var newRecords = [];
	var otherP = sforce.connection.query(strQuery);
	var records = otherP.getArray("records");
	for(var i=0; i < records.length ; i ++) {
		var ob = new sforce.SObject("Proposal__c");
		ob.Id = records[i].Id;
		ob.View__c = true;
		newRecords.push(ob);
	}
	var thisOb = new sforce.SObject("Proposal__c");
	thisOb.Id = "{!Proposal__c.Id}";
	thisOb.Status__c = "Awarded";

	var result = sforce.connection.update([thisOb]);
	result = sforce.connection.update(newRecords);

	window.location = "/a0D?fcf=00BA00000073XCw";
} 
catch(er) {
	alert(er);
}

 

This was selected as the best answer