You need to sign in to do that
Don't have an account?
Seraph
N>Trigger to Check 2 Different Fields from 2 Different Custom Objects
I have this visualforce page to show/explain my problem better
I need a trigger (after insert,after update I think) to check if any record (from Item__c :Type__c) uses any of the values (from Gadget__c : Name) and if so it puts a value (at Gadget__c : Status) either Used or Unused like shown on the screenshot. It also changes if the value (from Item__c :Type__c) is changed which I think why the trigger must also be after update.
here is my working code:
visualforce page
<apex:page sidebar="false" controller="DisplayStatus">
<apex:stylesheet value="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<apex:includeScript value="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" />
<div class="row">
<div class="col-xs-6">
<apex:pageBlock title="Gadget (Gadget__c)">
<apex:pageBlockTable value="{!gadgetlist}" var="gadget">
<apex:column headerValue="Gadget Type (Name)" value="{!gadget.Name}"/>
<apex:column headerValue="Status (Status__c)" value="{!gadget.Status__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</div>
<div class="col-xs-6">
<apex:pageBlock title="Item (Item__c)">
<apex:pageBlockTable value="{!itemlist}" var="item">
<apex:column headerValue="Item Name (Name)" value="{!item.Name}"/>
<apex:column headerValue="Type (Lookup,Gadget__c)" value="{!item.Type__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</div>
</div>
</apex:page>
controller
public class DisplayStatus{
public List<Gadget__c> gadgetlist {get; set;}
public List<Item__c> itemlist {get; set;}
public DisplayStatus()
{
this.ShowTable();
}
public void ShowTable()
{
gadgetlist = [select Name,Status__c from Gadget__c];
itemlist = [select Name,Type__c from Item__c];
}
}
It's a bit complicated for me so any help will be much appreciated.
Thanks!
I need a trigger (after insert,after update I think) to check if any record (from Item__c :Type__c) uses any of the values (from Gadget__c : Name) and if so it puts a value (at Gadget__c : Status) either Used or Unused like shown on the screenshot. It also changes if the value (from Item__c :Type__c) is changed which I think why the trigger must also be after update.
here is my working code:
visualforce page
<apex:page sidebar="false" controller="DisplayStatus">
<apex:stylesheet value="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<apex:includeScript value="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" />
<div class="row">
<div class="col-xs-6">
<apex:pageBlock title="Gadget (Gadget__c)">
<apex:pageBlockTable value="{!gadgetlist}" var="gadget">
<apex:column headerValue="Gadget Type (Name)" value="{!gadget.Name}"/>
<apex:column headerValue="Status (Status__c)" value="{!gadget.Status__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</div>
<div class="col-xs-6">
<apex:pageBlock title="Item (Item__c)">
<apex:pageBlockTable value="{!itemlist}" var="item">
<apex:column headerValue="Item Name (Name)" value="{!item.Name}"/>
<apex:column headerValue="Type (Lookup,Gadget__c)" value="{!item.Type__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</div>
</div>
</apex:page>
controller
public class DisplayStatus{
public List<Gadget__c> gadgetlist {get; set;}
public List<Item__c> itemlist {get; set;}
public DisplayStatus()
{
this.ShowTable();
}
public void ShowTable()
{
gadgetlist = [select Name,Status__c from Gadget__c];
itemlist = [select Name,Type__c from Item__c];
}
}
It's a bit complicated for me so any help will be much appreciated.
Thanks!
All Answers
Please try below trigger for your gadget object, it will assign status of gadget based on name with comparing item type.
Apex Trigger
Apex Class
Same way, based on that code reference you can write trigger and trigger handler class on Item object.
Thanks & Cheers,
Jigar
I have few things to ask about your reply (please bear with me as I have only minimal knowledge about triggers for now)
1. Is it not possible to do it all on a trigger (without a handler class)?
2. How did you determine its before insert,before update and not the opposite? (still confused about this)
3. How to post codes like your reply (text editor style)?
Hello,
Please see my comments.
1. Is it not possible to do it all on a trigger (without a handler class)?
- Yes, it is possible, you just need to move code from trigger handler class to trigger. But it is the best practice to manage all code in trigger handler class and call these methods from trigger.
2. How did you determine its before insert,before update and not the opposite? (still confused about this)
- We need to determine that based on the requirement exception possibilities, here we can also use after event but in that event you need to manage recursive trigger. if you update the same records in after trigger then that update will again execute the same trigger and it will give exception for recursive trigger. you can handle it using static variable. Update code like below to manage recursive.
- Add one static variable in trigger handler class at the top
- Replace the lines which is calling trigger handler method like below at both places
And then replace "BEFORE" to "AFTER" at all places in trigger.
3. How to post codes like your reply (text editor style)?
You can format it from "Add a code sample".
Thanks & Cheers,
Jigar
trigger UpdateStatus on Item__c(after insert,after update){
}
My basis for saying so is that the values for Gadgets__c: Name are already set up by admin and the changes on values (whether they add new items or update its type) will happen much on Items__c since users will be just adding more records on it rather than on Gadgets__c. Is it possible to do it that way?
Apex Trigger
Apex Class
Thanks & Cheers,
Jigar
I disabled it at the moment and moved on with the next.
I tried the 2nd pair and I get an error on line 23 of trigger ItemTrigger
[Error] Error: Compile Error: Variable does not exist: listGudgets at line 23 column 53
it compiled but still not working as it should be...
As per the your screenshot of the objects Gadget__c and Item__c, the Type__c field on the Item__c is a lookup to Gadget__c. You can set the default status on Gadget__c to Unused and use the trigger on the Item__c to update the status on the Gadget__c. Please find the trigger below.
You can aswell move the logic to a handler as Jigar suggested.
Hope this helps.
Find the issue, I was miss one line to add.
Please add new line(listUpdateGadgets.Add(objGadget)) at below line(objGadget.Status__c = 'Used') in "ItemTriggerHandler"
So updated code will look like.
Please try and let me know if it works.
And about Gadget trigger which is not working, please verify that you have updated "AFTER" keyword at all place with "BEFORE" keyword.
Thanks & Cheers,
Jigar
Thx for sharing some code...I got this after trying it
Error: Compile Error: Variable does not exist: trigger at line 7 column 13
@Krishna Sambaraju I used your revised code and it changed the status to Used after using it as lookup but it didn't change back to Unused when I changed the lookup to another value.
I have reviewed and update trigger and trigger handler code.
Please try with updated code.
Apex Trigger Apex Class
Hope it will work this time.
Let me know if it works.
Thanks & Cheers,
Jigar
I got an error on the class
Error: Compile Error: Duplicate variable: listItems at line 24 column 23
Please update variable name of list.
Replace "listItems" to "listExistingItems" from line #24 to end of the code.
I have found what is wrong with the code I have given. Here is the corrected trigger.
Hope this will work now.
I tried the latest one and it still behaves the same as the previous one.
Unused to Used = success
Used back to Unused = failed
This trigger will work in 1-1 case. If you have multiple items for each Gadget it might not work.
If your requirement is for 1:M (One gadget can have multiple items), here is an update of the trigger. Hope this works as per your requirement.