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
StenderStender 

Help on VisualForce Record Creation Page

Hello,

 

I am looking for help on creating a VF page/controller that will allow a user to create multiple records.  Right now in our Org we have a custom Opportunity_Product__c object related to Opportunities and a custom Sold_Accounts__c object related to the Opportunity_Product__c object.  The Sold Accounts record is basically a join object between the Opp Prod and Accounts.  My idea is to have a simple page with a lookup to Accounts where they will select the account with a button below that where they can add another lookup (allowing them to enter multiple accounts on a single page).  I am having trouble with the button part of this (its as far as I have gotten).  What happens when the button is clicked is instead of just adding another lookup field, it is 'refreshing' the page and giving a required field error on the initial field.  If I populate the initial field and click the button, the page refreshes with two lookup fields but then it removes the value from the first.  What am I doing wrong?  Here is my code:

<apex:page Controller="massCreateSoldAccountsController">
    <apex:form >
        <apex:pageBlock title="Mass Create Sold Accounts" mode="edit">
            <apex:repeat value="{!AccountLookups}" var="currentSoldAccount">
                <apex:inputField value="{!currentSoldAccount.Account__c}"/>           
            </apex:repeat>
            <apex:commandButton action="{!setAddOneToNumberOfAccounts}" value="Add Account" id="addAccountButton"/>
        </apex:pageBlock>
   </apex:form>
</apex:page>

 

 

 

 

 

public class massCreateSoldAccountsController {
       
        public Integer numberOfAccounts = 1;           
        public List<Sold_Accounts__c> soldAccountsToInsert = new List<Sold_Accounts__c>();      
        public void AddOneToNumberOfAccounts(){
                numberOfAccounts++;
        }
       
        public Opportunity_Product__c getOppProdSINGLE(){
                return [Select ID, Name, Product_Service__r.Name, Opportunity_Name__c FROM Opportunity_Product__c WHERE ID = : (ApexPages.currentPage().getParameters().get('oppProdID')) ];
        }
       
        //below method will return the list of Opportunity Products to the VF page.  This can be used to create the 'checkboxes'
        public List<Opportunity_Product__c> getOppProdsMULTI(){          
                Id oppID = (ApexPages.currentPage().getParameters().get('oppID'));
                List<Opportunity_Product__c> oppProducts = [Select ID, Pricing_Record__c, Product_Service__c, Product_Service__r.Name from Opportunity_Product__c WHERE Opportunity_Name__c = :oppID];
                If(oppProducts.size() == 0){
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'This Opportunity has no related Opportunity Product records.  Please create all appropriate Opportunity Product records before continuing.'));
                        return null;                   
                } else{
                        return oppProducts;    
                }
               
        }
        /*public void setSoldAccountstoInsertSINGLE(){
                ID oppProdID = (ApexPages.currentPage().getParameters().get('oppProdID'));             
        }*/
        public List<Sold_Accounts__c> getAccountLookups(){
                List<Sold_Accounts__c> soldAccounts = new List<Sold_Accounts__c>();
                For(Integer i = 0; i < numberOfAccounts; i++){
                                Sold_Accounts__c soldAccount = new Sold_Accounts__c();
                                soldAccount.Add(soldAccount);
                }
                return soldAccountsTest;
        }
}

 

 

 

Thanks again for any help!

 

Jeremy Stender

Best Answer chosen by Admin (Salesforce Developers) 
JitendraJitendra

Try this:

 

Visualforce page:

<apex:page Controller="massCreateSoldAccountsController">
    <apex:form >
        <apex:pageBlock title="Mass Create Sold Accounts" mode="edit">
            <apex:repeat value="{!soldAccounts}" var="currentSoldAccount">
                <apex:inputField value="{!currentSoldAccount.Account__c}"/>           
            </apex:repeat>
            <apex:commandButton action="{!AddOneToNumberOfAccounts}" value="Add Account" id="addAccountButton"/>
        </apex:pageBlock>
   </apex:form>
</apex:page>

 

 

Apex code:

public class massCreateSoldAccountsController {
       
	   public Integer numberOfAccounts = 1;           
       public List<Sold_Accounts__c> soldAccounts = null;    
		
	   public massCreateSoldAccountsController()
	   {
			soldAccounts = new List<Sold_Accounts__c>();
			Sold_Accounts__c soldAccount = new Sold_Accounts__c();
            soldAccounts.Add(soldAccount);
	   }
        
		public void AddOneToNumberOfAccounts(){
               Sold_Accounts__c soldAccount = new Sold_Accounts__c();
               soldAccounts.Add(soldAccount);
        }
       
        public Opportunity_Product__c getOppProdSINGLE(){
                return [Select ID, Name, Product_Service__r.Name, Opportunity_Name__c FROM Opportunity_Product__c WHERE ID = : (ApexPages.currentPage().getParameters().get('oppProdID')) ];
        }
       
