2

I have been using a visualforce tab to override the default "Recent Order" list view for a custom object "orders__c"

Following is my code...

 <apex:page >
    <script type="text/javascript">
      parent.frames.location.replace("/a0q?fcf=00BK0000000yabc");                                          
 </script>
</apex:page>

I face problem everytime I migrate because of hardcoding the list-view id.

Is there a better or out of the box solution? Thanks in advance.

EDIT: I also came across this great hack by deepak. But then again the hardcoding issue arises.

1 Answer 1

2

I don't entirely agree with implementing JS as the solution, but independent of that, you can use a Hierarchy Custom Setting (documentation) and merge in a value from it:

parent.frames.location.replace("{!$Setup.Order_Settings__c.Recently_Viewed__c}");

EDIT

You could also get the Id more programmatically by using ApexPages.StandardSetController. Take a look at the getListViewOptions method, it gives you back a List<SelectOption>. Each represents a List View with value=Id and label=Name.

Service

The below is a rudimentary and generic attempt to pair an sObjectType with a List View Name and come up with its Id and also a corresponding URL.

public with sharing class ListViewServices
{
    public static String getId(SObjectType sObjectType, String name)
    {
        List<SObject> records = new List<SObject> { sObjectType.newSObject(); }
        ApexPages.StandardSetController controller =
            new ApexPages.StandardSetController(records);
        for (SelectOption listView : controller.getListViewOptions())
        {
            if (listView.getLabel() == name) return listView.getValue();
        }
        return '';
    }
    public static String getUrl(String sObjectType, String name)
    {
        if (String.isBlank(sObjectType) || String.isBlank(name)) return null;

        SObjectType schemaType = Schema.getGlobalDescribe().get(sObjectType);
        this.relativeBaseUrl = String.format('/{0}?fcf={1}', new List<String> {
            schemaType.getDescribe().getKeyPrefix(),
            getId(schemaType, name)
        });
    }
}

Controller

Using the above service in a specific controller should be trivial.

public with sharing class ListViewController
{
    public static final String TYPE_PARAM = 'sobjecttype';
    public static final String NAME_PARAM = 'name';

    public String listViewUrl { get; private set; }
    public ListViewController()
    {
        this.listViewUrl = ListViewServices.getUrl(
            ApexPages.currentPage().getParameters().get(TYPE_PARAM),
            ApexPages.currentPage().getParameters().get(NAME_PARAM)
        );
    }
}

VisualForce

This would change your Javascript specifically to:

var listViewUrl = "{!URLENCODE(listViewUrl)}";
if (listViewUrl) parent.frames.location.replace(listViewUrl);
3
  • One thing that flew through my mind when I see "hard coded ID" issues is sticking them in custom settings instead.. which works when they are an Apex issue which you can't change on production orgs.. but you still have to "set/update" them., and seeing as you can just do this to VF pages anyway, putting the ID in a setting is no more simpler than the overhead of updating it on the page, so how does it help? (that said. functioning answer so you can have my vote!) Dec 19, 2015 at 21:37
  • @SimonLawrence while changing a VF page in PROD is doable, the next time the VF page is deployed from sandbox, the prod edit is smashed and has to be repeated as a post deployment task. Custom setting is done once in PROD and is unlikley to change value across repeated deployments
    – cropredy
    Dec 20, 2015 at 23:37
  • 1
    @adrian-larson Thanks for the tip. I have been using custom settings ever since your suggested. Sorry for late acceptance of your answer. Cheers :)
    – MnZ
    Mar 31, 2016 at 9:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .