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
jls_74_txjls_74_tx 

Add the parent object to a wrapper class

I have a wrapper class for a custom object Referral__c but I need to add the parent object so only the child object display. The purpose for the wrapper class is so when looking at the ClientDetails__c object, a user can delete child records with a check box. I have displayed the child records previously with an extention, but I'm not able to duplicate the functionality with this wrapper class. Can you help?

__________________________________________________
public class ApartmentDeleteWrapperCLs{

public ClientDetails__c CID {get; set;}
public Referral__c Ref {get; set;}

public List<ApartmentRecordCls> accWrapperRecordList {get;set;}

public ApartmentDeleteWrapperCLs(){

//Fetch Referrals
List<Referral__c> accList= new List<Referral__c>();
accWrapperRecordList = new List<ApartmentRecordCls>();
accList = [select id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, Apartment__r.Phone__c, Apartment__r.Year_Built__c, 
Apartment__r.Submarket__r.Name, Apartment__r.Address__c, Apartment__r.City__c, Apartment__r.State__c, Apartment__r.Zip_Code__c,Apartment__r.Commission_Bonus__c,
Unit__r.Bedrooms__c, Unit__r.Bathrooms__c, Unit__r.Layout__c, Unit__r.Square_Feet__c, Unit__r.Rent__c, Unit__r.CR_6M_Final__c, 
Unit__r.CR_6M_Final_Percent__c, Unit__r.CR_12M_Final__c, Unit__r.CR_12M_Final_Percent__c, Unit__r.Status__c,
ClientDetails__r.ID, ClientDetails__r.Referring_Locator__r.ID, ClientDetails__r.First_Name__c  
from Referral__c WHERE ClientDetails__c = :CID];


//For loop to set data
  if(!accList.isEmpty()) {
    for(Referral__c acc: accList){
     ApartmentRecordCls arcls = new ApartmentRecordCls();
     arcls.isSelected =  false;
     arcls.accObj = acc;
     accWrapperRecordList.add(arcls);
    
    } //end of for loop.
  
  } //end of if condition.
 }
  
  /*
   Delete Apartment functionality based on the selected records.
  */
  public PageReference DeleteApartment(){
   List<Referral__c> accToDelete = new List<Referral__c>();
   //To hold the unselected Apartment records.
   List<ApartmentRecordCls> listUnSelectedRecords  = new List<ApartmentRecordCls>();  
    if(accWrapperRecordList !=null && accWrapperRecordList.size()>0) {
      for(ApartmentRecordCls wrapObj :  accWrapperRecordList){
        if(wrapObj.isSelected == true){
          accToDelete.add(wrapObj.accObj);
        }else{
          listUnSelectedRecords.add(wrapObj);
        }
      
      
      }//end of for.
      /*
       checking the delete list size and assign the unselected values to 
       original wrapper list.
      */
      if(accToDelete !=null && accToDelete.size()>0){
       delete accToDelete;
       accWrapperRecordList.clear();
       accWrapperRecordList.addAll(listUnSelectedRecords);
      }
    
    }else{
     ApexPages.Message  myMsg = new ApexPages.Message(ApexPages.Severity.info, 'Records were not there to delete.');
     ApexPages.addMessage(myMsg);
    }
    
    return null;
  }

  

 /* Wrapper class with checkbox and Apartment object. 
  this is also  called as inner class 
  */

 public class ApartmentRecordCls{
  public boolean isSelected {get;set;}
  public Referral__c accObj {get;set;}

 }

}
Best Answer chosen by jls_74_tx
Robert_StrunkRobert_Strunk
The VF page definitely sheds some light!

Since the page is using a custom controller instead of a standard controller, we will need to set the CID value in the URL string.  So I am assuming this page will be called from a custom button or link.   So in order for this page to work the calling button or link should look similar to:
"/apex/YOURPAGENAME?id=THEReferral__cID"

So all we need to do is grab the id value from the URL and use that to set the CID member in the class.  
public class ApartmentDeleteWrapperCLs{

    public String CID;
    public List<ApartmentRecordCls> accWrapperRecordList {get;set;}

