1 of 88

advancedwebforms�http://bit.ly/advanced-webforms

2 of 88

Hello!

Hi, my name is Jacob Rockowitz.

  • I am known as jrockowitz on the web.
  • I am a Drupal developer and software architect.
  • I built and maintain the Webform module for Drupal 8.

3 of 88

there are a �lot of resources available for learning about the basics Of �the webform module

Advanced �presentations �should teach you �a few new things �& inspire you �to learn more

4 of 88

Building advanced�webforms requires leveraging hooks, understanding plugins, building render arrays, �& writing tests

5 of 88

Webform Basics

6 of 88

The Webform �module is a �powerful and flexible �Open Source �form builder & �submission manager �for Drupal 8

7 of 88

It provides all the features expected from an enterprise proprietary form builder...

...combined with the flexibility and openness of Drupal

8 of 88

The use case…

  • BUILD a form or copy a template
  • PUBLISH the form as a page, node, or block
  • COLLECT form submissions
  • SEND confirmations and notifications
  • REVIEW results online
  • DISTRIBUTE results as CSV or remote post

9 of 88

ONCE AGAIN, THE USE CASE…

BUILD

COLLECT

DISTRIBUTE

10 of 88

<demo>

Webform Basics

Overview: /admin/structure/webform

Build: …/webform/manage/contact

Source: …/webform/manage/contact/source

Configure …/webform/manage/contact/settings

Test: /webform/contact/test

Results: …/contact/results/submissions

Download: …/contact/results/download�Submission:…/contact/submission/1

11 of 88

Additional resources

  • Webform Articles�http://dgo.to/2932764

  • Webform Videos�http://dgo.to/2834424

  • Webform Features (Outdated)�http://dgo.to/2837024

12 of 88

testing

webforms

13 of 88

Tests confirm �expectations

14 of 88

Webform Tests confirm

  • Rendering: Check an element's markup
  • Processing: Check an input's default value
  • Validation: Check required error messages
  • Settings: Check labels and layout
  • Access: Check user access controls

15 of 88

testing best practices

  • Create a test module with exported webforms
  • Write tests for every element and setting
  • Establish repeatable testing patterns
  • Organize tests into groups/subdirectories

  • Having easy-to-repeat manual tests is okay
  • Some tests are better than no tests

16 of 88

BY the way, the WEbform module �Still uses deprecated simpletests…

…you should �only write�PHPUnit tests

17 of 88

<demo>�Testing Webform

Overview: /admin/structure/webform

Settings:…/src/Tests/Settings

Setting: WebformSettingsConfirmationTest

Elements:…/src/Tests/Element

Element: WebformElementEmailTest

Modules: /tests/modules

18 of 88

Additional resources

  • Testing | Drupal.org�http://dgo.to/2819027

19 of 88

Webform�entities

20 of 88

Everything in �Drupal 8 is �an entity �(or a plugin)

21 of 88

what is an entity?

Any defined chunk of data in Drupal. This includes things like nodes, users, taxonomy terms, files, etc. Contributed modules can define custom entities. �Each entity type can have multiple bundles. �-- https://dgo.to/937

22 of 88

THis is a�Webform�entity

23 of 88

THis is a�Webform�submission�entity

24 of 88

About webform entities

  • Webforms are config entities (exportable)
  • Submissions are content entities (database)

  • Webforms do not use Field API
  • Submissions use an �Entity–attribute–value model

25 of 88

Entity–attribute–value model

Entity–attribute–value model (EAV) is a data model to encode, in a space-efficient manner, entities where the number of attributes (properties, parameters) that can be used to describe them is potentially vast, but the number that will actually apply to a given entity is relatively modest.�-- https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model

26 of 88

A simple way

to store

A lot of data

27 of 88

webform_submission

28 of 88

webform_submission_data

Value

ATTRIBUTE

EnTITY

29 of 88

<demo>

Webform Entities

Overview: /devel/entity/info�Export: …/webform/manage/contact/export

API: /webform/contact/api

30 of 88

Additional resources

  • Introduction to Entity API in Drupal 8 | Drupal�http://dgo.to/2078191

  • Entities 101: Understanding Data Structures�in Drupal�https://youtu.be/LT83PfumjPU

31 of 88

discovering the �source entity

32 of 88

a SOURCE ENTITY �TRACKS & CREATES �A RELATIONSHIP TO �the Drupal ENTITY �From which A WEBFORM �WAS SUBMITTED

33 of 88

source entity overview

  • Allows a webform to be reused multiple times
  • Determined via the current route or query string

  • Webform nodes use source entities
  • Webform blocks use source entities
  • Even paragraphs use source entities

34 of 88

webform_submission

SOURCE ENTITY

35 of 88

THese �are �source entities

36 of 88

