You need to sign in to do that
Don't have an account?
Visualforce/Apex question: filtering a related list on a custom object
I have a custom object (Properties__c) that is a related list item for Accounts. Since some of the properties have been sold, users only want to see the Active Properties in the related list for Acccounts. I have attempted to use the Account Standard Controller in Visualforce along with an extension to accomplish this:
My Visualforce page markup is as follows:
<apex:page sidebar="false" showHeader="false" StandardController="Account" extensions="ActProp">
<apex:pageBlock title="List of Properties">
<apex:pageBlockTable value="{!props}" var="a">
<apex:column value="{!a.Name}"/>
<apex:column value="{!a.Asset_Type__c}"/>
<apex:column value="{!a.RecordType.Name}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
My Controller extension is as follows:
public class ActProp{
public ActProp(ApexPages.StandardController cont) {}
List<Property__c> props = [Select Name, RecordType.Name, Asset_Type__c from Property__c where Status__c ='1'];
public List<Property__c> getprops(){
return props;
}
}
My Visualforce page an custom controller both save with no issues; however, when I run the Page with a valid account (one with properties), the only thing that is returned is the "List of Properties" Block Title. I have read through the VF documentation and viewed related YouTube videos to try to figure this out. I know that I am thisclose, but am missing an element. Any assistance would be greatly appreciated. Thank you.
My Visualforce page markup is as follows:
<apex:page sidebar="false" showHeader="false" StandardController="Account" extensions="ActProp">
<apex:pageBlock title="List of Properties">
<apex:pageBlockTable value="{!props}" var="a">
<apex:column value="{!a.Name}"/>
<apex:column value="{!a.Asset_Type__c}"/>
<apex:column value="{!a.RecordType.Name}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
My Controller extension is as follows:
public class ActProp{
public ActProp(ApexPages.StandardController cont) {}
List<Property__c> props = [Select Name, RecordType.Name, Asset_Type__c from Property__c where Status__c ='1'];
public List<Property__c> getprops(){
return props;
}
}
My Visualforce page an custom controller both save with no issues; however, when I run the Page with a valid account (one with properties), the only thing that is returned is the "List of Properties" Block Title. I have read through the VF documentation and viewed related YouTube videos to try to figure this out. I know that I am thisclose, but am missing an element. Any assistance would be greatly appreciated. Thank you.
All Answers
Perhaps if you use a property for the props, it will help. Something like this:
Don't forget to change the SOQL to also consider the Account Id later.
I revised my code to match yours, but I am still getting a blank page.
A question on your technique; does "{get;set} replace "getX()", "returnX" (shorthand?)
props = [Select id, Name, RecordType.Name, Asset_Type__c from Property__c where id=:ApexPages.currentPage().getParameters().get(id) and Status__c = 'Active'];
but am seeing an Error: ActProp Compile Error: Variable does not exist: id at line 4 column 133
again I am missing the syntax, but am not sure where .
Yes, using Property {get;set;} is a "shorthand" of the setter and getter methods.
in your controller constructor, you can read the record id since you are using the Account standard controller.
String accountId = cont.getId();
props = [Select Name, RecordType.Name, Asset_Type__c from Property__c where accountID=:ApexPages.currentPage().getParameters().get(id) and Status__c = 'Active'];
But I am seeing a "Variable does not exist: id at line 5 column 136". I think i am duplicating the "get(id)" method in the SOQL statement . Definitely falling down the rabbit hole.
I confirmed that the name of the linking field on the Property__c object is named Operator__c, so the key couplet is now:
String AccountID = cont.getId();
props = [Select Name, RecordType.Name, Asset_Type__c from Property__c where Operator__c=:accountId and Status__c = 'Active'];
This is still returning no records, however, so I still have something out of order.
And please make sure the query actually returns a record when you run it with Operator__c='<an_account_id>' AND Status__c = '1'
Lending my thoughts on this.
In your intial code: The id needs to be wrapped in quotes. The correct syntax would be: Since you are using a standard controller for your page, an alternate way to retrieve the account id value would be to use pre-defined methods available in the standard controller itself. Like the one provided by Raidan where cont is the variable name of the standard controller.
Needless to say, the query (and the page) would only work if you provide a valid account Id for the page to work with. Salesforce has some standard methods of passing the record id to a visualforce page. Some of these methods are:
1. When you embed a visualforce page in a page layout
2. When you call a visualforce page from a detail page button.
3. When you pass the record ID in the URL as a query string parameter. A sample format would be like ....force.com/apex/myVFPage?id=RecordIDGoesHere
As always, you can use the debug logs to inspect why your apex code is not working as desired. The debug logs will display the SOQL that was executed and the number of rows it returned. You can also use the system.debug() method to print custom messages on the log file. This can help to inspect the values passed to the SOQL (in this case the account ID).
Give it a try and let us know how it goes.
Select Name, RecordType.Name, Asset_Type__c, from Property__c where Operator__c ='0015500000CQxfq' and Status__c = 'Active'
This gives me a good starting place tomorrow morning.
To summarize (for any others looking for sample code for a filter on a related field), the answer for my issue is as follows:
Visual Force Page
<apex:page sidebar="false" showHeader="false" StandardController="Account" extensions="ActProp">
<apex:pageBlock title="List of Properties">
<apex:pageBlockTable value="{!props}" var="a">
<apex:column value="{!a.Name}"/>
<apex:column value="{!a.Asset_Type__c}"/>
<apex:column value="{!a.RecordType.Name}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
Apex Class
public class ActProp{
public List<Property__C> props {get;set;}
public ActProp(ApexPages.StandardController cont) {
String AccountID = cont.getId();
props = [Select Name, RecordType.Name, Asset_Type__c from Property__c where Operator__c=:accountId and Status__c = 'Active'];
}
}
Now all that remains to complete the facsimile Related List page is to add the "New Properties" button and "Hover Help" that the current Related List has. But that can wait until morning!
Thank you again, Raidan, for a lot of instruction, but even more patience.
The purpose of this is to create a Visualforce page that is a filtered related list that can replace the standard related list with all of the functionality of the standard list. While the data output by the class is perfect (thank you again a million times for that!), it is missing those standard bells and whistles of the related list that is part of the account standard controller:
- The "New Record" Button at the top of the related list section
- Hyperlinks which take the user to the specific record (with Open in New Window option)
- The "Action" Column on the left with its Edit and Delete options
- Hover help in the upper right hand corner of the related list box
- The "Show More" items at the bottom of the related list box
Right now, my output is just the list.My question is, which is the best route to provide these: continue building out the Visualforce page with these features, or was I going about this all wrong - should I have built out the class then used that class to override the values returned in the Standard Account Related List. It would be cool to work through delivering on these bullet point items, but if overriding the Related List values is the better option, that works as well.
VF
<apex:page controller="PropertyList2Con">
<apex:pageBlock >
<apex:pageBlockTable value="{!Property}" var="p">
<apex:column value="{!p.name}"/>
<apex:column value="{!p.Asset_Type__c}"/>
<apex:column value="{!p.RecordType.Name}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
Apex
public class PropertyList2Con {
List<Property__c> proplst=[select name, RecordType.Name, Asset_Type__c from Property__c];
ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(proplst);
public List<Property__c> getProperty() {
return (List<Property__c>) ssc.getRecords();
}
}
This returned a list in good form:
Property Name Asset Type Name Property1 Assisted Living Seniors Housing
Property 2 Assisted Living Seniors Housing
Property 3 Assisted Living Seniors Housing
The problem is still the same as with the previous VF Page/Apex Class; it returns a flat list with none of the pieces (The "New Record" Button, Hyperlinks, Action Column) that the Standard Related List has. Is there additional markup that I have to do, or does the SSC have its own functionality that activates this? Thanks yet again.