I have a form based on FormBase. All the form is wrapped by form.html.twig. I want to render $form['charts']
outside the <form>
. I was able to do this, but {{ children }} still render all the form with the charts (charts it's duplicated).
Is their a better approach? I was wondering if I should use a normal controller and embed the form.
All this has to do with #theme_wrapper (that wrap the all content with the form template, but with everything already pre-render in #childrens). I must admit I don't really understand the #theme_wrapper logic.
<?php
namespace Drupal\mymodule\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a CDR Dashboard form.
*/
class SurveyQuestionsChartsForm extends FormBase {
private AccountInterface $account;
/**
* @param \Drupal\Core\Session\AccountInterface $current_user
*/
public function __construct(AccountInterface $account) {
$this->account = $account;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
// Instantiates this form class.
return new static(
// Load services required to construct this class.
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'mymodule_myform';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $section = '') {
$form['charts'] = $charts->build();
$form['charts']['#weight'] = 50;
$sections = $analysis->getSections();
$form['section'] = [
'#type' => 'select',
'#title' => $this->t('Thématique'),
'#options' => $sections,
'#default_value' => $section,
];
$form['actions'] = [
'#type' => 'actions',
'#weight' => 10,
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Afficher'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$section = $form_state->getValue('section');
$form_state->setRedirect($this->getRequest()->get('_route'), [
'section' => $section,
]);
}
}
mymodule.module
function mymodule_preprocess_form(&$variables) {
$variables['charts'] = $variables['element']['charts'];
}
form.html.twig
{{ charts }}
<form{{ attributes.addClass(classes) }}>
{{ children }}
</form>