Skip to main content
ocean waves

Blog Post

Theming a Webform in Drupal 7

Online forms are one of the most common methods used to gather meaningful information and connect with customers and prospects on your website. There’s always the need to add custom theming or functionality to your webforms in Drupal 7, and we’re going to cover a few different options that will equip you to bend webform to your will.

Theming options covered in this blog post:

  • Theming elements via the Webform UI
  • Theming elements via custom templates
  • Altering a Webform with hook_form_alter()
  • Theming a Webform with CSS and JS specific to this form
     

Theming elements via the Webform UI

The Webform UI allows a great amount of flexibility when you want to add custom classes to your form.

Webform 7.x-4.x​

The wrapper and field classes added in the UI are the rendered in the html output

The wrapper and field classes added in the UI

Theming elements via custom templates

If your theming needs are a bit more complex, theming your webform via custom tpl files is may be just what you need.

As a first step, enable theme_debug in settings.php. Do this by uncommenting the line for theme debug.

$conf['theme_debug'] = TRUE;

Theme Debug enables you to see information about what templates are responsible for rendering markup on a page, as well as showing template suggestions if you wish to override a template.

Theme Debug

You’ll see that theme debug shows that the webform output is being generated by path-to-contrib-modules/templates/webform-form.tpl.php in the webform module.

Copy this file and place in your current theme and rename based on template suggestions for webform.

  • webform-form-[nid].tpl.php
  • So if your webform node ID is 1, you would name the file webform-form-1.tpl.php

Within the webform-form-1.tpl.php file, form fields are rendered via this line:

print drupal_render($form['submitted']);

If you’re using devel, you can easily view the fields on the form by adding the following to your tpl file:

dpm($form[‘submitted’];

Output of dpm command
 

You can the render any of the fields in the webform in any order that you want, and group them with markup as you need. Here, I’ve added a div with the class of jumbotron and wrapped the First Name and Last Name fields. I’ve also added some divs to add a grid layout to some of the other form elements.

 

<div class="jumbotron">
  <h2><i class="glyphicon glyphicon-user"></i> Personal Information</h2>
  <div class="row">
    <div class="col-xs-12 col-md-6"><?php print drupal_render($form['submitted']['first_name']); ?></div>
    <div class="col-xs-12 col-md-6"><?php print drupal_render($form['submitted']['last_name']); ?></div>
  </div>
</div>

<div class="row form-group">
  <div class="col-xs-12 col-md-6"><?php print drupal_render($form['submitted']['email']); ?></div>
  <div class="col-xs-12 col-md-6"><?php print drupal_render($form['submitted']['telephone']); ?></div>
</div>

<div class="row form-group">
  <div class="col-xs-12"><?php print drupal_render($form['submitted']['reason_for_contact']); ?></div>
</div>

<div class="row form-group">
  <div class="col-xs-12"><?php print drupal_render($form['submitted']['message']); ?></div>
</div>

<?php
  // Print out the main part of the form.
  // Feel free to break this up and move the pieces within the array.
  print drupal_render($form['submitted']);

  // Always print out the entire $form. This renders the remaining pieces of the
  // form that haven't yet been rendered above (buttons, hidden elements, etc).
  print drupal_render_children($form);

Note
Once you render a form element individually, it will not render within the $form[‘submitted’] render array anymore.

Here’s the rendered result of the tpl changes just made.

A visualization of the form after rendering

Altering a Webform with hook_form_alter()

You can also theme your form using hook_form_alter().
See Programmatically modifying a webform with hook_form_alter() | Drupal.org

Add a hook to your theme or custom module.

/**
 * Implements HOOK_form_webform_client_form_NID_alter().
 */
function YOURTHEME_form_webform_client_form_1_alter(&$form, &$form_state, $form_id) {
  // Form alters here.
}

 

We’re going to alter the markup for some of the fields in our form.

/**
 * Implements HOOK_form_webform_client_form_NID_alter().
 */
function YOURTHEME_form_webform_client_form_1_alter(&$form, &$form_state, $form_id) {
  // Change the First Name field title.
  $form['submitted']['first_name']['#title'] = t('Tell me your first name');

  // Add an icon to the email form field.
  $form['submitted']['email']['#field_prefix'] = '<i class="glyphicon glyphicon-envelope"></i>';
}

 

Anything you can do using Drupal’s FAPI (Form API) can be done here.

Theming a Webform with CSS and JS specific to this form

You can also theme your form with just some good ol’ CSS and Javascript. You can add CSS and JS to your form via a hook form alter. The CSS and JS will be added to this form only when this specific form is loaded.

As an exercise, we’re going to display an icon when the selected option changes for Reason for Contact.

// Add the following to the YOURTHEME_form_webform_client_form_1_alter() function.
// Add css and js to the form.
  $form['#attached']['css'][] = drupal_get_path('theme', 'YOURTHEME') . '/css/webform_1.css';
  $form['#attached']['js'][] = drupal_get_path('theme', 'YOURTHEME') . '/js/webform_1.js';

The JS File

// mymodule/js/webform_1.js
!(function ($) {
  'use strict';
  Drupal.behaviors.WebformConfig = {
    attach: function(context) {
      var $contact = $('input[name="submitted[reason_for_contact]"]');
      $contact.parents('#edit-submitted-reason-for-contact').append('<div class="reason-icon"></div>');
      var $icon = $('.reason-icon');

      $contact.on('change', function (event) {
        var value = $(this).val();

        if (value == 'strategy') {
          $icon.html('<i class="glyphicon glyphicon-knight"></i>');
        }
        else if (value == 'theme_form') {
          $icon.html('<i class="glyphicon glyphicon-pencil"></i>');
          console.log('Theme Form');
        }
        else {
          $icon.html('<i class="glyphicon glyphicon-info-sign"></i>');
        }
      });
    }
  };
})(jQuery);

The CSS file 

//mymodule/css/webform_1.css
.reason-icon {
  position: absolute;
  right: 1em;
  top: 0;
}
.reason-icon i {
  font-size: 50px;
  padding: 30px;
}

And here’s the result! 

Interactive gif of final results

Summary

With these tools in hand, you can theme any of your webforms any way you want. Happy theming.

Additional Resources
Creating Advanced Theme Settings in Drupal and D8 | Blog
Component Based Theming in Drupal 8 | Blog
5 Advantages of Component Driven Theming | Video

Thumbnail

Meet team member, Bayo Fodeke

In addition to over six years of full-stack Drupal experience, Bayo brings a strong background in UX and website usability to his role as Senior Drupal Developer. Bayo got his start in...

Learn more about Bayo >