I've got a visualforce page with a lookup field with a filter on the field. The field is looking for a Class__c
object, which has a Master-Detail relationship with Campaigns, and is created under a Parent Campaign. The filter on the field checks to make sure that the shown classes are have the same Master_Campaign__c
as the child Campaigns ParentId
.
On standard detail pages, this works without an issue. However, on this visualforce page, the lookup displays no available values.
Page
<apex:page controller="ClassFilterTestController">
<apex:pageBlock>
<apex:form>
<apex:pageBlockSection>
<apex:inputField value="{!ChildCampaign.Class__c}" /> <!-- Shows no records available -->
</apex:pageBlockSection>
</apex:form>
</apex:pageBlock>
</apex:page>
Controller
public class ClassFilterTestController {
public Campaign childCampaign { get; set; }
private final RecordType childCampaignRecordType = [SELECT Id, Name, DeveloperName FROM RecordType WHERE DeveloperName = 'Child_Campaign'];
public ClassFilterTestController() {
Id MasterCampaignId = (Id)ApexPages.currentPage().getParameters().get('MasterCampaignId');
ChildCampaign = new Campaign(ParentId= MasterCampaignId, RecordTypeId= childCampaignRecordType.Id);
// Returns 1
System.debug([SELECT COUNT() FROM Class__c WHERE Master_Campaign__c = :ChildCampaign.ParentId]);
}
}
Filters on field
I've also tried a method using the Standard Controller for Campaigns, but the behavior is unchanged.
StandardController Page
<apex:page standardController="Campaign" extensions="ClassFilterTestController">
<apex:pageBlock>
<apex:form>
<apex:pageBlockSection>
<apex:inputField value="{!Campaign.Class__c}" />
</apex:pageBlockSection>
</apex:form>
</apex:pageBlock>
</apex:page>
Controller Extension
public class ClassFilterTestController {
public ClassFilterTestController(ApexPages.StandardController s) {
Id MasterCampaignId = (Id)ApexPages.currentPage().getParameters().get('MasterCampaignId');
s.getRecord().put('ParentId', MasterCampaignId);
System.debug([SELECT COUNT() FROM Class__c WHERE Master_Campaign__c = :(Id)s.getRecord().get('ParentId')]); // Returns 1
}
}
Best Answer
Figured out a method around the filter madness. A few related questions (Problem with Visualforce Page and Field Filters based on RecordType, Account lookup on Opportunity not filtered correctly from Visualforce page) showed up in my first searches on the matter, but I dismissed them due to the questions referring to a RecordType in the filter, not a related object.
After a bit more research, I ended up clicking on one and found the solution to both of those seemed to be adding
apex:inputField value="{!SomeObject.RecordTypeId}"
to the page, somewhere. It seems as though adding the object to the visualforce layout allows Salesforce to access the data used for the lookup filter, otherwise, it has no data for those fields, despite the data being present in the controller.Following this logic, placing the related id field for the object being filtered in the lookup would allow the visualforce to have access to the objects data, regardless of the type (
RecordTypeId
orCampaignId
). A quick test with the field on the layout confirmed that adding the related object lookup onto the visualforce layout re-enables the filter functionality.Ultimately, I ended up placing the field outside of the
apex:pageBlockSection
, and hiding it in a hiddendiv
.Interestingly, using the standard controller on the page does not perform correctly. My assumption would be that the Standard Controller would be able to access the data easily, and allow the filter through, without it being on the page, but that seems to be incorrect.