THE SOURCE ENTITY CAN BE USED to track...

  • Site Feedback�A form that tracks which page the comments are related to.

  • Event Registration�A registration form that tracks which event a user has registered for.

  • Application Evaluation�An evaluation form attached to applications.

37 of 88

<demo>

Webform Source Entity

Overview:…/webform/submissions/manage

Node: …/manage/contact/references

Module: webform_node.module

Plugin: RouteParametersWebformSourceEntity

QueryStringWebformSourceEntity

Interface:WebformSourceEntityInterface

38 of 88

Understanding�Form API (FAPI)

39 of 88

Webforms are �render arrays �which contain�elements that �builD, validate, & submit form Values �using Drupal's �Form API (FAPI)

40 of 88

Render arrays �are the basic �building blocks of �Drupal content

41 of 88

Drupal FORM API overview

  • An element is anything displayed on a page
  • An input is an element that collects data
  • A composite is a group of elements
  • A form is collections of elements and inputs

42 of 88

THis �is a�form

43 of 88

THIS �IS A �RENDER ARRAY�AS YAML

name:

'#title': 'Your Name'

'#type': textfield

email:

'#title': 'Your Email'

'#type': email

subject:

'#title': 'Subject'

'#type': textfield

message:

'#title': 'Message'

'#type': textarea

44 of 88

THIS �IS A �RENDER ARRAY�AS PHP

$form['name'] = [

'#title' => $this->t('Your Name'),

'#type' => 'textfield',

];

$form['email'] = [

'#title' => $this->t('Your Email'),

'#type' => 'email',

];

$form['subject'] = [

'#title' => $this->t('Subject'),

'#type' => 'textfield',

];

$form['message'] = [

'#title' => $this->t('Message'),

'#type' => 'textfield',

];

45 of 88

HOW DRUPAL HANDLES A FORM

BUILD

VALIDATE

SUBMIT

46 of 88

<demo>

Form API (FAPI)

Forms: /admin/config

Interface: FormInterface

Examples: http://dgo.to/examples

47 of 88

Additional resources

  • Form API | Drupal.org�http://dgo.to/2817929

48 of 88

Creating �Form �elEments

49 of 88

A form ELEMENT IS �DEfined using a �RENDER ARRAY, �which is processed by �a render element �Plugin, which�creates an input �ON A FORM

50 of 88

Plugins are

small pieces of functionality that are swappable

51 of 88

Plugins are...

Reusable

Extendable

Standardized

52 of 88

