A single branch from a tree in focus with a blurred sunny background.
Twig to the possibilities and expand what your forms can do.

Use Twig to create interactive webform calculations

We recently spoke with Ryan Jones from TAPS goClub group about a fascinating project to show commuters just how much pollution they are individually contributing to the environment. In addition to the eye-opening data it provides, the webform created by Ryan and his colleague Ramon Zavala also provides a perfect example of how you can incorporate calculations into your forms and share them with your users.

The method for incorporating Twig into your webforms is worth knowing and we'll recreate Ryan and Ramon's form for you so you can understand the process.

First, what is Twig?

Twig is a template engine specifically for the PHP programming language. This probably doesn't do much to clear this up for you, so, to put this more simply, Twig allows you to create reusable snippets of code containing placeholder tokens that can be saved as templates to output information in a structured way. 

Example with tokens in bold:
<p><a href="{{ id }}">{{ content_title }}</a></p>

UPDATED October 2022. The update to PHP 8.0 has introduced a stricter interpretation of the mathematical equations and the use of specific data types. PHP 8.0 will no longer allow a graceful failure if an equation is divided by zero; your Twig code will need to validate the field for a number greater than zero. Additionally, the Text field is deprecated in this use case and you will either need to convert to a number_format if continuing to use an existing Text field or begin with a Number field when the form is created. If you wish to update your form, consider duplicating the original, creating the new Number fields, then adjusting the Twig code as necessary. Should these issues not be addressed your webform or the block associated with your webform may not work or it may break the page entirely.

Create a Webform

The process begins by creating a basic webform. If you haven't done one before, we recommend you begin with Understanding Webforms, available in the Training for Everyone section.

  1. Navigate to Manage » Structure » Webforms.
  2. Click the + Add webform button.
  3. Provide a title. We'll use their original name and call ours 'Commute Calculator'.
  4. Click Save to continue.
  5. From within your new form's Build tab, add the following using the + Add element button:
    • Number field (or Text with number_format conversion) - titled Roundtrip Miles Per Day
      • Change Key [Edit} - commute_distance (this is the machine name of your field)
      • Limited: 1
      • Min/Max Length: 1 / 3
      • Size: 3
      • Input mask: Decimal
      • Field is required
    • Number field (or Text with number_format conversion) - titled Fuel Efficiency
      • Limited: 1
      • Min/Max Length: 1 / 2
      • Input mask: Decimal
      • Field is required
    • Number field (or Text with number_format conversion) - titled Price Per Gallon of Gas
      • Change Key [Edit} - price_for_gas
      • Limited: 1
      • Min/Max Length: 1 / 6
      • Placeholder: $
      • Input mask: Decimal
      • Field is required
    • Number field (or Text with number_format conversion) - titled Days of Commuting Per Month
      • Change Key [Edit] - days_of_work
      • Limited: 1
      • Min/Max Length: 1 / 2
      • Placeholder: Number of days
      • Input mask: Decimal
      • Field is required

This outputs the following elements in your form's list:

A screenshot of our list of form fields, their type and key name.
Note this screenshot is using the older Text field data type, which would require the use of a number_format conversion in the Twig statement.

  

Understanding how to read and write Twig calculations

Here is an example of one of the calculations we're going to use:

{{ (data.commute_distance / data.fuel_efficiency)|round(1, 'ceil') }} gal used per day

As the calculation term suggests, this is actually a mathematical equation, so we have to keep that fact in mind as we proceed and understand how our elements are written and structured so we get the output we expect to see. What follows is a breakdown of each of the parts that make up the above calculation.

{{ token }} 

When you see double braces, this a token or a placeholder. The token, if referencing a specific form field, should include the field's Key machine name. In programming, we would call this a variable; a container for a value we want, but we won't know what it is until the equation is calculated. 

{{ data.token }}

