+ Start a Discussion
DrBixDrBix 

Controller Extends and VF Page with Empty Fields

I'm trying to create a controller extends and VF Page to enable custom product selection for quote line items.  However, for some reason, all of the fields inside of the related Quote object are empty.  I've created two sections of the VF Page and the controller extension to show this behavior.  The first section of the page does not work as I would think it should, and the second part does work becuase I load up the data in the constructor of the controller extension using SOQL.

 

 

Controller:

public class QuoteControllerExtension {
	private final   Quote quote;
        
	public String shippingState {get; set;}
	public String quoteName {get; set;}
	public ID 		quoteId {get; set;}
        
	public QuoteControllerExtension (ApexPages.StandardController stdController) {
		this.quote = (Quote)stdController.getRecord ();
                
			ID qid = System.currentpageReference ().getParameters ().get ('addTo');
			List<Quote> quotes = [select Id,Name,Opportunity.Account.shippingstate from Quote where id = :qid];
			this.quoteName = quotes[0].Name;
			this.quoteId = quotes[0].Id;
			this.shippingState = quotes[0].Opportunity.Account.shippingstate;
	}
        
	public String getTest () {
		return 'This is a test.';
	}
}

 

Page:

 

<apex:page standardController="Quote" extensions="QuoteControllerExtension">
  <body>
  <apex:sectionHeader title="Select Products for Quote: {!quoteName}" Subtitle="Product Selection"/>
    <br/>
    <h3>This SHOULD work but does not</h3>
    <br/>
    <apex:outputText value="Quote Id: {!Quote.Id}" />
    <br/>
    <apex:outputText value="Quote: {!Quote.Name}" />
    <br/>
    <apex:outputText value="Shipping State: {!Quote.Opportunity.Account.shippingstate}" />
    <hr/>
    <h3>This will work</h3>
    <br/>
    <apex:outputText value="Quote Id: {!quoteId}" />
    <br/>
    <apex:outputText value="Quote: {!quoteName}" />
    <br/>
    <apex:outputText value="Shipping State: {!shippingState}" />
    <br/>
    
  Enter your keyword and filter criteria, then click Search to begin your search. Click More filters to use more than one filter. Search results include all records that match both your keyword and filter 
  </body>
</apex:page>

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Shashikant SharmaShashikant Sharma

You must be providing an addTo in query parameter , just provide id also with it like this

 

yourpageName?id=salesforceidforquote&addTo=salesforceidforquote

 

Then it will work as Standard Controller takes fron id parameter in query string

All Answers

Shashikant SharmaShashikant Sharma

You must be providing an addTo in query parameter , just provide id also with it like this

 

yourpageName?id=salesforceidforquote&addTo=salesforceidforquote

 

Then it will work as Standard Controller takes fron id parameter in query string

This was selected as the best answer
DrBixDrBix

It is in there, I simply didn't post the URL to the page.  It comes from the "Add Line Item" button in the Quote page.  If it wasn't there, then NEITHER section of the page would work when, in fact, the 2nd section does work.

Shashikant SharmaShashikant Sharma

Just change your controller to this

public class QuoteControllerExtension {
	private final   Quote quote;
        
	public String shippingState {get; set;}
	public String quoteName {get; set;}
	public ID 		quoteId {get; set;}
        
	public QuoteControllerExtension (ApexPages.StandardController stdController) {
		this.quote = (Quote)stdController.getRecord ();
                if(this.quote.id != null)
                 {
                   this.quote = [select Id,Name,Opportunity.Account.shippingstate from Quote where id = :this.quote.id];
                  }

			ID qid = System.currentpageReference ().getParameters ().get ('addTo');
			List<Quote> quotes = [select Id,Name,Opportunity.Account.shippingstate from Quote where id = :qid];
			this.quoteName = quotes[0].Name;
			this.quoteId = quotes[0].Id;
			this.shippingState = quotes[0].Opportunity.Account.shippingstate;
	}
        
	public String getTest () {
		return 'This is a test.';
	}
}

 It will work for you.

DrBixDrBix

I'm really not sure I've made myself clear.  The part where I use SOQL shouldn't even be necessary if the quote is already loaded by the standard controller.  That's why I do the "getRecord()" call.  I shouldn't HAVE to load the quote fields.  Let's try this instead.  I'm going to repost the controller and the VF Page without the code that I already know works.  All you did was put a null check around code that already works without the null check.  I realize that's good preventive coding, and rightfully it should be there.  However, that part of the code already works.  Here's what does not work, and maybe this will make things clearer:

 

Controller:

 

public class QuoteControllerExtension {
  private final   Quote quote;
        
  public QuoteControllerExtension (ApexPages.StandardController stdController) {
    this.quote = (Quote)stdController.getRecord ();
  }
        
