I have a visualforce page with the standardController to a custom object.
I want to get all orders (Orders__c) from an event (Event__c). I started by the offer (Offer__c)
Offer is in master-detail with the event and the event is in master-detail with the orders.
I have tried two following codes:
<apex:page standardController="Caterer_Offer__c" sidebar="false" showHeader="false" >
<apex:repeat var="events" value="{!Caterer_Offer__c.Event__r}">
{!events.Name}
<apex:repeat var="orders" value="{!events.Orders__r}">
<!-- {!orders.Name}-->
</apex:repeat>
</apex:repeat>
At this the error-message in the developer console is:
"Aggregate Relationship is used in an unsupported complex expression containing 'Event__r.orders__r'"
And...then I have trief to save the event and use a new variable to "repeat" all orders. I get no error message, but a error in Salesforce
<apex:page standardController="Caterer_Offer__c" sidebar="false" showHeader="false" >
<apex:repeat var="events" value="{!Caterer_Offer__c.Event__r}">
{!events.Name}
<apex:variable var="e" value="{!events}"/>
<apex:repeat var="orders" value="{!e.Orders__r}">
<!-- {!orders.Name}-->
</apex:repeat>
</apex:repeat>
Error-message: SObject row was retrieved via SOQL without querying the
requested field: Event__c.Orders__r
I cannot explain it and work on it since a few hours....
A standardcontroller's record will only contain the fields referenced in the visualforce page you're using it on. You may need to use a custom controller and extend features of standard controller in these cases. The standard controller addFields() method allows you to extend this to the fields you need in your apex code.
I could find a similar solution here.
I'm not sure from your question which object is the Parent record and which is the child, but my answer is going to be based on Caterer_Offer__c being the parent of Event__c and Event__c being the parent of Order__c, so that you can loop through all Orders for an Event for a Catered Offer which is what I think you want to do.
In short what you are trying to do cannot be done in the way you are trying it is because you are in essence trying to perform a child aggregate query that is two levels deep. In essence you are trying to do:
[SELECT Name, (SELECT Name, (SELECT Name FROM Orders__r) FROM Events__r) FROM Caterer_Offer__c];
However salesforce only allows aggregate child queries one level deep, not more. So you have to add an extension that would have code to probably lazy-load the Orders on an event of some sort with a partial page re-render on a link click or button click. In that case you would make the Visualforce page for the Caterer_Offer__c and child Events__c, then load the child Orders from some user action that calls the extension with a element using the id of the selected Event.
But for the error you specifically asked about it would have been:
<apex:page standardController="Caterer_Offer__c" sidebar="false" showHeader="false" >
<apex:repeat var="event" value="{!Caterer_Offer__c.Events__r}">
{!event.Name}
<apex:repeat var="order" value="{!event.Orders__r}">
{!order.Name}
</apex:repeat>
</apex:repeat>
</apex:page>
But again that's not possible because of the aforementioned single depth child aggregation query limitation in salesforce
Related
I have a picklist in my custom object. I am creating a visualforce page where different templates need to be embedded. In main VF page, I am iterating this custom object list, where in I have to pass picklist value to this apex:include's attribute "pagename". And I have visualforce pages whose name is same as this pick list value.
Below is the sample codes that I have tried so far but had no luck :
Code 1 --
<apex:page renderAs="pdf" controller="MyCheckLayoutController">
<apex:repeat value="{!listwrapper}" var="cl" >
<apex:include pageName="{!cl.check_layout_type}" > // cl.check_layout_type is variable in wrapper class and it is the name of visualforce page as well.
/* This gives error as variable not found. */
</apex:include>
</apex:repeat>
</apex:page>
Code 2 --
<apex:page renderAs="pdf" controller="MyCheckLayoutController">
<apex:repeat value="{!listwrapper}" var="cl" >
<apex:variable var="type" value="{!cl.check_layout_type}" />
{!type} // This variable contains value
<apex:include pageName="{!type}" >
/* But It doesnot read it's value here. It says pagename cannot be null*/
</apex:include>
</apex:repeat>
</apex:page>
I have tried many ways till now. It would be really great help if some one could answer.
Thanks.
So I actually gave this a try and it looks like the page name needs to be defined in the VF page or must be bound to a getter that return a page ref or a property that has get attribute that returns a page ref. It looks like it cannot be bound to the variable in a repeater. Maybe you should try to see if Dynamic Components might do the trick
I am new to SFDC, struggling to retreive parent objects fields through SOQL query on child object.
I have two objects namely Opportunity and Scope where Scope has a lookup to Opportunity.
Here is the query i have written in Controller.
ScopeController.cls:
List<Scope> scopeList=[Select id,Name,ScopeValue__c,Opportunity__c,Opportunity__r.opAmount__c from Scope__c];
System.debug('scopeList : '+scopeList);
Accessing the values of scopeList in below VF Page.
ScopePage:
<apex:repeat value="{!scopeList}" var="s">
<tr>
<td>{!s.Name}</td>
<td>{!s.ScopeValue__c}</td>
<td>{!s.Opportunity__c}</td>
<td>{!s.Opportunity__r.opAmount__c}</td>
</tr>
</apex:repeat>
But in the above VF Page not able to show the value of s.Opportunity__r.opAmount__c, it is empty. I debugged in Controller, the SOQL query itself not retrieving the value of "Opportunity__r.opAmount__c" hence shown empty in VF Page.
One reason could be that your profile does not have access to this field (Opportunity__r.opAmount__c).
Query looks fine to me. Do you see this value on the standard layout. Does your profile have access to this field?
From the management settings for the field’s object, go to the fields area.
Select the field you want to modify.
Click View Field Accessibility.
I'm new to Salesforce/Apex and I need to be able to test a component I am working on in a separate page.
Here is the scenario. I have the following test page:
<apex:page sidebar="false" showHeader="false" standardController="Contact">
<div id="wrapper" style="max-width:980px;">
<c:djEmailTemplate_MainComponent sObject="{!Contact}" theContactId="{!Contact.Id}"/>
</div>
</apex:page>
I can display the page by adding /apex/testpage to the url after the project name.
What I don't know how to do is to include data to satisfy the parameters (sObject, theContactId) that are needed to populate values in the component.
Can anyone explain how I can do this?
Thanks in advance.
Your test page uses the Contact object as its standard controller, so in most cases you would want to specify a Contact record for the page/controller to operate on. You can use any existing Contact record in your org, or create a new one (specifically you'll want to grab the ID of the record) and then append the ID to the URL you're using like so: /apex/testpage?id=003xxxxxxxxxxxx. This will provide the page and controller a record to pass to the VF component.
In my VF page I have a form which uses map of a hardcoded custom object for some operations (Schema.Sobjecttype.object1_c.fields.getMap()).
Now I want to repeat this same form three times in the same page each time it takes a different custom object.
<apex:page>
<apex:repeat .... give the 3 custom objects in a loop>
<apex: form>
//form code
</apex:form>
</apex:repeat>
</apex:page>
The form code is done inside a controller. So I want to know if I can give a list of sobjects to loop through and if yes then how?
Why don't you make the form a visualforce component and use the object name as a parameter for the component. Then in the component controller, load the getMap() for that object and show in the component.
How to hide a section of fields using a checkbox in visualforce pages?
Assuming the Salesforce approach (keeping the page weight down etc.), you could do something like the following:
<apex:inputCheckbox value="{!theBool}">
<apex:actionSupport event="onChange" action="{!myAction}" rerender="theFieldsPanel"/>
</apex>
<apex:outputPanel id="theFieldsPanel">
<apex:variable var="v" value="" rendered="{!theBool}">
<apex:inputField value="{!someField"} rendered/>
<!-- more fields etc. -->
</apex:variable>
</apex:outputPanel>
Note that I don't use the rendered attribute on the output panel itself, this is because if it's not rendered then it doesn't exist in the page, and as such, doesn't make for a good rerender target! Now you just require a simple action on the controller (you could do any other logic in here if need be):
public Pagereference myAction()
{
// any logic etc. goes here
return null;
}
The benefit of doing things this way, as opposed to with javascript is that you can ensure that if the fields are hidden then values won't be sent back to the controller for the variables they're bound to. Simply hiding things with javascript would not have the same effect, so say the user typed something in one of the fields and then hid them, whatever he/she typed would still end up in the related controller variables.