Drupal Answers Asked by Bohus Ulrych on December 8, 2021
I’m trying to render limited user edit form on custom page using Drupal Controller.
In the routing.yml I defined _controller, I do not want to use _form.
I want to display on the form e.g. only timezone field, but not the rest. And I’m not able to achieve it. I can render this field, other fields like form_build_id, form_id, form_token
But form html tag is not rendered at all.
It works only if I display the whole form with {{ form.form }}
.
This is the content of the files I am using.
name: 'My module'
type: module
description: 'my module'
core_version_requirement: ^8.8 || ^9
my_module.mymodule_controller_view::
path: '/my-module'
defaults:
_controller: 'Drupalmy_moduleControllerMymoduleController::view'
_title: 'My module'
requirements:
_permission: 'access content'
function my_module_theme($existing, $type, $theme, $path)
{
$templates = array(
'my_module_form' => [
'render element' => 'form',
],
);
return $templates;
}
namespace Drupalmy_moduleController;
use DrupalCoreControllerControllerBase;
use DrupaluserEntityUser;
class MymoduleController extends ControllerBase
{
public function view()
{
$data['header'] = [
'#type' => 'markup',
'#markup' => '<h1>HEADER</h1>',
];
$user = User::load(Drupal::currentUser()->id());
$formObject = Drupal::entityTypeManager()
->getFormObject('user', 'default')
->setEntity($user);
$form = Drupal::formBuilder()->getForm($formObject);
$data['form'] = [
'#theme' => 'my_module_form',
'form' => $form,
];
$data['footer'] = [
'#type' => 'markup',
'#markup' => '<h3>footer</h3>',
];
return $data;
}
}
<div>TWIG TEMPLATE</div>
{{ form.form.timezone }}
{{ form.form.form_build_id }}
{{ form.form.form_token }}
{{ form.form.form_id }}
{{ form.form.actions }}
This is not working, you can't use a form template in a controller. You have to assign the template to $form['#theme']
when building the form or in a form alter hook. Then it gets used by formBuilder()->getForm()
automatically.
See for example seven_form_node_form_alter():
$form['#theme'] = ['node_edit_form'];
and the corresponding twig file for a two column layout:
core/themes/seven/templates/node-edit-form.html.twig
{#
/**
* @file
* Theme override for a node edit form.
*
* Two column template for the node add/edit form.
*
* This template will be used when a node edit form specifies 'node_edit_form'
* as its #theme callback. Otherwise, by default, node add/edit forms will be
* themed by form.html.twig.
*
* Available variables:
* - form: The node add/edit form.
*
* @see seven_form_node_form_alter()
*/
#}
<div class="layout-node-form clearfix">
<div class="layout-region layout-region-node-main">
{{ form|without('advanced', 'footer', 'actions') }}
</div>
<div class="layout-region layout-region-node-secondary">
{{ form.advanced }}
</div>
<div class="layout-region layout-region-node-footer">
<div class="layout-region-node-footer__content">
{{ form.footer }}
{{ form.actions }}
</div>
</div>
</div>
Form modes
A different approach would be to configure a form mode in UI containing only the field you want and then use it in your controller:
$formObject = Drupal::entityTypeManager()
->getFormObject('user', 'custom_form_mode')
->setEntity($user);
See How do I load a form with a specific form display (form mode)?
Answered by 4k4 on December 8, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP