I need to change the form displayed on a page using ajax.
I created an ajax command (having class CommandInterface). The command is called from JavaScript on the client, which in turns sets a callback command that takes the rendered form markup and injects it in a <div>. The form is displayed, but when submit is clicked, the page redirects to: http://as.local/outline/form_action_p_pvdeGsVG5zNF_XLGPTvYSKCf43t8qZYSwc.... The url is a hardcoded value that acts as a placeholder (hardcoded in the Drupal core FormBuilder class).
This issue exists on the D8 Outline module development version (code below is from that module), available at https://www.drupal.org/project/outline. If you download and install this module, and create a simple outline, and set the outline's "render as" setting to "Form", you can reproduce the issue.
Here is the client js code that calls the command:
...
var url = 'outline/render-entry/' +
type + '/' +
id + '/' +
render + '/' +
mode;
var ajax = Drupal.ajax({
url: Drupal.url(url)
});
ajax.execute();Here is the render method of the Ajax Command class:
/**
* {@inheritdoc}
*/
public function render() {
// Get the entity.
$entity = \Drupal::entityTypeManager()
->getStorage($this->type)
->load($this->id);
// Create render array.
if ($this->render == Entry::RENDER_AS_DISPLAY) {
$renderArray =
\Drupal::entityTypeManager()
->getViewBuilder($this->type)
->view($entity, $this->mode);
}
elseif ($this->render == Entry::RENDER_AS_FORM) {
$form = \Drupal::service('entity.manager')
->getFormObject('outline_entry', 'default')
->setEntity($entity);
$renderArray = \Drupal::formBuilder()->getForm($form);
}
// Return the markup.
$markup = \Drupal::service('renderer')->render($renderArray);
return [
'command' => 'renderEntry',
'renderedEntry' => $markup,
];
}Here is the "renderEntry" command that is called on the client:
Drupal.AjaxCommands.prototype.renderEntry = function (ajax, response, status) {
var renderedEntry = response.renderedEntry;
var entryContainer = $('.entry-container');
entryContainer.html(renderedEntry);
var form = entryContainer.find('form')[0];
Drupal.attachBehaviors(form, Drupal.settings);
};
Comments
Comment #2
captaindav commentedComment #3
captaindav commentedComment #4
captaindav commentedComment #5
cilefen commentedHi @captaindav:
You filed this one as a support request but did you intend to mark it a bug?
P.S. It enhances readability to surround code snippets in <code> tags so I did that.
Comment #6
captaindav commentedThanks @cilefen for fixing the code snippets!
I wasn't sure if I am doing something incorrectly, or if there is an actual bug in the core form system, so I marked it "support request". I was hoping someone else might know if it is a bug.
Comment #15
cilefen commentedThere have been no comments in a few years.