I am not seeing my results from my code on trying to alter form values for the Shipping/Billing default_values. I have a two-step checkout process in which the first checkout page/pane (a custom addition in my module) captures 5 important customer fields that I want to be able to re-use in the Shipping/Billing form. I deposit this information into $order->data and pass it into the $form upon submission. I can output the changes to the form in devel but the data is not being displayed on the form itself under the Shipping/Billing fields.

This is the code I'm using presently:

function my_module_form_alter(&$form, $form_state, $form_id)  {
    if($form_id == "commerce_checkout_form_checkout"){
//        $form['cart_contents']['#title'] = "My Deals";
        $checkout_page = commerce_checkout_pages();
        $checkout_page = $checkout_page['checkout'];
        foreach (commerce_checkout_panes(array('enabled' => TRUE, 'page' => $checkout_page['page_id'])) as $pane_id => $checkout_pane) {
            if ($callback = commerce_checkout_pane_callback($checkout_pane, 'checkout_form')) {
                // Generate the pane form.
                $pane_form = $callback($form, $form_state, $checkout_pane, $form_state['order']);
dpm($form);

  $holder = $form_state['order']->data;

  $name = $holder['ShippingFirstName'] . ' ' .  $holder['ShippingLastName'];

$form_state->values['customer_profile_shipping']['commerce_customer_address']['und'][0] = array(
    
    'name_line' => $name,
);
            }
        }
    }
}

Comments

generalconsensus’s picture

Category: support » feature
Priority: Minor » Normal

I would love to hear from the community on this.

marcin.wosinek’s picture

Category: feature » support
Status: Active » Closed (fixed)

Culprit for not seeing changes will be the first line:
function my_module_form_alter(&$form, $form_state, $form_id) {

You are missing:
hook_form_alter(&$form, <strong>&</strong>$form_state, $form_id)

When you have & before parameter it's used by reference - so all changes done locally in function are done in original object. Without it, you are just changing local copy of $form_state.

generalconsensus’s picture

wow that was a pretty silly mistake, glad you noticed that. Sadly I still haven't been able to push new values to items like:

$form_state['field']['#parents']['customer_profile_shipping']['#fields']['commerce_customer_address']['und']['field']['columns']['name_line']['default'] = 'test';

generalconsensus’s picture

The answer is in altering $elements within the hook below. Address field does not allow you alter values or defaults directly in the form or form_state but rather in the addressfield_standard_form_alter :)

hook_field_widget_addressfield_standard_form_alter(&$element, &$form_state, &$context){
}
John Pitcairn’s picture

Status: Closed (fixed) » Active

I'd like to see an actual working example of how to use hook_form_commerce_checkout_form_checkout_alter() to set default values for a custom field (not addressfield) within the customer_profile_billing pane. The $form_state structure for this is utterly bewildering to me.

I have a process that begins with a custom form. This adds items to the user's cart in its submit function, then redirects to checkout. I've added a button to the checkout pane which takes the user back to my form and repopulates it for editing, now I'd like to repopulate the checkout form with any values that the user entered prior to going back.

rszrama’s picture

I'm afraid such support is out of the scope of this issue queue. The real problem you're going to have is in trying to recover these form values that were not saved anywhere; I'm not sure your problem as described is feasible. Your best bet will be real-time chat in a Drupal IRC channel like #drupal-support or #drupal-commerce. The only leads I can give you are $form_state['values'] will have validated form input in it when a form is submitted, so you can probably cache the data you want in the session during the redirect and then extract those values and set them as the #default_value of the related form elements in $form on return to the checkout form.

rszrama’s picture

I'm afraid such support is out of the scope of this issue queue. The real problem you're going to have is in trying to recover these form values that were not saved anywhere; I'm not sure your problem as described is feasible. Your best bet will be real-time chat in a Drupal IRC channel like #drupal-support or #drupal-commerce. The only leads I can give you are $form_state['values'] will have validated form input in it when a form is submitted, so you can probably cache the data you want in the session during the redirect and then extract those values and set them as the #default_value of the related form elements in $form on return to the checkout form.

John Pitcairn’s picture

Status: Active » Closed (fixed)

Understood, thanks. I'm already caching relevant $form_state data in the session and retrieving that, in both directions. It's finding and setting the appropriate checkout pane $form or $form_state values that is proving more than a little frustrating. I'll post back here if I get it working, since this issue is one of the few results for a relevant google search on the subject.

rszrama’s picture

Sorry for the double post earlier. Not sure what happened. : P

