Steps:
I created a content type named as 'newname'.
I added two simple textfields as fields: 'name' and 'new_name'.
I created the module 'newname' and added the following code:

<?php
function newname_form_newname_node_form_alter(&$form, &$form_state) {
$form['field_new_name']['und'][0]['value']['#ajax'] = array(
      'callback' => 'newname_form_newname_node_form_callback',
      'wrapper' => 'edit-field-name',
);
if (!empty($form_state['values']['field_new_name'])) {
$form['field_name']['und'][0]['value']['#default_value'] = $form_state['values']['field_new_name']['und'][0]['value'];
}
return $form;
}
function newname_form_newname_node_form_callback($form, $form_state) {
  return $form['field_name'];
}

Expected behaviour:
When editing content of the content type 'newname' and writing a new name into the field 'new_name', this new name should be copied and shown in the field 'name' by AJAX.

What happened instead?
The new name is not copied, no change happens to the field 'name'.

Please see the screenshots.
before_ajax.jpg shows that initially the id of the div 'name' is 'edit-field-name'.
after_ajax.jpg shows that after typing 'Bryan' to 'new_name', the id of the div 'name' becomes 'edit-field-name--2'.
The ID should not change so we could see the right result.

Please advise or correct.

Comments

Priority:Critical» Normal

In Drupal 7, you basically can't target CSS using IDs because of this *feature* where IDs are always unique on a page. It may be controversial, but it's a feature, not a bug.

Sorry, I don't understand you. Could you be a bit more specific?
Help says: ''wrapper' is the HTML id of the page element that will be replaced. '
Example simplest: 'wrapper' => 'replace_textfield_div'. Isn't this an ID?
How else can I order AJAX then to replace the HTML element with the field 'name'?

Sorry, I didn't listen well enough in #2.

The canonical way to solve this problem is to place this in the replaceable section of the form:

'#prefix' => '<div id="some-unique-id">',
'#suffix' => '</div>',

and then in the #ajax:

'wrapper' => 'some-unique-id',

What you're doing (I think) is working with a wrapper which is a multivalue field, so that's a more complex thing. Drupal is trying to ensure that the ID is unique. You'll have to insert an ID that you control as a wrapper in there.

I'm not sure how you're going to solve this with a multivalue field like this, but the behavior you describe is in fact how Drupal deals with IDs on a page since #384992: drupal_html_id does not work correctly in AJAX context with multiple forms on page.

I'm not sure if you're telling me that changing the code the following way solves my problem, because it does not. :(

$form['field_new_name']['und'][0]['value']['#ajax'] = array(
      'callback' => 'newname_form_newname_node_form_callback',
      'wrapper' => 'my_unique_id',
);
$form['field_name']['und'][0]['value']['#prefix'] = '<div id="my_unique_id">';
$form['field_name']['und'][0]['value']['#suffix'] = '</div>';

Please post a module that does nothing but this and I'll take a look at debugging it. If you'll include an export of the content type with it that will be great.

I exported the content type with Features module, but if you check the jpg too you'll see that there's only 2 simple textfields created for the content type, so it's maybe quicker just to click them as usual.
I also attached the module.
Thank you!

Category:bug» support

Thanks! I may be a few days but this is on my list to work on.

Status:Active» Fixed
StatusFileSize
new514 bytes

OK, this turns out to be a FAPI issue, unrelated to AJAX.

What's happening is that the form element you're applying #default_value already has input in it. The workaround for this is to unset $form_state['input'] for the item, and then it all works fine.

So with this code it works:

if (!empty($form_state['values']['field_new_name'])) {
  unset($form_state['input']['field_name']['und'][0]['value']);
  $form['field_name']['und'][0]['value']['#default_value'] = $form_state['values']['field_new_name']['und'][0]['value'];
}

I've attached the fixed module.

$form_state['input'] is explained a little in http://api.drupal.org/api/drupal/includes--form.inc/group/form_api/7, but not this exact use case.

Title:AJAX messes up layoutHow do I use AJAX to set the default value of another textfield?

Status:Fixed» Closed (fixed)

Thank you very much, it really works this way!

Thanks for the module and illustrative way of describing... It really helped a lot.

Happy Coding.

#9 did the trick for me,

Thank you rfay.

#9 good for me as well.

Thanks