        //below method will return the list of Opportunity Products to the VF page.  This can be used to create the 'checkboxes'
        public List<Opportunity_Product__c> getOppProdsMULTI(){          
                Id oppID = (ApexPages.currentPage().getParameters().get('oppID'));
                List<Opportunity_Product__c> oppProducts = [Select ID, Pricing_Record__c, Product_Service__c, Product_Service__r.Name from Opportunity_Product__c WHERE Opportunity_Name__c = :oppID];
                If(oppProducts.size() == 0){
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'This Opportunity has no related Opportunity Product records.  Please create all appropriate Opportunity Product records before continuing.'));
                        return null;                   
                } else{
                        return oppProducts;    
                }
               
        }
        /*public void setSoldAccountstoInsertSINGLE(){
                ID oppProdID = (ApexPages.currentPage().getParameters().get('oppProdID'));             
        }*/
}

 

All Answers

JitendraJitendra

Try this:

 

Visualforce page:

<apex:page Controller="massCreateSoldAccountsController">
    <apex:form >
        <apex:pageBlock title="Mass Create Sold Accounts" mode="edit">
            <apex:repeat value="{!soldAccounts}" var="currentSoldAccount">
                <apex:inputField value="{!currentSoldAccount.Account__c}"/>           
            </apex:repeat>
            <apex:commandButton action="{!AddOneToNumberOfAccounts}" value="Add Account" id="addAccountButton"/>
        </apex:pageBlock>
   </apex:form>
</apex:page>

 

 

Apex code:

public class massCreateSoldAccountsController {
       
	   public Integer numberOfAccounts = 1;           
       public List<Sold_Accounts__c> soldAccounts = null;    
		
	   public massCreateSoldAccountsController()
	   {
			soldAccounts = new List<Sold_Accounts__c>();
			Sold_Accounts__c soldAccount = new Sold_Accounts__c();
            soldAccounts.Add(soldAccount);
	   }
        
		public void AddOneToNumberOfAccounts(){
               Sold_Accounts__c soldAccount = new Sold_Accounts__c();
               soldAccounts.Add(soldAccount);
        }
       
        public Opportunity_Product__c getOppProdSINGLE(){
                return [Select ID, Name, Product_Service__r.Name, Opportunity_Name__c FROM Opportunity_Product__c WHERE ID = : (ApexPages.currentPage().getParameters().get('oppProdID')) ];
        }
       
        //below method will return the list of Opportunity Products to the VF page.  This can be used to create the 'checkboxes'
        public List<Opportunity_Product__c> getOppProdsMULTI(){          
                Id oppID = (ApexPages.currentPage().getParameters().get('oppID'));
                List<Opportunity_Product__c> oppProducts = [Select ID, Pricing_Record__c, Product_Service__c, Product_Service__r.Name from Opportunity_Product__c WHERE Opportunity_Name__c = :oppID];
                If(oppProducts.size() == 0){
                        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'This Opportunity has no related Opportunity Product records.  Please create all appropriate Opportunity Product records before continuing.'));
                        return null;                   
                } else{
                        return oppProducts;    
                }
               
        }
        /*public void setSoldAccountstoInsertSINGLE(){
                ID oppProdID = (ApexPages.currentPage().getParameters().get('oppProdID'));             
        }*/
}

 

This was selected as the best answer
StenderStender

Perfect Jitendra.  Even better I see what you did and understand why it works and my previous way didn't.  Also, this provides an 'extra' piece of functionality, it makes them enter an account before they can 'add' another, helping with data integrity.  I appreciate the help!

 

Thanks,
Jeremy Stender

StenderStender

Hi the above did work for that situation, but I have progressed a little farther and the same problem is happening for the two different buttons now.  I have added a button to 'remove' one of the lookup fields added by the 'Add Account' button.  I have also added a 'Cancel' button to return the user to the previous page (they will be getting to this page from the Opportunity_Product__c detail page).  However, for both buttons it is still asking for all of the Account Lookup fields that are appearing to be populated.  I.e. I click to the VF page and then I click "Cancel" and it says I have to enter an Account before I can "Cancel".  Here is my code as it is now:

 

VF Page:

<apex:page Controller="massCreateSoldAccountsController">
    <apex:form >
        <apex:pageBlock title="Mass Create Sold Accounts" mode="edit">
            <apex:outputText value="Please enter all accounts that you wish to create Sold Account records for {!OppProdSingle.Product_Service__r.Name}" />
            <apex:repeat value="{!soldAccounts}" var="currentSoldAccount">
                <apex:inputField value="{!currentSoldAccount.Account__c}"/>           
            </apex:repeat>
            <apex:commandButton action="{!AddOneToNumberOfAccounts}" value="Add Account" id="addAccountButton"/>
            <apex:commandButton action="{!SubtractOneFromNumberOfAccounts}" value="Remove Account" id="removeAccountButton"/>

        </apex:pageBlock>
        <apex:pageBlock >
            <apex:outputText value="Once you have indicated all accounts, click the button below to create the Sold Account records for the Product inidicated." />
            <br />  
            <apex:commandButton value="Create Sold Account Records" id="createSoldAccountsButton"/>
            <apex:commandButton value="Cancel" id="CancelButton" action="{!cancelSingle}" />        
        </apex:pageBlock>
   </apex:form>