    public ApartmentDeleteWrapperCLs(){
    
        CID = ApexPages.currentPage().getParameters().get('id');

        //Fetch Referrals
        List<Referral__c> accList = new List<Referral__c>();

        accWrapperRecordList = new List<ApartmentRecordCls>();

        accList = [
            SELECT     id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, 
                        Apartment__r.Phone__c, Apartment__r.Year_Built__c, Apartment__r.Submarket__r.Name, 
                        Apartment__r.Address__c, Apartment__r.City__c, Apartment__r.State__c, 
                        Apartment__r.Zip_Code__c,Apartment__r.Commission_Bonus__c,
                        Unit__r.Bedrooms__c, Unit__r.Bathrooms__c, Unit__r.Layout__c, Unit__r.Square_Feet__c, 
                        Unit__r.Rent__c, Unit__r.CR_6M_Final__c, Unit__r.CR_6M_Final_Percent__c, 
                        Unit__r.CR_12M_Final__c, Unit__r.CR_12M_Final_Percent__c, Unit__r.Status__c,
                        ClientDetails__r.ID, ClientDetails__r.Referring_Locator__r.ID, 
                        ClientDetails__r.First_Name__c  
            FROM Referral__c 
            WHERE ClientDetails__c = :CID
        ];

        //For loop to set data
        if(!accList.isEmpty()){
        
            for(Referral__c acc: accList){
            
                ApartmentRecordCls arcls = new ApartmentRecordCls();
                arcls.isSelected =  false;
                arcls.accObj = acc;
                accWrapperRecordList.add(arcls);
            }
        }
    }

    /*
    Delete Apartment functionality based on the selected records.
    */
    public PageReference DeleteApartment(){
    
        List<Referral__c> accToDelete = new List<Referral__c>();
        
        //To hold the unselected Apartment records.
        List<ApartmentRecordCls> listUnSelectedRecords  = new List<ApartmentRecordCls>();  
        
        if(!accWrapperRecordList.isEmpty()) {
        
            for(ApartmentRecordCls wrapObj :  accWrapperRecordList){
            
                if(wrapObj.isSelected == true){
                    accToDelete.add(wrapObj.accObj);
                }
                else{
                    listUnSelectedRecords.add(wrapObj);
                }
            }
            
            /*
            checking the delete list size and assign the unselected values to 
            original wrapper list.
            */
            if(!accToDelete.isEmpty()){
                delete accToDelete;
                accWrapperRecordList.clear();
                accWrapperRecordList.addAll(listUnSelectedRecords);
            }
        }
        else{
        
            ApexPages.Message  myMsg = new ApexPages.Message(
                ApexPages.Severity.info, 'Records were not there to delete.'
            );
            ApexPages.addMessage(myMsg);
        }
        return null;
    }

    /* Wrapper class with checkbox and Apartment object. 
    this is also  called as inner class 
    */

    public class ApartmentRecordCls{
        public boolean isSelected {get;set;}
        public Referral__c accObj {get;set;}
    }
}

Hope that helps!

All Answers

Robert_StrunkRobert_Strunk
Having a tough time figuring out what exactly you are trying to do but if you want to include the parent of the wrapped Referral__c sObject record, you can just create a new class member in your wrapper class to store that value.  

For example, your wrapper class is:
public class ApartmentRecordCls{
	public boolean isSelected {get;set;}
	public Referral__c accObj {get;set;}
}
And all you need to do is change it to:
public class ApartmentRecordCls{
	public boolean isSelected {get;set;}
	public Referral__c accObj {get;set;}
	public PARENT_TYPE theParent {get;set;}
}
Where PARENT_TYPE is the parent's type.  Then, whenever you are constructing your wrappers just add the parent to the wrapper.  

 
Robert_StrunkRobert_Strunk
Obviously the <b></b> tags on line four of the second code block above are bugs with the page and can be ignored.  
jls_74_txjls_74_tx
Robert,

Thank you for trying to help me. This is the first time I've built a wrapper so most likely I have the structure wrong. Let me explain a little more.

