Whenever I change the country it removes all the hook_form_alter changes and conditions. Even I have set my own submit callback which is removed when I change the country.

I am using profile2 module and creating form using following custom code.

//load user personal contact profile form
    global $user;
    $profile2 = profile2_by_uid_load($user->uid, 'personal_contact_info');
    $entity_form = entity_ui_get_form('profile2', $profile2, 'edit');
    drupal_set_title(t('Personal and contact info'));

    //render drupal form
    return drupal_render($entity_form);

Now when ever I make country change request using ajax remove my following alter set:

unset($form['actions']['submit']);
unset($form['actions']['delete']);
$form['field_company_search'] = array(
      '#title' => htmlspecialchars_decode($title) . '<span title="This field is required." class="form-required">*</span>',
      '#type' => 'textfield',
      '#maxlength' => 60,
      '#autocomplete_path' => 'org/autocomplete',
      '#description' => check_plain($description)
    );

Please help?

Comments

chera.jaswinder created an issue. See original summary.

Jaypan’s picture

Issue summary: View changes
Jaypan’s picture

Issue summary: View changes
Jaypan’s picture

You need to show what functions that code is in. The function name/hook name provides context, without it, we have no idea how this code is going to affect anything.

chera.jaswinder’s picture

Following is the function in address field module due to which when request is made from address plugin it causes to change in the form as describe above. If you need any further information please let me know.

<?php
/**
 * Ajax callback in response to a change of country in an address field.
 *
 * The only thing we have to do is to find the proper element to render.
 */
function addressfield_standard_widget_refresh($form, $form_state) {
  // The target element is one element below the triggering country selector.
  $array_parents = $form_state['triggering_element']['#array_parents'];
  array_pop($array_parents);

  // Iterate over the form parents to find the element.
  $element = $form;
  foreach ($array_parents as $name) {
    $element = &$element[$name];
    if (!empty($element['#addressfield'])) {
      break;
    }
  }

  // Return the address block, but remove the '_weight' element inserted
  // by the field API.
  unset($element['_weight']);

  // Replace the address field widget with the updated widget and focus on the
  // new country select list.
  $commands[] = ajax_command_replace(NULL, render($element));
  $commands[] = ajax_command_invoke('#' . $element['country']['#id'], 'focus');
  // Add the status messages inside the new addressfield's wrapper element,
  // just like core does.
  $commands[] = ajax_command_prepend(NULL, theme('status_messages'));

  // Allow other modules to add arbitrary AJAX commands on the refresh.
  drupal_alter('addressfield_standard_widget_refresh', $commands, $form, $form_state);

  return array('#type' => 'ajax', '#commands' => $commands);
}
?>
Jaypan’s picture

You showed us different code in this new post. You need to show the code from the original post, but show what functions it is in.

chera.jaswinder’s picture

ok let me put each and everything in front of you.

I created a profile form using profile 2 module.

I need to show the same form on some another page so I used following code to show my form.

<?php
//load user personal contact profile form
    global $user;
    $profile2 = profile2_by_uid_load($user->uid, 'personal_contact_info');
    $entity_form = entity_ui_get_form('profile2', $profile2, 'edit');
    drupal_set_title(t('Personal and contact info'));

    //render drupal form
    return drupal_render($entity_form);
?>

I altered my form using hook_form_alter() as mentioned earlier like removing submit button and providing my own submit buttons and its related functionality.

I added address field in while creating profile fields using address_field module.

If you are aware of address field module it provides us power to add another plugin so following is the plugin part which makes call to the ajax function known as addressfield_standard_widget_refresh

<?php
$format['country'] = array(
    '#title' => t('Country'),
    '#options' => _addressfield_country_options_list(),
    '#render_option_value' => TRUE,
    '#required' => TRUE,
    '#attributes' => array(
      'class' => array('country'),
      'autocomplete' => 'country',
    ),
    '#weight' => 100,
  );
// AJAX enable it.
    $format['country']['#ajax'] = array(
      'callback' => 'addressfield_standard_widget_refresh',
      'wrapper' => $format['#wrapper_id'],
    );
?>

Called function looks like this which is contained in address_field.module file

<?php
/**
 * Ajax callback in response to a change of country in an address field.
 *
 * The only thing we have to do is to find the proper element to render.
 */
function addressfield_standard_widget_refresh($form, $form_state) {
  // The target element is one element below the triggering country selector.
  $array_parents = $form_state['triggering_element']['#array_parents'];
  array_pop($array_parents);
  
// Iterate over the form parents to find the element.
  $element = $form;
  foreach ($array_parents as $name) {
    $element = &$element[$name];
    if (!empty($element['#addressfield'])) {
      break;
    }
  }
  
// Return the address block, but remove the '_weight' element inserted
  // by the field API.
  unset($element['_weight']);
  
// Replace the address field widget with the updated widget and focus on the
  // new country select list.
  $commands[] = ajax_command_replace(NULL, render($element));
  $commands[] = ajax_command_invoke('#' . $element['country']['#id'], 'focus');
  // Add the status messages inside the new addressfield's wrapper element,
  // just like core does.
  $commands[] = ajax_command_prepend(NULL, theme('status_messages'));
  
// Allow other modules to add arbitrary AJAX commands on the refresh.
  drupal_alter('addressfield_standard_widget_refresh', $commands, $form, $form_state);
  return array(
'#type' => 'ajax', '#commands' => $commands);
}
?>

All form alter setting done using hook_form_alter are removed. Speacilly i added one text field to a form using hook_form_alter().

Problem is:

Till the time I am submitting the form without making ajax hit it is working fine. Moment I make ajax hit and then re-submit the form submit button which was unset starts appearing and text field which i have added to form using hook_form_alter is removed.

I am not able to understand how to restrict all this? Its urgent please help. Hope it clears everything now.

chera.jaswinder’s picture

Hey Jaypan,

It was my mistake at hook_form_alter().

Actually I have put some condition to call my alter function only if current path is equivalent to "verify/personal" path.

When we make ajax call it always set path to "system/ajax" due to which my alter conditions were not called. My bad.

Anyways, Thanks for your help. Keep doing great work.

Regards,
Jaswinder

Jaypan’s picture

Status: Active » Fixed

I'm glad you figured it out!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

koushiknaikel’s picture

I am new in drupal,
I am using this code bellow on tpl file.

//load user personal contact profile form
    global $user;
    $profile2 = profile2_by_uid_load($user->uid, 'genarel');
    $entity_form = entity_ui_get_form('profile2', $profile2, 'edit');
    return drupal_render($entity_form);

but when I want to change country then Address field remove.
please help me what will be exact code ?