We declare the type of object this information represents. We're telling the template engine that the content we're pulling from the specific form field is of the Data object type. If you're not sure which to use, you can reference the list in the Help with Twig list below or via the link by the same title directly in the Computer Twig field type in your webform.

  • Help with Twig
  • Learn about Twig and how it is used in Drupal.

    The following variables are available:
    {{ webform }}
    {{ webform_submission }}
    {{ elements }}
    {{ elements_flattened }}
    {{ data.element_key }}
    {{ data.element_key.delta }}
    {{ data.composite_element_key.subelement_key }}
    {{ data.composite_element_key.delta.subelement_key }}
    {{ serial }}
    {{ sid }}
    {{ uuid }}
    {{ token }}
    {{ uri }}
    {{ created }}
    {{ completed }}
    {{ changed }}
    {{ in_draft }}
    {{ current_page }}
    {{ remote_addr }}
    {{ uid }}
    {{ langcode }}
    {{ webform_id }}
    {{ entity_type }}
    {{ entity_id }}
    {{ locked }}
    {{ sticky }}
    {{ notes }}
    You can also output tokens using the webform_token() function.

    {{ webform_token('[webform_submission:values:element_value]', webform_submission, [], options) }}

{{ ( data.token / data.token ) }} 

Just like in math equations, we have to respect the order of operations. In the example, we eventually want to make sure our final number is rounded up to a whole value, but without a way to separate the equation from the roundup function, we might still arrive at a number with a decimal. We want to calculate distance commuted divided by the fuel efficiency first, so we isolate this using brackets, after which it will apply any additional instructions, such as the |round syntax described below to round the number up to a whole number.

{{ ( data.token / data.token ) }} plain text

Anything you add outside of the double braces will be printed out as plain text. In our specific example here, the number outputted by our calculation will be followed by 'gal used per day' to make it clearer for the submitter what the data total is referencing.

{{ ( data.token / data.token | round(1, 'ceil') }} plain text

Next, we want to make sure we get a whole number from this equation, so we'll add some additional syntax that instructs the engine to round up so we avoid having any decimal points in our output.

Add Twig to perform the calculations

  1. While in the Build tab, click on the + Add element button, then search for the Computed Twig element to add each of the following Computed Twig elements:
    1. Computed Twig - titled Gallons Per Day
      1. Display on: Both form and viewed submission
      2. Mode: Auto-detect
      3. Computed value/markup:
        {% if data.fuel_efficiency|number_format > 0 %}{{(data.commute_distance|number_format / data.fuel_efficiency|number_format)|round(1, 'ceil')}}{% else %}0{% endif %} gal used per day
      4. Automatically update the computed value using Ajax: Check
    2. Computed Twig - titled Cost of Fuel Per Day
      1. Display on: Both form and view submissions
      2. Mode: Auto-detect
      3. Computed value/markup:
        {% if data.fuel_efficiency|number_format > 0 %}{{(data.commute_distance|number_format * data.price_for_gas|number_format / data.fuel_efficiency|number_format)|number_format(2, '.', ',')}}{% else %}0{% endif %} spent per day
      4. Automatically update the computed value using Ajax: Check
    3. Computed Twig - titled Cost of Fuel Per Month
      1. Display on: Both form and view submissions
      2. Mode: Auto-detect
      3. Computed value/markup:
        {% if data.fuel_efficiency|number_format > 0 %}{{(data.commute_distance|number_format * data.price_for_gas|number_format * data.days_of_work|number_format / data.fuel_efficiency|number_format)|number_format(2)}}{% else %}0{% endif %} spent per month
      4. Automatically update the computed value using Ajax: Check
    4. Computed Twig - titled KG of Pollution
      1. Display on: Both form and view submissions
      2. Mode: Auto-detect
      3. Computed value/markup:
        {% if data.fuel_efficiency|number_format > 0 %}{{(8.89 * data.commute_distance|number_format * data.days_of_work|number_format / data.fuel_efficiency|number_format)|round(1, 'ceil')}}{% else %}0{% endif %} kg of co2
      4. Automatically update the computed value using Ajax: Check

Presentation Change

To pretty up ours, we created a container using the Fieldset element and nested all the Computer Twig fields inside of it, but otherwise this represents almost the exact form built by the goClub site.

Final Thoughts

This is a great way to add dynamic functionality to your webforms; it provides instant gratification to your visitors and, on submission, will store the submitted data for your use. As with all other webforms, you can configure email handlers to submit the data to the location or email account of your choice, or leave it in your site's database to export at a later time. 

Primary Category

Tags

Demo of the Commute Calculator

Your results
0 gal used per day
​​​​​​​$0 spent per day
​​​​​​​$0 spent per month
0 kg of co2