[SalesForce] Lookup with filters fails to display records on visualforce page

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

Class - MasterCamapaignId EQUALS Campaign - Parent Campaign Id


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 or CampaignId). 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 hidden div.

<apex:page controller="ClassFilterTestController">
    <apex:pageBlock>
        <apex:form>
            <div style="display: none;">
                <apex:inputField value="{!ChildCampaign.ParentId}" />
            </div>
            <apex:pageBlockSection>
                <apex:inputField value="{!ChildCampaign.Class__c}" />
            </apex:pageBlockSection>
        </apex:form>
    </apex:pageBlock>
</apex:page>

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.

Related Topic