I'd like to theme a contact form in Drupal 8. I'd like to put divs around form elements (using bootstrap).
I also want to put some classes on certain elements (submit button, the form itself).
I'd like to theme a contact form in Drupal 8. I'd like to put divs around form elements (using bootstrap).
I also want to put some classes on certain elements (submit button, the form itself).
Open up your YOURTHEMENAME.theme file and add the following code:
function YOURTHEMENAME_form_contact_message_feedback_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
// Name
$form['name']['#prefix'] = '<div class="row"><div class="col-md-6"><div class="form-group">';
$form['name']['#suffix'] = '</div>';
$form['name']['#attributes']['placeholder'][] = $form['name']['#title'].'*';
$form['name']['#attributes']['class'][] = 'form-control';
unset($form['name']['#title']);
// Mail
$form['mail']['#prefix'] = '<div class="form-group">';
$form['mail']['#suffix'] = '</div>';
$form['mail']['#attributes']['placeholder'][] = $form['mail']['#title'].'*';
$form['mail']['#attributes']['class'][] = 'form-control';
unset($form['mail']['#title']);
// Subject
$form['subject']['widget'][0]['value']['#attributes']['class'][] = 'form-control';
$form['subject']['widget'][0]['value']['#attributes']['placeholder'][] = $form['subject']['widget'][0]['#title'].'*';
$form['subject']['widget'][0]['#title'] = '';
unset($form['subject']['widget'][0]['value']['#title']);
$form['subject']['widget'][0]['#prefix'] = '<div class="form-group">';
$form['subject']['widget'][0]['#suffix'] = '</div></div>';
// Message
$form['message']['widget'][0]['value']['#attributes']['class'][] = 'form-control';
$form['message']['widget'][0]['value']['#attributes']['placeholder'][] = $form['message']['widget'][0]['#title'].'*';
$form['message']['widget'][0]['#title'] = '';
unset($form['message']['widget'][0]['value']['#title']);
$form['message']['widget'][0]['#prefix'] = '<div class="col-md-6"><div class="form-group">';
$form['message']['widget'][0]['#suffix'] = '</div></div></div>';
// Submit
$form['actions']['#prefix'] = '<div class="clearfix">';
$form['actions']['#suffix'] = '</div>';
$form['actions']['submit']['#attributes']['class'][] = 'btn';
$form['actions']['submit']['#attributes']['class'][] = 'btn-success';
$form['actions']['submit']['#attributes']['class'][] = 'pull-right';
}
And here is your result:
Don't forget to clear your caches ;)
You can simply theme every form how you want. I don't like the method by @rpayanm, cuz it hard to maintane and hard readable, with big forms this is not the case, just single wrapper and simple structure.
Every form trying to use theme equals their machine name. You can find this template name in $form['#theme']
just by alter, it is always (or in most times) same as form id machine name. What you need to do is register template for it. You need to implement hook_theme()
. You can write it in CUSTOMMODULE.module or in THEMENAME.theme. Theme key must be the same as in $form['#theme']
, so its automatically use it, otherwise you need to add new one via form alter.
/**
* Implements hook_theme().
*/
function MODULENAME_theme($existing, $type, $theme, $path) {
return [
'FORM_ID_THEME' => [
'template' => 'custom-form-template-name',
'render element' => 'form',
]
];
}
Drupal pass $form variable with form.
Then you must create custom-form-template-name.html.twig
(with your template name from hook_theme()).
The minimal template is
{{ form }}
You also can print every field from form where you want
{{ form.field_name }}
Here you can do whatever you want with markup.
You also can pass additional data to template by implementing template_preprocess_TEMPALTENAME
function template_preprocess_FORM_ID_THEME(&$variables) {
$variables['example'] = 'This is added via preprocess';
}
And then use in template
{{ example }}
<div class="first-field">
{{ form.first_field }}
</div>
<div class="second-field">
{{ form.second_field }}
</div>
<div class="buttons">
{{ form.submit }}
{{ form.preview }}
</div>
{#
Don't forget to add printing form special info at the end.
Without this data form will not working propertly.
#}
{{ form.form_build_id }}
{{ form.form_token }}
{{ form.form_id }}
I think this method is more fliexible, clean and powerful.
P.s. sorry for my english, hopes someone edit and fix my mistakes :)
Example of complex form using this method.
{{ form.submit }}
to {{ form.actions.submit }}
Commented
Oct 24, 2016 at 23:19
{{ form }}
, it is printing entire form.But if i use specific field like {{ form.my_field }}
, nothing displayed. Any idea how can we display each fields of custom entity bundle form?
Commented
Jul 19, 2017 at 14:10
{{ form }}
. I suggest after printing {{ form }}
all form elements will be marked as '#rendered' => TRUE
and won't be rendered soon. If you wan't to use this method of theming form, you must print every field individually. There is no drupal_render_children()
in Drupal 8, unless you write it by yourself. Anyway by default this will cause duplicates, so try to print each field manually.
{{ form }} & {{ form.my_field }}
together. First tried with only {{ form }}
, here I can able to see entire form. Then removed {{ form }}
from template then tried for each form fields separately like this {{ form.my_field }}, etc
, but dint get any out put. Nothing displayed.
Commented
Jul 20, 2017 at 6:51
template_preprocess_FORM_ID_THEME(&$variables)
. In this preprocess you can add new variables, change existing including form elements. I never seen this {{ form.field_name.widget }}
and I theming forms often. Looks like this field is custom created or added by third party module? I think this is allowed, but not rule for others. I recommend you to start with preprocess hook and just look at $variables['form']
what it contains inside.
You have a similar approach here:
//file themename.theme
function themename_preprocess_node(&$variables) {
if(isset($variables['node'])){
$node = $variables['node'];
if($node->getType() == 'application') {
$message = \Drupal::entityTypeManager()
->getStorage('contact_message')
->create(array(
'contact_form' => 'webentwickler_job', //ID(Machine name) of form
));
$form = \Drupal::service('entity.form_builder')->getForm($message);
$variables['application_form'] = $form;
}
}
}
//file node--application.html.twig
{{ application_form }}