-1

I am new to this community and I hope I will be clear in my support request.

I have a custom form that uses nested field collection items as follows:

>     form
>      form_field_a
>      form_field_b
>      form_field_collection_tenant (with unlimited values) - add another item
>        field_collection_user_details (with unlimited values)  - add another item
>          field_u1
>          field_u2 etc
>        field_collection_instance_details (with unlimited values)  - add another item
>          field_i1
>          field_i2 etc

I would like to add a functionality so that when "add another item" for field_collection_user_details is pressed it will do a custom callback and return field_collection_user_details with previous field values populated so I can manually update only one field value an leave the rest unchanged.

Or, have another button created with a custom ajax callback to clone previous field_collection_user_details filled on the first delta. (saves time for let's say a field collection with 10-20 fields that require only changing one or two field values)

I am updating my question: I have custom content type created which is being altered via hook_form_alter. begining of code pasted bellow: (is very long so I will just paste in until the relevant part)

function instanceform_form_plex_demand_node_form_alter(&$form, &$form_state, $form_id) {
drupal_add_css(drupal_get_path('module', 'instanceform') . '/css/instanceform.css', array('group' => CSS_DEFAULT, 'type' => 'file'));
$delta_i = 0;
$max_delta_i = $form['field_orig_tn']['und']['#max_delta'];
// we don't want to see additional settings block
$form['additional_settings']['#access'] = false;
$form['field_orig_tn']['und']['add_more']['#value'] = t('+');
$form['actions']['submit']['#attributes']['style'] = '-moz-border-radius: 5px; border-radius: 5px; width: 50px!important; height: 24px!important; background-color: #E60000; border: 1px solid #fff; line-height: 20px; font-size: 11px; text-align: center; color: #fff!important;';
while ($delta_i <= $max_delta_i) {
    $form['#tree'] = TRUE;
    $delta_j = 0;
    $delta_k = 0;
    $max_delta_j = $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ic']['und']['#max_delta'];
    $max_delta_k = $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['#max_delta'];
    // add custom class to select tags for tenant
    $form['field_orig_tn']['und'][$delta_i]['field_parent_nodes']['#access'] = FALSE;
    $form['field_orig_tn']['und'][$delta_i]['field_org_tn_en']['und']['#attributes']['class'][] = 'field-custom-select-tenant';
    $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ac']['und']['#attributes']['class'][] = 'field-custom-select-tenant';
    $form['field_orig_tn']['und'][$delta_i]['field_org_tn_lc']['und']['#attributes']['class'][] = 'field-custom-select-tenant';
    // add custom class to input tag for tenant
    $form['field_orig_tn']['und'][$delta_i]['field_org_tn_sn']['und'][0]['value']['#attributes']['class'][] = 'field-custom-input-tenant';
    $form['field_orig_tn']['und'][$delta_i]['field_org_tn_sn']['und'][0]['value']['#size'] = NULL;
    while ($delta_k <= $max_delta_k) {
        // add custom class to select tags for user
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_actions']['und']['#attributes']['class'][] = 'field-custom-select-user';
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_permission']['und']['#attributes']['class'][] = 'field-custom-select-user';
        // add custom class to input tag for user
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['und'][0]['value']['#attributes']['class'][] = 'field-custom-input-user';
        // hide the parent node field as we are not using it within the Plex demand form
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_parent_nodes']['#access'] = FALSE;
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['add_more']['#value'] = t('+');

        $delta_k++;
    }
    while ($delta_j <= $max_delta_j) {
        ....

What i would like to accomplish is to add another "add another item" (e.g.: $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['add_clone']) button that will clone the values previously filled by the user (for $delta_k = 0) and return the form (field collection item form) with $delta_k=1 having fields with the same values as in $delta_k = 0.

EDIT2: I have managed so far to add the second "add another item" button to the form however I cannot manage to set the default values in the ajax callback

In function instanceform_form_plex_demand_node_form_alter I have created the "add clone" button as follows:

 $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['#prefix'] = '<div id="field-clonefield-add-more-wrapper'. $delta_i . '">';
  $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['#suffix'] ='</div>';
  $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und']['add_clone']= array(
    '#type' => 'submit',
    '#value' => t('Add Clone'),
    '#submit' => array('0' => 'clone_field_add_more_submit'),
    '#name' => t('field_clonefield_add_clone'),
    '#limit_validation_errors' => array ( ),
    '#ajax' => array(
      'callback' => 'clone_field_add_more_js',
      'wrapper' => 'field-clonefield-add-more-wrapper'. $delta_i,
      'effect' => 'fade',
    ),
  );

Then i have added the submit and callback functions:

function clone_field_add_more_submit($form, &$form_state) {
  $button = $form_state['triggering_element'];
  // Go one level up in the form, to the widgets container.
  $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1));
  $field_name = $element['#field_name'];
  $langcode = $element['#language'];
  $parents = $element['#field_parents'];

  // Increment the items count.
  $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);

  $field_state['items_count']++;
  field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);

 >>>>>I THINK HERE IS WHERE THE DEFAULT VALUES SHOULD BE MODIFIED<<<<<

  $form_state['rebuild'] = TRUE;
}

