1

I have a phone field in a form, which is just a textfield with its default widget. I'm trying (and failing) to add values to this field programmatically through ajax calls.

I have an ajax call elsewhere on the form, the purpose of which is to add several values to the phone (text) field, and let the user continue to edit them or add more.

My strategy in the ajax callback function has been to take the first textfield delta as a template, and reproduce it to add more. That's not working, because there are too many values to set that have side effects, like ['#delta'] or ['#max_delta']. The modules that manage this even seem to use #id suffixes to control behaviours.

The code below loads the values all right (3 of them show up on the form after the call), but when I press "Add another item", the field collapses from 3 values to 2. A subsequent "Add another item" call then opens up a blank new item, ie starts to behave normally. So something amiss after my ajax operation on the form structure, but gets reset with the first subsequent "Add another item" call. But I haven't been able to isolate what the problem is.

In any case, I think I'm using a bad strategy, and instead need some kind of helper function, or at least a strategy that conforms to Drupal-wide patterns.

So, how do I do this? I need a strategy or an example.

Here's my current ajax callback. The parts other than phone update are working, but the phone part is a mess. The phone part demonstrates what I want to do with updating phones, and the complexity shows why my current strategy isn't working for that phone part.

function rc_business_card_populate_from_staff($form,&$form_state)
{
       // ===============================================
       // THIS PART WORKS
    $selected_staff_id = $form_state['values']['line_item_fields']['field_staff']['und'][0]['profile_id'];
    if (is_null($selected_staff_id)) return $form; // do nothing
    // assemble input fields for data
    $address = &$form['line_item_fields']['field_recipient_address']['und'][0];
    $street_block = &$address['street_block'];
    $locality_block =  &$address['locality_block'];
    $organisation_block =  &$address['organisation_block'];
    $name_block =  &$address['name_block'];
    $values = array(
        // address field:
        'name_line' => &$name_block['name_line']['#value'],// Full Name
        'organisation_name' => &$organisation_block['organisation_name']['#value'], // Company
        'thoroughfare' => &$street_block['thoroughfare']['#value'], // Address 1
        'premise' => &$street_block['premise']['#value'],// Address 2
        'locality' => &$locality_block['locality']['#value'], // City
        'administrative_area' => &$locality_block['administrative_area']['#value'], // Province
        'postal_code' => &$locality_block['postal_code']['#value'],// Postal Code
        // independent fields:
        'field_designation' => &$form['line_item_fields']['field_designation']['und'][0]['value']['#value'], // Designation
        'field_email' => &$form['line_item_fields']['field_email']['und'][0]['email']['#value'],// Email
        'field_website' => &$form['line_item_fields']['field_website']['und'][0]['value']['#value'], // Website
        // phone field, independent:
    );
       // ===============================================
       // THIS PART DOESN'T WORK
    $field_phone = &$form['line_item_fields']['field_phone']['und'];
    $field_phone_template = $form['line_item_fields']['field_phone']['und'][0];
    // assemble input data
    $entities = entity_load('commerce_customer_profile',array($selected_staff_id));
    if (empty($entities)) return $form;
    $entity = reset($entities);
    $source_phones = $entity->field_phone['und'];
    $source_phones[2] = $source_phones[1];
    $source_phones[2]['value'] = 'test'; // ADD A THIRD VALUE FOR TESTING PURPOSES
    $phones = array();
    $length = count($source_phones);
        // HACKING - TRYING TO SET VALUES THAT MAKE THE TEXTFIELD BEHAVE - NOT WORKING
    foreach ($source_phones as $key => $source_phone) {
        $phones[$key] = $field_phone_template;
        $phones[$key]['value']['#value'] = $source_phone['value'];
        $phones[$key]['#delta'] = 
        $phones[$key]['#weight'] = 
        $phones[$key]['value']['#delta'] = 
        $phones[$key]['value']['#weight'] = 
        $phones[$key]['_weight']['#default_value'] = 
        $phones[$key]['_weight']['#value'] = $key;
        $phones[$key]['_weight']['#delta'] = $length + 1;
        $phones[$key]['value']['#id'] = 'edit-line-item-fields-field-phone-und-' . $key . '-value--' . ($length + 1);
        $phones[$key]['value']['#name'] = 'line_item_fields[field_phone][und][' . $key . '][value]';
        $phones[$key]['_weight']['#id'] = 'edit-line-item-fields-field-phone-und-' . $key . '-weight--' . ($length + 1);
        $phones[$key]['_weight']['#name'] = 'line_item_fields[field_phone][und][' . $key . '][weight]';
        $phones[$key]['#id'] = 'edit-line-item-fields-field-phone-und-' . $key;
    }
        // THIS SUCCESSFULLY LOADS THE DATA FOR PRESENTATION, BUT DOESN'T BEHAVE PROPERLY ON "Add another item"
    if (!empty($phones)) {
        foreach ($phones as $key => $phone) {
            $field_phone[$key] = $phone;
        }
        $form['line_item_fields']['field_phone']['und']['#max_delta'] = $length + 1;
//        $form['line_item_fields']['field_phone']['und']['add_more']['#id'] = 
//            'edit-line-item-fields-field-phone-und-add-more--' . ($length + 1);
        $form['line_item_fields']['field_phone']['#id'] = 'edit-line-item-fields-field-phone--' . $length;
    }
       // ===============================================
       // THIS REMAINING PART WORKS
    $source_address = $entity->commerce_customer_address['und'][0];
    $values['name_line'] = $source_address['name_line'];
    $values['organisation_name'] = $source_address['organisation_name'];
    $values['thoroughfare'] = $source_address['thoroughfare']; // Address 1
    $values['premise'] = $source_address['premise'];// Address 2
    $values['locality'] = $source_address['locality']; // City
    $values['administrative_area'] = $source_address['administrative_area']; // Province
    $values['postal_code'] = $source_address['postal_code'];// Postal Code
//    dpm($entity);
    // apply input data to input fields
//    $value = 'something';
//    $form['line_item_fields']['field_designation']['und'][0]['email']['#value'] = $value;
    dpm($form);
    $form['line_item_fields']['#suffix'] = rconnection_get_debug_data();
    return $form;
}

1 Answer 1

0

To answer my own question (it happens):

The critical part for the subsequent behaviour of "Add another item" is to set field_state['items_count'] (yes field state) for the NEXT ajax call from the "Add another item" button.

You can use this as a guide.

  • Henrik

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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