</apex:page>

 

 

Controller:

public class massCreateSoldAccountsController {
       
	public Integer numberOfAccounts = 1;           
    public List<Sold_Accounts__c> soldAccounts {get; set;}
    
		
	public massCreateSoldAccountsController(){
		soldAccounts = new List<Sold_Accounts__c>();			
		Sold_Accounts__c soldAccount = new Sold_Accounts__c();	
        soldAccounts.Add(soldAccount);
	}
    //this will be used by the Add Account button to add another lookup field to accounts.    
	public void AddOneToNumberOfAccounts(){
    	Sold_Accounts__c soldAccount = new Sold_Accounts__c();
        soldAccounts.Add(soldAccount);
    }
    //this will be ysed by the Remove Account button to remove the most recent lookup field.
    public void SubtractOneFromNumberOfAccounts(){
    	If(soldAccounts.size() >= 1){
    		soldAccounts.remove(soldAccounts.size()-1);
    	}
    }
    //returns the Opportunity Product that the button was clicked from.  Can be used for multiple other things.   
    public Opportunity_Product__c getOppProdSINGLE(){
    	return [Select ID, Name, Product_Service__r.Name, Opportunity_Name__c FROM Opportunity_Product__c WHERE ID = :(ApexPages.currentPage().getParameters().get('oppProdID')) ];
    }
       
    //below method will return the list of Opportunity Products to the VF page.  This can be used to create the 'checkboxes'
    public List<Opportunity_Product__c> getOppProdsMULTI(){          
    	Id oppID = (ApexPages.currentPage().getParameters().get('oppID'));
        List<Opportunity_Product__c> oppProducts = [Select ID, Pricing_Record__c, Product_Service__c, Product_Service__r.Name from Opportunity_Product__c WHERE Opportunity_Name__c = :oppID];
        If(oppProducts.size() == 0){
        	ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'This Opportunity has no related Opportunity Product records.  Please create all appropriate Opportunity Product records before continuing.'));
            return null;                   
        } else{
        	return oppProducts;    
        }
               
	}
	//this method will be used by the 'Create Sold Account Records' button to actually insert the records.  It will either return the user to the Opp Product's page or return an error if no Sold Accounts have been indicated.
	public Pagereference insertSoldAccountsSingle(){		
		PageReference pageRef = null;
		List<Sold_Accounts__c> soldAccountsToInsert = new List<Sold_Accounts__c>();
		If(soldAccounts != null){
			For(Sold_Accounts__c currentSA :soldAccounts){				
				currentSA.Opportunity_Product_Record__c = (ApexPages.currentPage().getParameters().get('oppProdID'));
				soldAccountsToInsert.add(currentSA);
			}			
			insert soldAccountsToInsert;
			String oppProd = (ApexPages.currentPage().getParameters().get('oppProdID'));
			pageRef = new PageReference('https://' + ApexPages.currentPage().getUrl().substring(2,6) + 'salesforce.com' + '/' + oppProd); 
		} else{
			ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'The list of Opportunity Products in the uploaded .csv does not match the list for this Opportunity in SF.  If you added or removed an Opportunity Product for this Opportunity, you MUST export a new .csv for the ROI, re-enter the quoted prices there and upload the new .csv file it creates.'));
			pageRef = new PageReference(ApexPages.currentPage().getUrl());
		}
		return pageRef;
	}
	//this will be used by the Cancel Button (for SINGLE product creation) to send the user back to the Opp Prod page
	public Pagereference cancelSINGLE(){
		String oppProd = (ApexPages.currentPage().getParameters().get('oppProdID'));
		return new Pagereference('https://' + ApexPages.currentPage().getUrl().substring(2,6) + 'salesforce.com' + '/' + oppProd);
	}
        
}

 Thanks again for any help in advance!

 

Jeremy Stender

StenderStender

Just a thought:  Instead of using the Sold_Accounts__c object to get those Account lookup fields to appear would it be possible to instead instantiate a list of a different object that  looks up to the accounts, but where the Account is NOT required for that object?  Then, when inserting the Sold Accounts just transfer the values in the account field on these objects to  the account field on the list of Sold Accounts I will be inserting.  I know this is a pretty messy way to do this so I am hoping to do it the RIGHT way.  But If I can't do that I will try to use this method.

 

Thanks,

Jeremy Stender

StenderStender

Nevermind,  I was able to do this by setting the required attribute on the inputfield(s)  to false.