function clone_field_add_more_js($form, $form_state) {
  $button = $form_state['triggering_element'];

  // Go one level up in the form, to the widgets container.
  $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1));
  $field_name = $element['#field_name'];
  $langcode = $element['#language'];
  $parents = $element['#field_parents'];

  $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);

  $field = $field_state['field'];
  if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
    return;
  }

  // Add a DIV around the delta receiving the Ajax effect.
  $delta = $element['#max_delta'];
  $element[$delta]['#prefix'] = '<div class="ajax-new-content">' . (isset($element[$delta]['#prefix']) ? $element[$delta]['#prefix'] : '');
  $element[$delta]['#suffix'] = (isset($element[$delta]['#suffix']) ? $element[$delta]['#suffix'] : '') . '</div>';

  return $element;
}
1

I have managed to achieve this. I will post the answer maybe someone will use id in the future.

It seems that it was quite simple.

i have created an ajax callback function:

function _user_ajax_check($form, $form_state) {
// load the user then     
$delta_tn  =$form['field_orig_tn']['und']['#max_delta'];
$delta_tn_ud = $form['field_orig_tn']['und'][$delta_tn]['field_org_tn_ud']['und']['#max_delta'];
$form_state['rebuild'] = TRUE;
return $form['field_orig_tn']['und'][$delta_tn]['field_org_tn_ud']['und'][$delta_tn_ud]['field_org_tn_ud_email'];}

The call with value assign:

$form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['und']['#prefix'] = '<div id="field-'. $delta_i .'-user-details-'. $delta_k . '-add-more-wrapper">';
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['und']['#suffix'] = '</div>';
        $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['#ajax'] = array(
          'callback' => '_user_ajax_check',
          'wrapper' => 'field-'. $delta_i .'-user-details-'. $delta_k . '-add-more-wrapper',
          'effect' => 'fade',
        );
        if (isset($form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['und'][0]['value'])) {
            if((isset($form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_cp_pre']['und'][0]['value'])) &&
                ($form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_cp_pre']['und'][0]['value'] == 1)) {
                $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k+1]['field_org_tn_ud_email']['und'][0]['value']['#value'] =
                        $form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_email']['und'][0]['value'];
                $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k+1]['field_org_tn_ud_actions']['und']['#default_value'][0] = 
                    $form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_actions']['und'][0]['value'];
                $form['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k+1]['field_org_tn_ud_permission']['und']['#default_value'][0] = 
                    $form_state['values']['field_orig_tn']['und'][$delta_i]['field_org_tn_ud']['und'][$delta_k]['field_org_tn_ud_permission']['und'][0]['value'];               
            }
        }

Result:enter image description here

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.