+ Start a Discussion
Tom DJTom DJ 

Correlate edited record to trigger invocation

I have created a set of triggers that block duplicates on Leads,  Contacts and Accounts that are entered through the standard edit screen.   The trigger puts an error message at the top of the edit screen using Trigger.addError() when it blocks a duplicate record from  being created .    I am trying to implement an override button that shows up alongside the error.   I have the button code in place and the button shows up fine.   When clicked, I would like the override button to signal to the trigger that the current record that is being edit should not be blocked.   I need a way to signal to the trigger that the record that is currently being edited should not be blocked.

 

My initial thought was to create a new Custom Settings object that would contain a session ID field.  The override button 'onclick' javascript event handler would insert a new record into the Custom Setting table (by invoking apex class method) that includes the current session ID (UserInfo.getSessionId()).  After the API call, the event handler would auto-click the  “Save” button on the standard edit page.

 

My thought was that the trigger would get the current session Id using UserInfo.getSessionId() and query the Custom settings for a record that matches the the current session ID and is not older than a hard coded time (e.g. 5 seconds).  If it finds a matching record, it exits instead of running the trigger logic.

 

I printed the session ID from the Web Servcie method and again from the trigger and the Ids are different so this approach does not work.

 

Apex WebService method sessionId:

00DA0000000c7YG!AQ4AQE6qc65itrKsrkPRxobinnc_Q7NaaECyv7Iyciu_pLtt_Asz_uISpmDRfpxQQJhV3k_cJCOYrlufnhU7D0zqNXkoCRk6

 

Trigger sessionId:

00DA0000000c7YG!AQ4AQMqmgZYEVoCtC12KYptrbLEbznz8HVvaIFtgf1KvpP5Mb4s6ODZJloN8.8M1rwN0XQ8WppIvT8YA_zxCaDr4hyXNpHv_

 

Does anyone know of something I can use to correlate a new record that is being created in an edit page to a trigger that is invoked when that record is saved?

 

Any ideas or help this would be greatly appreciated.

 

Tom DesJardins

Best Answer chosen by Admin (Salesforce Developers) 
Jon Mountjoy_Jon Mountjoy_

Tricky.  How about this.

 

1. Add an extra field to the object.  Override(type boolean) default to false.

 

2. Hide the field from page layouts -perhaps use some FLS on it too.

 

3. Make your Override button change the state of the variable for that record.

 

4. Make your trigger take this field into account.  ie. if (!override) { /* as before */ } else { /* do nothing?  */}

 

Will that do it? 

 

All Answers

Jon Mountjoy_Jon Mountjoy_

Tricky.  How about this.

 

1. Add an extra field to the object.  Override(type boolean) default to false.

 

2. Hide the field from page layouts -perhaps use some FLS on it too.

 

3. Make your Override button change the state of the variable for that record.

 

4. Make your trigger take this field into account.  ie. if (!override) { /* as before */ } else { /* do nothing?  */}

 

Will that do it? 

 

This was selected as the best answer
Tom DJTom DJ

Thanks for the quick response.  It is a good solution, but I am not sure it will work for what I am doing.

 

A couple of issues.  Hopefully you can help me on the second one.

 

 

  • This is for an App Exchange app and I would prefer not to ask customers to add fields to standard records, but I am not completely against it.
  • This override button is injected into the standard (not custom) edit pages for Lead, Contact, and Account.  I am unsure how I could update the new field for the record from javascript for a record that is not created yet and resides solely in the edit screen.  Is there a way that I can do that? 

 

 

It is a little bit ugly, but I guess I could let the custom field be visible in the layout and fill it in when the button is pressed.  I am not sure that the value will make to the record though.

 

Thanks,

 

Tom

 

 

 

 

Tom DJTom DJ

OK,  I have figured out how to get the Session ID to the trigger.  Pretty simple, but my mind was stuck on a track.   From the trigger invocation, I just need to inject the trigger's session ID into the Trigger.addError() methods as a parameter to the onclick handler, which in turn passes it as a parameter to the Apex Web Service Method when the Override button is pressed.   The Web Service method then adds the session ID to the Custom Settings cache so that the trigger can detect that the session ID was added a short time in the past. The trigger after detecting the override clears the cache of stale session IDs.   Using the session ID record in the cache with a short time to live is not perfect because a user could have two tabs open in the browser and submit two records back to back, but it is good enough.

 

So now I have a transparent seamless way to override the trigger from blocking a particular duplicate when a customer has API access.  Great.

 

Jon, I intend to use your solution of a custom field for customers that do not have API access.  It is less transparent, but if those customers want the feature, they can either pay for API access or add custom fields to their records.   Thanks so much for your help.  It enabled me to come up with a two part solution that is good enough.

 

BTW, does anyone know if it is possible from within Apex to determine if a customer has API access?

 

Tom

 

 

Jon Mountjoy_Jon Mountjoy_

Yikes Tom :-)  

 

Why do you need the web service method?

Tom DJTom DJ

 

Scary, eh:)

 

I am using triggers to detect duplicates and injecting an error message (Record.addError()) into the new record that is being blocked, which is a list of duplicates that are hyperlinked.  This allows the trigger handler to block duplicates on the standard edit pages for Lead, Contacts and Accounts and give the user the ability to explore the duplicates.  I really don't want to supply my own versions of the edit screens.

 

The problem is that there is no way for the user to override the trigger if they decide they are not duplicates.  So, I have injected an HTML "Override"  button and a javascript onclick handler into the error.   When the user presses the button the handler calls the Web Service method to tell the trigger to ignore an upcoming insert of a duplicate record, and then it auto-clicks the edit page's save button.   I got this working last night.

 

I have tried to inject Apex components into the edit pages through Record.addError() but they are not rendered because the edit pages are not Visual Force pages.   Is there a way  to communicate from javascript within a non-VF page to Apex without using the API?  That would give me a single solution for all Org types and make me very happy. 

 

 

Thanks,

 

Tom

 

 

 

 

Jon Mountjoy_Jon Mountjoy_

Oh my.  That sounds very inefficient.  I still don't quite get it.

 

Are you using the Ajax toolkit on the button to call the webservice in your own org to set the data?

 

There's a new feature coming soon (JavaScript Remoting) -it's for visualforce pages.  Why don't you create a Visualforce page?

Tom DJTom DJ

 

 I am using sforce.apex.execute() (Ajax toolkit) to call my Apex WebService method from Javascript.  

 

Thanks for the tip on JavaScript Remoting.   I can already call methods and transfer parameters on a controller from a javascript in a VF page using the apex:ActionFunction component with an apex:param subcomponent.   The JavaScript Remoting sounds much simpler. 

 

I am trying to avoid VF pages for this feature.  The feature is for an App Exchange application that we are trying to insert into the normal workflows of most businesses with as little admin configuration as possible and as little change as possible to the end user's normal mode of operation.   Therefore I am trying to get things to work on the standard Salesforce edit pages, which I have little dynamic control over except through JavaScript injected as invisible error text.

 

Thanks again for your responses.

 

Regards,

 

Tom