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.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Csabbencs’s picture

Priority: Critical » Normal
rfay’s picture

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.

Csabbencs’s picture

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'?

rfay’s picture

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.

Csabbencs’s picture

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>';
rfay’s picture

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.

Csabbencs’s picture

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!

rfay’s picture

Category: bug » support

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

rfay’s picture

Status: Active » Fixed
FileSize
514 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.

rfay’s picture

Title: AJAX messes up layout » How do I use AJAX to set the default value of another textfield?
Csabbencs’s picture

Status: Fixed » Closed (fixed)

Thank you very much, it really works this way!

jdjeet’s picture

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

Happy Coding.

adrian.tuhut’s picture

#9 did the trick for me,

Thank you rfay.

natuk’s picture

#9 good for me as well.

Thanks

signulator’s picture

Thanks..#9 worked for me as well.

fromtheindia’s picture

Issue summary: View changes

Thanks a lot it worked for me...

liles’s picture

Thanks! Your code #9 works also for me

kkalaskar’s picture

Thanks #9 worked form me. It saves my time.

praveenmoses61’s picture

rfay Thanks! your code #9 works for me. It saves my time.