2

It is well-known that OrderItem doesn't support record types so you can't vary the page layout based on recordtype like you can for most other objects.

Given that OrderItem is a detail to Order, and Order does support record types, how might one override the OrderItem Edit page without using a VF controller redirect via a page action method?

That is, without recourse to:

Page that overrides the standard Edit button

<apex:page standardController="OrderItem" extensions="MyRedirector" 
   action="{!redirect}">
</apex:page>

and VF controller method:

PageReference redirect() {
  return isParentOrderOfRecordTypeX 
     ? new PageReference('/apex/PageOrderItemX')
     : new PageReference(this.id+'/e');
}

and the custom PageOrderItemX

<apex:page standardController="OrderItem">
   ... custom layout as needed ...
</apex:page>

That is, can this be done more elegantly with fewer components?

  • Possibly a duplicate of this question, but I leave it up to you to decide. – sfdcfox Sep 18 '18 at 2:09
  • @sfdcfox: figures you would remember your answer :-). I added this question for those who might vector in based on OrderItem which has its own idiosyncrasies. – cropredy Sep 18 '18 at 4:33
2

Here's one approach

Override the OrderItem Edit button with this page:

<apex:page id="OrderProductEdit" standardController="OrderItem" 
   action="{!IF(OrderItem.Order.RecordType.Name='X',
       NULL,
       URLFOR($Action.OrderItem.Edit,OrderItem.Id,null,true))}">

    <apex:variable value="{!OrderItem.Order.RecordType.Name}" var="rt"/> 

    ... custom markup for Order recordtype X's influence on OrderItem

</apex:page>

How does this work?

  • The apex:variable provides a merge field to the standardController to fetch the value of the parent object's RecordType.Name. Why do you have to do this? Because the standardController only fetches fields from OrderItem that are otherwise referenced by apex:inputField, apex:inputHidden, and apex:outputField. And you might not want to have fields from Order in the markup for the edit page. Merely putting the OrderItem.Order.RecordType.Name in the action attribute is not sufficient as the page will not compile.
  • The expression action="{!IF(OrderItem.Order.RecordType.Name='X', NULL, URLFOR($Action.OrderItem.Edit,OrderItem.Id,null,true))}"> can be understood as follows:

  • if the OrderItem's Order's recordtype is X, return NULL. This will display the markup for your page. No recourse required to a controller extension.

  • if the recordtype is not X, then URLFOR does a redirect to the standard Edit page for OrderItem. The second argument is the OrderItem Id to edit, the 3rd argument are any extra url parameters to pass to the standard edit page (none in this case) and the 4th argument true is the nooverride argument and tells SFDC not to go into an infinite loop because the standard Edit button is overridden

So - one VF page and no controller extension. One less thing to write a testmethod for.

Similar approach can be done for the standard View page with some caveats, notably certain related lists available on the standard view page aren't supported in VisualForce (like OrderItemHistories)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.