Conditional Panes are asked about quite extensively in the Drupal Commerce Issue Queues. We should provide an example of how to pragmatically execute conditional panes based on a user input. The following is the code to disable panes from view:

<?php
function my_module_commerce_checkout_pane_info_alter(&$checkout_panes)
{
    global $user;
    // load current order
    $order = commerce_cart_order_load($user->uid);

        foreach ($checkout_panes as $pane_name => &$pane_data) {
        
            // override the unneeded pane
            if ($pane_name == 'pane_to_override' && $pane_data['enabled']) {

                $pane_data['enabled'] = 0;
                
            }
        }
    }
?>

We should provide examples to users of how to use this in more complex situations. You see this referred to a lot in the context of shipping. Some products require shipping information and some don't. This is generally done by creating multiple products and then using the selected product to determine what panes should be displayed. However to allow for more complexity and promote strategies that are easier to maintain (not having 100's of products), we should show how to base this on a users choice during checkout. This could be something simple like asking a customer if they would like to add/extend their purchase in mid-checkout and collecting that information on the spot in a conditional pane. A simple example would be an event registration where during checkout you allow the user to addon dinner reservations should they choose. If they choose select yes then the registration pane shows, ect.

I would envision this done in a way similar to the following, with switch statements allowing for more complex set ups where they are multiple panes for different selections:

<?php
function my_module_commerce_checkout_pane_info_alter(&$checkout_panes, $form, &$form_state)
{
    global $user;

    // Get Selected Value from field in Pane that belongs to the Orders entity
    // If X value is selected then disable X pane
    if ($form_state['values']['my_field'] == 'disable_value') {

        foreach ($checkout_panes as $pane_name => &$pane_data) {

            // load current order
            $order = commerce_cart_order_load($user->uid);          
            
            // override the unneeded pane
            if ($pane_name == 'pane_to_override' && $pane_data['enabled']) {

                $pane_data['enabled'] = 0;
                
            }
        }
    }
}
?>

Comments

bobbyaldol’s picture

Assigned: Unassigned » bobbyaldol
JMOmandown’s picture

Status: Active » Needs review

The following is my solution to my above stated request:

<?php

function commerce_conditional_panes_commerce_checkout_pane_info_alter(&$checkout_panes, $form, &$form_state) {
    global $user;

    foreach($checkout_panes as $pane_name => &$pane_data) {

        // load current order
        $order = commerce_cart_order_load($user->uid);

        // retrieve the value of controlling field
        $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
        $control = $order->field_make['und']['0']['value'];

        // Perform switch to see what to do with each aircraft make
        switch ($control)
        {
           case "value1":
             
             break;
           case "value2":
             
             break;
           case "value3":
             
             break;
           case "value4":
             
             break;
           case "value5":
             
             break;
           case "value6":
             // ...we only need to override one of them
             if($pane_name == 'commerce_fieldgroup_pane__conditional_pane' && $pane_data['enabled']) {

               // the pane is enabled by default, so we need to disable it
               $pane_data['enabled'] = 0;
             }
             break;
           case "value6":
             
             break;
           case "value7":
             
             break;
           case "value8":
             
             break;
           default:
             break;
        }

    }
}
?>

If there is a large amount of possible panes, I suggest starting with them all disabled and only enabling the ones that are needed by using the following replacement:

<?php
if($pane_name == 'commerce_fieldgroup_pane__conditional_pane' && $pane_data['disabled']) {

               // the pane is enabled by default, so we need to disable it
               $pane_data['enabled'] = 1;
             }
?>

Further nested switches could be used for pulling values from fields that are dependent on other fields. Hope this helps someone down the road and hope to see a concrete example in the module!

bobbyaldol’s picture

Brilliant, I will definitely consider adding a solid example on this. This feature is like much sort after by many people.
Thanks for your interest, and if you have any more ideas for the module, you are welcome to add to the issue queue.

JMOmandown’s picture

@bobby do you think we could accomplish this on the pane_info declaration level? If the panes weren't existant unless the requirement was met it would boost performance greatly by saving the looping at the moment of the condition. Anotherwards only bring the panes into existence at the time the requirement is met instead of trying to disable all those that fail to meet the requirements in the end (beneficial for complex stores with many conditional panes)

JMOmandown’s picture

Issue summary: View changes

added php tags

Tim Bozeman’s picture

Issue summary: View changes