0

I have an autocomplete textfield whose autocomplete_route_parameters is updated on the onChange event of a textfield, which is filled by a jQuery UI datepicker. Everything works, but after the update of the list the datepicker, which was closed after the selection of the date, shows up again. So I thought, well, I'll just use jquery to close it again.

This means that the ajax callback cannot simply return a renderable array, but rather an AjaxResponse; the problem is that I don't understand how to use a form element inside a ReplaceCommand. If before the change I had

function seduta_senato_form_datetime_changed(array &$form, FormStateInterface $form_state) {
  return $form['struttura-input'] ;
}

now I should say something along the lines of

function seduta_senato_form_datetime_changed(array &$form, FormStateInterface $form_state) {
  $response = new AjaxResponse() ;
  $response
  ->addCommand(new ReplaceCommand('#ajax-wrapper', "<div id='ajax-wrapper'>" . $form['struttura-input']->??? . '</div>'))
  return $response ;
}

but the form element has to be rendered somehow, otherwise it will simply appear in the HTML as Array.

I thought this would be simple, since for sure the functionality that renders the changed element is already there, but the research I made gave me only rather intricate solutions. Any help or hint would be greatly appreciated!

  • The first example needs an ajax wrapper div too, so $form['struttura-input'] should include this already. If you really need to add a wrapper, then don't try to concatenate a string and an array. Add the wrapper div to the form array, either with a '#type' => 'container' element or simply a #prefix and #suffix. – 4k4 Jul 13 '18 at 12:45
  • Yes, I know that I don't need a wrapper div if I use AjaxResponse, I just changed as little as I could from the solution returning a renderable array. – Francesco Marchetti-Stasi Jul 13 '18 at 13:24
0

So, I used the source, and I found out that Drupal\Core\Ajax\ReplaceCommand calls getRenderedContent(), I found an implementation in CommandWithAttachedAssetsTrait where I saw that it expects an array, as I should have well known. So I ended up with the following calls:

$response
  ->addCommand(new RemoveCommand('label[for^="edit-struttura-input"]'))
  ->addCommand(new ReplaceCommand('input[id^="edit-struttura-input"]', array( $form['struttura-input'] )))
  ->addCommand(new InvokeCommand('#edit-field-next-field-to-edit', 'focus')  )

Note that I removed the wrapper, as suggested by @4k4, but then I had to select on a match on the start of the ID of the element, and to remove the label, since it is added by each new rendering. As a command to get rid of the datepicker I simply moved the focus to the next element to edit, which is very convenient to the user.

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.