I want to add AJAX to an autocomplete field on a form that fills in two other fields with data based on what the user chooses in the autocomplete field. The AJAX was working when the first field was a select list, but when I changed it to an autocomplete field, the event trigger no works. What do you I need to do beyond attaching the AJAX callback to the autocomplete field? Any suggestions or examples would be very welcome.

Comments

undersound3’s picture

Perhaps this could be of use to you
http://drupal.org/project/examples

Raumfisch’s picture

If the autocomplete field is an Entity Reference field, the solution that worked for me is to put the ajax callback directly to the field "target_id".
e.g.:

$form['field_yourfield'][LANGUAGE_NONE][0]['target_id']['#ajax'] = array()

vegantriathlete’s picture

Yup, it's just an issue of finding the right place to attach the #ajax attribute. Doing this for my autocomplete field did get my ajax callback to fire.

albertski’s picture

Thanks @Raumfisch! Adding the #ajax callback on the target id worked for me.

gusantor’s picture

I'm working with a node reference, so I added #ajax this way

  $form['field_myfield']['und'][0]['nid']['#ajax']=array(
    'event'=>'change',
    'callback'=>'_mycallback',
    'wrapper'=>'other_field_wrapper',
    'method'=>'html',
    'effect'=>'fade',
  );

this works, I'm using ajax to modify other field, but I can't find the actual nid (or target_id) returned after autocomplete

when I look at $form_state['input']['field_myfield']['und] or $form_state['values']['field_myfield']['und'] I just found the text I entered, not the actual nid returned by autocomplete

I've also looked at $form_state['triggering_element']['#value'] but also, there's just the text I entered for search with autocomplete

so where can I find the nid, or target_id returned by autocomplete ?, or even the full fieldtext value , not just what I've entered ?

please help, thanks

albert volkman’s picture

Any thoughts on how to do this for D8? Adding the callback directly to the form works, but it doesn't include the selected value in the callback, only the user entered text.

albert volkman’s picture

Figured it out- use the event "autocompletechange"

http://api.jqueryui.com/autocomplete/#event-close

solide-echt’s picture

You mentioned "adding the callback directly to the form" works. Do you mean like $form['field_name']['widget'][0]['target_id']['#ajax'] = array(...)? In the callback I use function xyz_callback(&$form, \Drupal\Core\Form\FormStateInterface &$form_state) {...} but nothing is happening...

Eric

albert volkman’s picture

I actually had to change the event as autcompletechange wasn't giving me the selected value. autocompleteclose does, however. Here is my example form element-

$form['search'] = [
  '#type' => 'textfield',
  '#autocomplete_route_name' => 'search_block.autocomplete',
  '#autocomplete_route_parameters' => ['product' => $this->product->nid->value],
  '#title' => $this->t('Enter Model'),
  '#placeholder' => $this->t('Start typing model number - ex: @example', ['@example' => $this->getExampleSKU()]),
  '#ajax' => [
    'callback' => '::updatePreview',
    'wrapper' => 'preview-wrapper',
    'event' => 'autocompleteclose',
  ],
];

Is that helpful?

edwardchiapet’s picture

I was able to use $form['field_name']['widget'][0]['target_id']['#ajax'] = array(...); to assign and make the call to the callback function.

keithm’s picture

Here is an answer for D7 and D8: http://drupal.stackexchange.com/a/228150/2272

AndyLicht’s picture

When i use this with an entity reference it does not work for me. Maybe some of u can find my mistake (the ajax of the select field is working fine):

class LayerForm extends ContentEntityForm {

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    
    $form['wrapper'] = array(
      '#type' => 'container',
      '#attributes' => array('id' => 'data-wrapper'),
    );
    /* @var $entity \Drupal\openlayers\Entity\OpenLayersLayer */
    $form['wrapper'][] = parent::buildForm($form, $form_state);
    $form['wrapper'][0]['layer_source_ref']['widget']['#ajax'] =[
      'callback' => '::rebuildLayerForm',
      'event' => 'autocompleteclose',
      'wrapper' => 'data-wrapper',
      'progress' => FALSE,
    ];
    $form['wrapper'][0]['layer_type']['widget']['#ajax'] =[
      'callback' => '::rebuildLayerForm',
      'event' => 'change',
      'wrapper' => 'data-wrapper',
      'progress' => [
        'type' => 'throbber',
        'message' => t('...'),
      ],
    ];
//....
return $form;
}
public function rebuildLayerForm(array &$form, FormStateInterface $form_state) {
    $form_state->setRebuild(true); 
    return $form['wrapper'];
  }

my entity field is build by this way:

$fields['layer_source_ref'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Source of the layer'))
      ->setDescription(t('Reference to the source of the layer'))
      ->setSetting('target_type', 'openlayers_source')
      ->setSetting('handler', 'default')
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'string',
        'weight' => -20,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'entity_reference_autocomplete',
        'settings' => array(
          'match_operator' => 'CONTAINS',
          'size' => 60,
          'placeholder' => 'Name of the source',
            'weight' => -20,
        ),
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

thanks for helping me

best regards

Andy

jeffschuler’s picture

@keithm, from your StackExchange answer:

In D8 the jQuery UI autocompleteselect event will also be also triggered but an Ajax callback on it will not receive updated form state values.

I noticed this too. Any idea why?

I'd prefer to be able to use autocompleteselect than autocompleteclose, since the close event can fire when the option list is empty. (To see this, start typing letters from some items in the list, then type wrong letters so that there are no longer any options. The close event fires here, which is undesirable in my case.)