  public String getTest () {
    return 'This is a test.';
  }
}

 

 

Page:

 

<apex:page standardController="Quote" extensions="QuoteControllerExtension">
  <body>
  <apex:sectionHeader title="Select Products for Quote: {!quoteName}" Subtitle="Product Selection"/>
    <br/>
    <h3>This SHOULD work but does not</h3>
    <br/>
    <apex:outputText value="Quote Id: {!Quote.Id}" />
    <br/>
    <apex:outputText value="Quote: {!Quote.Name}" />
    <br/>
    <apex:outputText value="Shipping State: {!Quote.Opportunity.Account.shippingstate}" />
    <hr/>
  </body>
</apex:page>

 

 

 



Shashikant SharmaShashikant Sharma

You will get field in quote directly from standard controller but will not get related field of referenced object like this

Quote.Opportunity.Account.shippingstate , to fetch them you need to SOQL this. This is similar to that we have in triggers as well

in triggers : using trigger.new you can fetch fields of that object but not referenced objects fields.

 

Paul.FoxPaul.Fox

You just need a getter method so the visualforce page gets the quote. I'm not exactly sure why you didn't get an error when saving the visualforce page.

 

Add this to your apex class:

public Quote getQuote(){
   return quote;
}

Also, this is just a nitpick, but I recommend using variable names that aren't the same as the Object. It makes the code easier to read.

Shashikant SharmaShashikant Sharma

the reason why he did not get error while saving page is because he used the Quote as standard controller . In any case related fied can not come directly from standard controller need to SOQL to fetch them.

DrBixDrBix

Nothing comes from the Quote object.  Not the Id, not the Name, nothing, so are you saying that "NO" fields come from the underlying controller's object even when I call getRecord() ?

 

And, as Shashikant pointed out, I'm using the Quote object as the controller so I shouldn't have to have a getter nor should I have to retrieve any Quote fields unless I'm missing something.  No?

Shashikant SharmaShashikant Sharma

I just replicated this and succesfully saw the results for id and name but not for sipping state as it is related field.

 

are you passing 

id=0Q090000000PVCz as query parameter,

 

My URL was  : https://c.ap1.visual.force.com/apex/StandardControllerQuote?id=0Q090000000PVCz

In this url "StandardControllerQuote" is vf page name

 

please give your URL that you are hitting or getting

Paul.FoxPaul.Fox

Ok, that makes sense. However, I think he's right, if the field is in the visualforce markup, it should be included in the getRecord().

 

I just checked the Salesforce documentation, and that's what it says:

Note that only the fields that are referenced in the associated Visualforce markup are available for querying on this SObject. All other fields, including fields from any related objects, must be queried using a SOQL expression.

 

DrBixDrBix

I believe that the problem lies in the id being passed in the URL.  The button that calls this is the "Add Line Item" button from the quote page.  The ID of the quote is passed in as "addTo" not "id."  That is, more than likely, the issue.

 

As for the related item not coming up, I too read that exact Note and thought that it "should" work since I'm referencing it in the VFP.

Shashikant SharmaShashikant Sharma

just change the qurey parameter name or have another parameter id , I suggested you this in my first post. You have to query the related field. 

DrBixDrBix

Ok, so I made the following modification to the constructor:

 

		Map<String,String> theParameters = System.currentPageReference().getParameters();
		theParameters.put ('id', theParameters.get ('addTo'));
		this.quote = (Quote)stdController.getRecord ();

 so that now, the controller looks like this:

public class QuoteControllerExtension {
	private final   Quote quote;
        
	public QuoteControllerExtension (ApexPages.StandardController stdController) {
		Map<String,String> theParameters = System.currentPageReference().getParameters();
		theParameters.put ('id', theParameters.get ('addTo'));
		this.quote = (Quote)stdController.getRecord ();
	}
        
	public String getTest () {
		return 'This is a test.';
	}
}

 

and of course I updated the VFP to remove the Quote.name reference.  Now EVERYTHING works perfectly, even the related field (as I would have hoped it would).

 

The problem boiled down to the parameter being "addTo" and not "id."  The small piece of code simply adds the "id" parameter to the map of parameters and uses the "addTo" parameter as the source.

 

Thanks for your help guys.

 

 

 

 

 

 

Shashikant SharmaShashikant Sharma

Gr8, thats what community is all about to talk over thing, learn things and resolve issue.

 

In my first post I said

 

Then it will work as Standard Controller takes fron id parameter in query string

You must be providing an addTo in query parameter , just provide id also with it like this

 

yourpageName?id=salesforceidforquote&addTo=salesforceidforquote

 

I would request you to mark it as solution so that other's can also benifit from this.

 

DrBixDrBix

Done.  However, it's good to know that you can access related fields in the VFP.