If you have the Devel module on your site, you can do a dpm($form); to get a handy collapsed browser of the $form array. Then you can step through to the precise form elements you're going to want to alter. That's how I tend to find the right things to alter.

generalconsensus’s picture

@John Pitcairn

Just as reference here is my code as how I was able to autopopulate the shipping/billing fields. You have to figure I'm dumping my custom values into the order array for portability.


function test_field_widget_addressfield_standard_form_alter(&$element, &$form_state, &$context) {

    if ($element['#bundle'] == 'shipping') {
        global $user;
        $order = commerce_cart_order_load($user->uid);
        if (!empty($order->data)) {

        $countrylist = array(
        'AT' => t('Austria'),
        'AS' => t('American Samoa'),
        'BE' => t('Belgium'),
        'BG' => t('Bulgaria'),
        'CA' => t('Canada'),
        'CY' => t('Cyprus'),
        'CZ' => t('Czech Republic'),
        'DK' => t('Denmark'),
        'EE' => t('Estonia'),
        'FI' => t('Finland'),
        'FR' => t('France'),
        'DE' => t('Germany'),
        'GR' => t('Greece'),
        'GU' => t('Guam'),
        'HU' => t('Hungary'),
        'IE' => t('Ireland'),
        'IT' => t('Italy'),
        'LV' => t('Latvia'),
        'LT' => t('Lithuania'),
        'LU' => t('Luxembourg'),
        'MT' => t('Malta'),
        'NL' => t('Netherlands'),
        'NO' => t('Norway'),
        'PL' => t('Poland'),
        'PR' => t('Puerto Rico'),
        'PT' => t('Portugal'),
        'RO' => t('Romania'),
        'SK' => t('Slovakia'),
        'SI' => t('Slovenia'),
        'ES' => t('Spain'),
        'SE' => t('Sweden'),
        'CH' => t('Switzerland'),
        'GB' => t('United Kingdom'),
        'US' => t('United States'),
        'UM' => t('United States Minor Outlying Islands'),
        'VI' => t('U.S. Virgin Islands'),
    );
            if (isset($order->data['self']['country'])) {
                if (array_key_exists($order->data['self']['country'], $countrylist)) {
                    $element['#address']['first_name'] = $order->data['self']['FirstName'];
                    $element['#address']['last_name'] = $order->data['self']['LastName'];


                    $handlers = array('address' => 'address'); //There are other formats, but this one will output the mailing address.
                    $context = array('mode' => 'form');

                    $address = array(
                        'country' => $order->data['self']['country'],
                        'name_line' => '',
                        'first_name' => '',
                        'last_name' => '',
                        'organisation_name' => '',
                        'administrative_area' => '',
                        'sub_administrative_area' => '',
                        'locality' => '',
                        'dependent_locality' => '',
                        'postal_code' => '',
                        'thoroughfare' => '',
                        'premise' => '',
                        'sub_premise' => '',
                        'data' => '',
                    );

//Now generate the render array, where $addressfield_object is your addressfield, of course
                    $address_rendered = addressfield_generate($address, $handlers, $context);
//Now all you have to do is use drupal_render to create the output, and voila!
                    $element['street_block'] = $address_rendered['street_block'];
                    $element['locality_block'] = $address_rendered['locality_block'];
                    $element['country'] = $address_rendered['country'];
//Override the country option list
                    $element['country']['#options'] = array($order->data['self']['country'] => $onepointo_countrylist[$order->data['self']['country']]);


                }
            }
        }
    }
}
John Pitcairn’s picture

Ah, there's my problem. I was attempting to replace relevant parts of the $form_state variable with the cached parts, set $form_state['rebuild'] and have the form automagically repopulate itself just like standard form. Which won't fly, because I'm in hook_form_alter(), not the form builder. Well, it was 2am ;-)

So to pursue that approach and avoid manually repopulating lots of fields in $form, I guess I could try:

1 - implement hook_commerce_checkout_router() and route to a custom menu item
2 - the page callback for that calls drupal_get_form() for a custom form builder
3 - which itself calls commerce_checkout_form($form, &$form_state, $order, $checkout_page), supplying the cached $form_state.

Feasible?

John Pitcairn’s picture

Issue summary: View changes

changed the php code to be consistent with original code

mrweiner’s picture

Anybody else landing here looking to alter the addressfield default values, you have the option of hook_addressfield_default_values_alter(&$default_values, $context) -- http://cgit.drupalcode.org/addressfield/diff/?id=bb4b1d9&id2=00476fb755e...