Form elements overview

  • Form elements are plugins
  • Form elements extend render elements

  • Element properties begin with a hash (#)
  • Elements must have keys

53 of 88

name:

'#title': 'Your Name'

'#type': textfield� '#attributes': style:'bg-color:yellow'

class:

- my-custom-class

INPUT NAME (KEY)

PROPERTIES

LABEL

INPUT TYPE

INPUT ATTRIBUTES

54 of 88

<div class="js-form-item form-item js-form-type-textfield form-type-textfield js-form-item-name form-item-name">

<label for="edit-name">Your Name</label>

<input style="background-color:yellow"

class="my-custom-class form-text"

data-drupal-selector="edit-name"

type="text"

id="edit-name"

name="name"

value=""

size="60"

maxlength="255">

</div>

FORM ELEMENT

INPUT ATTRIBUTES

INPUT TYPE

LABEL

INPUT NAME (Key)

XHTML MARKUP

55 of 88

Form element PLUGIN Methods

  • Define properties FormElement::getInfo
  • Set input value FormElement::valueCallback
  • Build input FormElement::buildElementName
  • Process input FormElement::processElementName
  • Render input FormElement::preRenderElementName
  • Validate value FormElement::validateElementName

56 of 88

Form element TIPs

  • Copy and extend existing elements
  • Use #element_validate to alter form values
  • For composite elements you must use #tree

57 of 88

<demo>

Form Elements

Overview: /devel/elements

Interface:…/lib/Drupal/Core/Render/Element

Example: …/Render/Element/Textfield

58 of 88

Additional resources

  • Render arrays | Drupal.org�http://dgo.to/2456267

59 of 88

Creating �webform elements

60 of 88

Webform elements are �Wrappers that enhance�drupal form elements

61 of 88

WebForm element plugins overview

  • Requires a corresponding FormElement
  • Both plugins must use the same plugin ID (#type)
  • Handles everything related to an element
  • Base classes help organize related elements
  • Traits help group related behaviors

62 of 88

webForm element PLUGIN Methods

  • Defines default properties WebformElement::getDefaultProperties
  • Prepares an element WebformElement::prepare
  • Determine behaviors WebformElement::hasMultipleValues
  • Display submission value WebformElement::buildHtml
  • Exports values WebformElement::getTableColumn
  • Builds configuration form WebformElement::form

63 of 88

<demo>

Webform Elements

Overview: …/reports/webform-plugins/elements

Test: …/elements/email

Plugins: …/src/Plugin/WebformElement/�Interface: WebformElementInterface�Modules: webform_example_element.module

webform_example_composite.module

64 of 88

Creating Custom Webform Elements

  • Create a custom module
  • Extend or copy existing form element plugin
  • Build a test webform
  • Define webform element plugin
  • Test webform integration
  • Write tests

65 of 88

Implementing�webform handlers

66 of 88

Webform Handler �plugins are used to �route submitted data �to applications �& send email �notifications

67 of 88

THese�are�webform�Handlers

68 of 88

THis �is an�email �Handler

69 of 88

webform handler plugin overview

  • Contains methods that act like hooks
  • Reacts to a submission’s state
  • Supports conditional logic

70 of 88

webForm handler PLUGIN Methods

  • Configuration settings WebformHandler::getConfiguration
  • Override settings WebformHandler::overrideSettings
  • Alter forms & elements WebformHandler::alterElement
  • Entity operations WebformHandler::postSave
  • Element operations WebformHandler::createElement
  • Handler operations WebformHandler::createHandler

71 of 88

<demo>

Webform Handlers

Overview: …/reports/webform-plugins/handlers

Test: …/contact/settings/handlers

Plugins: …/src/Plugin/WebformHandler/�Interface: WebformHandlerInterface�Module: webform_example_handler.module

72 of 88

extending�webform exporters

73 of 88

Webform Exporter �plugins are used to �download submissions �into spreadsheets �& other applications

74 of 88

THese are�exporters

75 of 88

webform exporter plugin overview

  • Always extend an existing Webform Exporter
  • Use DelimitedWebformExporter for CSV files
  • Drush command is available for automation

76 of 88

WebForm exporter PLUGIN Methods

  • Configuration settings WebformExporter::getConfiguration
  • Writing data WebformExporter::writeHeader
  • File naming WebformExporter::getBaseFileName

77 of 88

<demo>

Webform Exporters

Overview: …/reports/webform-plugins/exports

Test: …/contact/results/download

Plugins: …/src/Plugin/WebformExporter/�Interface: WebformExporterInterface

78 of 88

implementing�webform �hooks

79 of 88

Hooks are �functions that �define or alter �behaviors

80 of 88

webform & Drupal Hooks overview

  • Handler plugins and hooks are very similar
  • Handlers are applied to a single form
  • Hooks can be applied to all forms
  • All entity hooks are applicable to webforms

81 of 88

PLUGINS & �EVENT SUBSCRIBERS �ARE THE "new" hooks �for Drupal 8

82 of 88

/**

* Implements hook_webform_submission_form_alter().

*/

function CUSTOM_MODULE_webform_submission_form_alter(

array &$form,

\Drupal\Core\Form\FormStateInterface $form_state,

$form_id

) {

// Add .btn-lg to all 'submit' button in $form['actions'].

foreach (Element::children($form['actions']) as $key) {

$button =& $form['actions'][$key];

$button['#attributes']['class'][] = 'btn-lg';

$button['#attributes']['style'] = 'margin-top: 24px';

}

}

Form Alter Hooks (aka functions)

83 of 88

/**

* Implements hook_webform_element_ELEMENT_TYPE_alter().

*/

function CUSTOM_MODULE_webform_element_webform_actions_alter(

array &$element,

\Drupal\Core\Form\FormStateInterface $form_state,

array $context

) {

// Add .btn-lg to all 'submit' button properties in $element.

$buttons = \Drupal\webform\Element\WebformActions::$buttons;foreach (buttons as $button) {

$element['#' . $button . '__attributes']['class'][] = 'btn-lg';

$element['#' . $button . '__attributes']['style'] = 'margin-top: 24px';

}

}

Element Alter Hooks (aka functions)

84 of 88

FORM hooks

hook_webform_submission_form_alter

element hooks

hook_webform_element_alter

option hooks

hook_webform_options_alter

handler hooks�hook_webform_handler_invoke_alter

entity hooks

hook_webform_submission_insert�hook_webform_submission_load�hook_webform_submission_save�hook_webform_submission_delete�etc…

more hooks…

hook_webform_libraries_info_alter�hook_webform_access_rules_alter

@see webform.api.php

85 of 88

Additional

webform

resources

86 of 88

Connecting with Me

  • Jacob Rockowitz (Blog)�http://jrockowitz.com

  • jrockowitz on Drupal.org�https://www.drupal.org/u/jrockowitz

  • jrockowitz on Twitter�https://twitter.com/jrockowitz

87 of 88

Getting help & support

88 of 88

Thank You!!!

ANY QUESTIONS?

Ralph says...