I have a custom object ClientDetails__c and each record has many child records in a custom object Referral__c. I have a VF page published on a SalesForce Site for each ClientDetails__c record and at the bottom of the VF page is a list of Referral__c child records. My reason for building the wrapper was so my clients could open the VF page and delete any child records using a check box.

I found an example online to build the wrapper but once it was completed I realized it displays every Referral__c record in the object. I have built the wrapper a couple of different ways, but every time it displays all 9,595 records in the Referral__c record. I know I am not pulling in the ClientDetails__c information correctly but I don't know how to add it.

My previous experience building the VF page is use an extension and the from Referral__c WHERE ClientDetails__c = :CID.id but clearly I'm missing a step building the wrapper.

I added my Parent_Type as your suggested, but it is still showing all of the Referral__c records, what am I missing here?

 public class ApartmentRecordCls{
  public boolean isSelected {get;set;}
  public Referral__c accObj {get;set;}
  public ClientDetails__c cdObj {get;set;}

 Thank you in advance!

 
Robert_StrunkRobert_Strunk
Ahh ok, I get it now.  The reason this is happening is because your CID member is null when the query is ran in the constructor.  So basically your accList is populated with all Referral__c records that have a null value for ClientDetails__c.

To verify this, just add a debug statement before your accList query to dump the CID value like so:
accWrapperRecordList = new List<ApartmentRecordCls>();

System.debug(LoggingLevel.Error, 'CID isNull :: ' CID == null );

accList = [select id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, Apartment__r.Phone__c,

 
Robert_StrunkRobert_Strunk
Wish I could edit the post above, need to change line 3 to be:
System.debug(LoggingLevel.Error, 'CID isNull :: ' + String.valueOf(CID == null));

I am just freehanding this so hopefully there are no syntax errors. 
jls_74_txjls_74_tx
This is the error I'm getting:
System.NullPointerException: Attempt to de-reference a null object
Class.ApartmentDeleteWrapperCLs.<init>: line 20, column 1 

Here are the code changes I made:
 
public class ApartmentDeleteWrapperCLs{

public ClientDetails__c CID;
public List<ApartmentRecordCls> accWrapperRecordList {get;set;}

public ApartmentDeleteWrapperCLs(){

//Fetch Referrals
List<Referral__c> accList= new List<Referral__c>();

accWrapperRecordList = new List<ApartmentRecordCls>();

System.debug(LoggingLevel.Error, 'CID isNull :: ' + String.valueOf(CID == null));

accList = [select id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, Apartment__r.Phone__c, Apartment__r.Year_Built__c, 
Apartment__r.Submarket__r.Name, Apartment__r.Address__c, Apartment__r.City__c, Apartment__r.State__c, Apartment__r.Zip_Code__c,Apartment__r.Commission_Bonus__c,
Unit__r.Bedrooms__c, Unit__r.Bathrooms__c, Unit__r.Layout__c, Unit__r.Square_Feet__c, Unit__r.Rent__c, Unit__r.CR_6M_Final__c, 
Unit__r.CR_6M_Final_Percent__c, Unit__r.CR_12M_Final__c, Unit__r.CR_12M_Final_Percent__c, Unit__r.Status__c,
ClientDetails__r.ID, ClientDetails__r.Referring_Locator__r.ID, ClientDetails__r.First_Name__c  
from Referral__c where ClientDetails__c = :CID.id];


//For loop to set data

 
Robert_StrunkRobert_Strunk
Your CID member is not being set thus CID.ID is null.  
jls_74_txjls_74_tx
How do I set the CID.ID?

 
Robert_StrunkRobert_Strunk
That depends on how your wrapper class is being invoked but basically it would look similar to:
 
ApartmentDeleteWrapperCLs tmpWrapper = new ApartmentDeleteWrapperCLs();

tmpWrapper.CID = <Here is where you pass in the ClientDetails__c record>

If you can post the VF page code and the page's controller code it will help us look into how the wrapper is being constructed.   
 
jls_74_txjls_74_tx
I'm usually much smarter than this. ;-)

VF Page:
<apex:page sidebar="false" showHeader="false" cache="false" id="profile" controller="ApartmentDeleteWrapperCLs">
<apex:image url="http://www.locatormls.com/staticfiles/misc/websiteheader.png"/>

 <apex:form id="theForm">
  <apex:commandButton value="Delete Apartments" action="{!DeleteApartment}" reRender="thePb,Msg" status="deleteStatus"/>
  <apex:pageblock id="thePb">
   <apex:pageblockTable value="{!accWrapperRecordList}" var="record">
   <apex:column headerValue="Select">
     <apex:inputCheckbox value="{!record.isSelected}"/>
    </apex:column> 
    <apex:column value="{!record.accObj.Apartment__r.Complex_Name__c}"/>
   </apex:pageblockTable>  
  </apex:pageblock> 
 </apex:form>
 
</apex:page>

Controller:
 
public class ApartmentDeleteWrapperCLs{

public ClientDetails__c CID;
public List<ApartmentRecordCls> accWrapperRecordList {get;set;}

public ApartmentDeleteWrapperCLs(){

//Fetch Referrals
List<Referral__c> accList= new List<Referral__c>();

accWrapperRecordList = new List<ApartmentRecordCls>();

System.debug(LoggingLevel.Error, 'CID isNull :: ' + String.valueOf(CID == null));

accList = [select id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, Apartment__r.Phone__c, Apartment__r.Year_Built__c, 
Apartment__r.Submarket__r.Name, Apartment__r.Address__c, Apartment__r.City__c, Apartment__r.State__c, Apartment__r.Zip_Code__c,Apartment__r.Commission_Bonus__c,
Unit__r.Bedrooms__c, Unit__r.Bathrooms__c, Unit__r.Layout__c, Unit__r.Square_Feet__c, Unit__r.Rent__c, Unit__r.CR_6M_Final__c, 
Unit__r.CR_6M_Final_Percent__c, Unit__r.CR_12M_Final__c, Unit__r.CR_12M_Final_Percent__c, Unit__r.Status__c,
ClientDetails__r.ID, ClientDetails__r.Referring_Locator__r.ID, ClientDetails__r.First_Name__c  
from Referral__c where ClientDetails__c = :CID.id];


//For loop to set data
  if(!accList.isEmpty()) {
    for(Referral__c acc: accList){
     ApartmentRecordCls arcls = new ApartmentRecordCls();
     arcls.isSelected =  false;
     arcls.accObj = acc;
     accWrapperRecordList.add(arcls);
    
    } //end of for loop.
  
  } //end of if condition.
 }
  
  /*
   Delete Apartment functionality based on the selected records.
  */
  public PageReference DeleteApartment(){
   List<Referral__c> accToDelete = new List<Referral__c>();
   //To hold the unselected Apartment records.
   List<ApartmentRecordCls> listUnSelectedRecords  = new List<ApartmentRecordCls>();  
    if(accWrapperRecordList !=null && accWrapperRecordList.size()>0) {
      for(ApartmentRecordCls wrapObj :  accWrapperRecordList){
        if(wrapObj.isSelected == true){
          accToDelete.add(wrapObj.accObj);
        }else{
          listUnSelectedRecords.add(wrapObj);
        }
      
      
      }//end of for.
      /*
       checking the delete list size and assign the unselected values to 
       original wrapper list.
      */
      if(accToDelete !=null && accToDelete.size()>0){
       delete accToDelete;
       accWrapperRecordList.clear();
       accWrapperRecordList.addAll(listUnSelectedRecords);
      }
    
    }else{
     ApexPages.Message  myMsg = new ApexPages.Message(ApexPages.Severity.info, 'Records were not there to delete.');
     ApexPages.addMessage(myMsg);
    }
    
    return null;
  }

  

 /* Wrapper class with checkbox and Apartment object. 
  this is also  called as inner class 
  */

 public class ApartmentRecordCls{
  public boolean isSelected {get;set;}
  public Referral__c accObj {get;set;}

 }

}

 
Robert_StrunkRobert_Strunk
Thanks for posting this, will take a look.  Don't be hard on yourself!
Robert_StrunkRobert_Strunk
The VF page definitely sheds some light!

Since the page is using a custom controller instead of a standard controller, we will need to set the CID value in the URL string.  So I am assuming this page will be called from a custom button or link.   So in order for this page to work the calling button or link should look similar to:
"/apex/YOURPAGENAME?id=THEReferral__cID"

So all we need to do is grab the id value from the URL and use that to set the CID member in the class.  
public class ApartmentDeleteWrapperCLs{

    public String CID;
    public List<ApartmentRecordCls> accWrapperRecordList {get;set;}

    public ApartmentDeleteWrapperCLs(){
    
        CID = ApexPages.currentPage().getParameters().get('id');

        //Fetch Referrals
        List<Referral__c> accList = new List<Referral__c>();

        accWrapperRecordList = new List<ApartmentRecordCls>();

        accList = [
            SELECT     id, Apartment__r.Complex_Name__c, Apartment__r.Warning_Image__c, 
                        Apartment__r.Phone__c, Apartment__r.Year_Built__c, Apartment__r.Submarket__r.Name, 
                        Apartment__r.Address__c, Apartment__r.City__c, Apartment__r.State__c, 
                        Apartment__r.Zip_Code__c,Apartment__r.Commission_Bonus__c,
                        Unit__r.Bedrooms__c, Unit__r.Bathrooms__c, Unit__r.Layout__c, Unit__r.Square_Feet__c, 
                        Unit__r.Rent__c, Unit__r.CR_6M_Final__c, Unit__r.CR_6M_Final_Percent__c, 
                        Unit__r.CR_12M_Final__c, Unit__r.CR_12M_Final_Percent__c, Unit__r.Status__c,
                        ClientDetails__r.ID, ClientDetails__r.Referring_Locator__r.ID, 
                        ClientDetails__r.First_Name__c  
            FROM Referral__c 
            WHERE ClientDetails__c = :CID
        ];

        //For loop to set data
        if(!accList.isEmpty()){
        
            for(Referral__c acc: accList){
            
                ApartmentRecordCls arcls = new ApartmentRecordCls();
                arcls.isSelected =  false;
                arcls.accObj = acc;
                accWrapperRecordList.add(arcls);
            }
        }
    }

    /*
    Delete Apartment functionality based on the selected records.
    */
    public PageReference DeleteApartment(){
    
        List<Referral__c> accToDelete = new List<Referral__c>();
        
        //To hold the unselected Apartment records.
        List<ApartmentRecordCls> listUnSelectedRecords  = new List<ApartmentRecordCls>();  
        
        if(!accWrapperRecordList.isEmpty()) {
        
            for(ApartmentRecordCls wrapObj :  accWrapperRecordList){
            
                if(wrapObj.isSelected == true){
                    accToDelete.add(wrapObj.accObj);
                }
                else{
                    listUnSelectedRecords.add(wrapObj);
                }
            }
            
            /*
            checking the delete list size and assign the unselected values to 
            original wrapper list.
            */
            if(!accToDelete.isEmpty()){
                delete accToDelete;
                accWrapperRecordList.clear();
                accWrapperRecordList.addAll(listUnSelectedRecords);
            }
        }
        else{
        
            ApexPages.Message  myMsg = new ApexPages.Message(
                ApexPages.Severity.info, 'Records were not there to delete.'
            );
            ApexPages.addMessage(myMsg);
        }
        return null;
    }

    /* Wrapper class with checkbox and Apartment object. 
    this is also  called as inner class 
    */

    public class ApartmentRecordCls{
        public boolean isSelected {get;set;}
        public Referral__c accObj {get;set;}
    }
}

Hope that helps!
This was selected as the best answer
jls_74_txjls_74_tx
That was it! I knew I missing something to pass the URL. You are correct about the ID being in the URL. I knew the CID was in the URL, I just couldn't figure out how to pass it to the controller.

You're the best! Thank you so much for your help on a weekend!