Form item
Wrapper for a form element (or group of form elements) and its label.
Notes: If you'd like for the label to be have focus styles:
- A class of
.js-form-item-focus
must be applied to the form item. - The following JS must be included.
Requires:
dist/js/foreach-nodelist/vendors/foreach-nodelist.js
dist/js/form-item.bundle.js
form-item__required
icon to the label.
disabled
to the form element as well.
{% import '@h4h_theme/icons/icons.twig' as icons %}
<div class="form-item {{modifier_class}}">
{% if modifier_class == 'is-required' -%}
<label class="form-item__label" for="form-item-input-required">{{ icons.get('asterisk', 'icon form-item__required') }} Label</label>
<input class="form-item__text js-form-item-focus" required type="text" id="form-item-input-required" value="Text value">
{% elseif modifier_class == 'is-disabled' -%}
<label class="form-item__label" for="form-item-input-disabled">Label</label>
<input class="form-item__text" required type="text" id="form-item-input-disabled" value="Text value" disabled>
{% else %}
<label class="form-item__label" for="form-item-input">Label</label>
<input class="form-item__text js-form-item-focus" type="text" id="form-item-input" value="Text value">
{% endif -%}
<div class="form-item__error">Field is required.</div>
<div class="form-item__description">
Form item description.
</div>
</div>
Form Ask String
This component is basically custom radio elements with a small bit of JavaScript to make sure the 'custom amount' text input works. Note that the ask string is always required.
Requires:
dist/js/foreach-nodelist/vendors/foreach-nodelist.js
dist/js/form-ask-string.bundle.js
{% import '@h4h_theme/icons/icons.twig' as icons %}
<fieldset class="form-ask-string form-item {{modifier_class}}">
<legend class="form-item__label form-item__legend">{{ icons.get('asterisk', 'icon form-item__required') }} Amount:</legend>
<label class="form-ask-string__btn" for="donate10">
<input class="form-ask-string__input form-ask-string__hidden" name="askString" type="radio" id="donate10" value="10" required>
<span class="form-item__text form-ask-string__faux">$10</span>
</label>
<label class="form-ask-string__btn" for="donate15">
<input class="form-ask-string__input form-ask-string__hidden" name="askString" type="radio" id="donate15" value="15">
<span class="form-item__text form-ask-string__faux">$15</span>
</label>
<label class="form-ask-string__btn" for="donate25">
<input class="form-ask-string__input form-ask-string__hidden" name="askString" type="radio" id="donate25" value="25">
<span class="form-item__text form-ask-string__faux">$25</span>
</label>
<label class="form-ask-string__btn" for="donate50">
<input class="form-ask-string__input form-ask-string__hidden" name="askString" type="radio" id="donate50" value="50">
<span class="form-item__text form-ask-string__faux">$50</span>
</label>
<label class="form-ask-string__btn" for="donate100">
<input class="form-ask-string__input form-ask-string__hidden" name="askString" type="radio" id="donate100" value="100">
<span class="form-item__text form-ask-string__faux">$100</span>
</label>
<div class="form-ask-string__other js-ask-wrapper">
<label for="donateother"><span class="form-ask-string__hidden">Other</span></label>
<input class="js-ask-target form-ask-string__hidden form-ask-string__input" name="askString" type="radio" id="donateother" value="other">
<label class="visually-hidden" for="donateOtherCustom">Other Amount</label>
<input class="js-ask-source form-item__text form-ask-string__other-input" type="text" id="donateOtherCustom" value="" placeholder="Other Amount">
</div>
</fieldset>
Form Control
Group checkboxes and radio elements together.
Make sure to wrap multiple checkbox fields with a <fieldset>
.
form-item__required
icon to the label.
disabled
to the form element as well.
{% import '@h4h_theme/icons/icons.twig' as icons %}
<fieldset class="form-item form-control {{modifier_class}}">
{% if modifier_class == 'is-required' -%}
<legend class="form-item__label form-item__legend">{{ icons.get('asterisk', 'icon form-item__required') }} Optional Details</legend>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('inHonor-' ~ modifier_class ) }}">
<input class="form-control__el" type="checkbox" name="optionalDetails" value="inHonor" id="{{ id|default('inHonor-' ~ modifier_class ) }}" required>
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc">
Donate in honor of someone and send a personalized card
</div>
</label>
</div>
{% else %}
<legend class="form-item__label form-item__legend">Optional Details</legend>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('inHonor-' ~ modifier_class ) }}">
<input class="form-control__el" type="checkbox" name="optionalDetails" value="inHonor" id="{{ id|default('inHonor-' ~ modifier_class ) }}" {{ modifier_class == 'is-disabled' ? 'disabled' }}>
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc">Donate in honor of someone and send a personalized card
<div class="form-control__details">Minimum donation: $10</div>
</div>
</label>
</div>
{% endif -%}
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('designate-' ~ modifier_class ) }}">
<input class="form-control__el" type="checkbox" name="optionalDetails" value="designate" id="{{ id|default('designate-' ~ modifier_class ) }}" {{ modifier_class == 'is-disabled' ? 'disabled' }}>
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc">
Designate your donation
<div class="form-control__details">Your gift will go where it is needed most, unless you specify a particular location or cause for it to be used.</div>
</div>
</label>
</div>
</fieldset>
<fieldset class="form-item form-control {{modifier_class}}">
{% if modifier_class == 'is-required' -%}
<legend class="form-item__label form-item__legend">{{ icons.get('asterisk', 'icon form-item__required') }} Choose Your Donation</legend>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('monthly-' ~ modifier_class ) }}">
<input class="form-control__el" type="radio" name="donateFrequency" value="monthly" id="{{ id|default('monthly-' ~ modifier_class ) }}" required>
<div class="form-control__indicator form-control__indicator--radio"></div>
<div class="form-control__desc">
Donate monthly
</div>
</label>
</div>
{% else %}
<legend class="form-item__label form-item__legend">Choose Your Donation</legend>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('monthly-' ~ modifier_class ) }}">
<input class="form-control__el" type="radio" name="donateFrequency" value="monthly" id="{{ id|default('monthly-' ~ modifier_class ) }}" {{ modifier_class == 'is-disabled' ? 'disabled' }}>
<div class="form-control__indicator form-control__indicator--radio"></div>
<div class="form-control__desc">
Donate monthly
</div>
</label>
</div>
{% endif -%}
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('once-' ~ modifier_class ) }}">
<input class="form-control__el" type="radio" name="donateFrequency" value="once" id="{{ id|default('once-' ~ modifier_class ) }}" {{ modifier_class == 'is-disabled' ? 'disabled' }}>
<div class="form-control__indicator form-control__indicator--radio"></div>
<div class="form-control__desc">
Donate one time
</div>
</label>
</div>
</fieldset>
{% if modifier_class == '[modifier class]' and id is empty -%}
<fieldset class="form-item form-control">
<legend class="form-item__label form-item__legend">Different description formatting</legend>
<div class="form-control__item">
<label class="form-control__label" for="subName">
<input class="form-control__el" type="checkbox" name="subName" value="monthly" id="subName">
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc">
<div class="form-control__title">Habitat Extra!</div>
<div class="form-control__subtitle">Sent monthly<span class="form-control__vertline"></span><a href="#">Sample</a></div>
<p class="form-control__info">Stay informed of the latest Habitat for Humanity news, special events and volunteer opportunities.</p>
</div>
</label>
</div>
</fieldset>
{% endif -%}
Form Credit Cards
This component is used within the donation page to show which credit cards the form accepts.
{{ attach_library('theme_name/form-creditcards') }}
{% import '@h4h_theme/icons/icons.twig' as icons %}
<fieldset class="form-item form-control form-creditcard is-required">
<legend class="form-item__label form-item__legend">{{ icons.get('asterisk', 'icon form-item__required') }} Payment method</legend>
<div class="form-control__item form-creditcard__credit">
<label class="form-control__label" for="{{ id|default('monthly-' ~ modifier_class ) }}">
<input class="form-control__el" type="radio" name="donateFrequency" value="monthly" id="{{ id|default('monthly-' ~ modifier_class ) }}">
<div class="form-control__indicator form-control__indicator--radio"></div>
<div class="form-control__desc">
Credit or debit card
<div class="form-control__image">
<img src="../../dist/assets/form-creditcards-icon.png">
</div>
</div>
</label>
</div>
<div class="form-control__item form-creditcard__paypal">
<label class="form-control__label" for="{{ id|default('once-' ~ modifier_class ) }}">
<input class="form-control__el" type="radio" name="donateFrequency" value="once" id="{{ id|default('once-' ~ modifier_class ) }}">
<div class="form-control__indicator form-control__indicator--radio">
</div>
<div class="form-control__desc">
PayPal
{%
include "@h4h_theme/tool-tip/tool-tip.twig" with {
label: "What's this?",
selector_id: "paypal-info",
body: "<p>Paypal is a third-pary payment service that enables you to make payments online. Learn more at paypal.com.</p><p><em>Please note: Monthly donations cannot be made through PayPal.</em></p>"
} only
%}
<div class="form-control__image">
<img src="../../dist/assets/form-paypal-icon.png">
</div>
</div>
</label>
</div>
</fieldset>
Form Expandable
This is the Form Expandable component. It allows a checkbox or radio element to expand a child container. This is a pure CSS solution with no JS dependency.
Usage:
- Add
.form-expandable__src
to the radio or checkbox. - On the same level add
.form-expandable__container
to the container element of the element you'd like to toggle. - Finally add
.form-expandable__target
to the element you would like to toggle. - The
.form-expandable__content
class adds additional padding for nested elements.
Example:
<input class="form-expandable__src" type="radio">
...
<div class="form-expandable__container">
...
<div class="form-expandable__target">
<div class="form-expandable__content">
Content that will be expanded.
</div>
</div>
</div>
{{ attach_library('theme_name/form-expandable') }}
<div class="form-expandable">
{% include '@h4h_theme/hr/hr.twig' with {
modifier_class: 'hr--hot-orange hr--mb'
} only
%}
<fieldset class="form-item form-control {{modifier_class}}">
<legend class="form-item__label form-item__legend form-item__legend--secondary">Optional Details</legend>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('inHonor-' ~ modifier_class ) }}">
<input class="form-control__el form-expandable__src" type="checkbox" name="optionalDetails" value="inHonor" id="{{ id|default('inHonor-' ~ modifier_class ) }}">
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc form-expandable__container">Donate in honor of someone and send a personalized card
<div class="form-control__details">Minimum donation: $10</div>
<div class="form-expandable__target">
<div class="form-expandable__content">
{% include '@h4h_theme/info/info.twig' with {
modifier_class: 'info--full',
icon: 'info',
label: info_full.label,
description: info_full.description
} only
%}
</div>
</div>
</div>
</label>
</div>
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('designate-' ~ modifier_class ) }}">
<input class="form-control__el form-expandable__src" type="checkbox" name="optionalDetails" value="designate" id="{{ id|default('designate-' ~ modifier_class ) }}">
<div class="form-control__indicator form-control__indicator--checkbox"></div>
<div class="form-control__desc form-expandable__container">
Designate your donation
<div class="form-control__details">Your gift will go where it is needed most, unless you specify a particular location or cause for it to be used.</div>
<div class="form-expandable__target">
<div class="form-expandable__content">
<fieldset class="form-item form-control">
<legend class="form-item__label form-item__legend">Your Designation</legend>
{% for item in radio.items %}
<div class="form-control__item">
<label class="form-control__label" for="{{ id|default('expandable-' ~ loop.index ) }}">
<input class="form-control__el form-expandable__src" type="radio" name="donateFrequency" value="monthly" id="{{ id|default('expandable-' ~ loop.index ) }}" required>
<div class="form-control__indicator form-control__indicator--radio"></div>
<div class="form-control__desc form-expandable__container">
{{ item.text }}
<div class="form-expandable__target">
<div class="form-expandable__content">
Expanded description with more information.
</div>
</div>
</div>
</label>
</div>
{% endfor %}
</fieldset>
<div class="form-control__details">{{ disclaimer }}</div>
</div>
</div>
</div>
</label>
</div>
</fieldset>
{% include '@h4h_theme/hr/hr.twig' with {
modifier_class: 'hr--hot-orange'
} only
%}
</div>
Form Float Label
On focus the label moves above the form field so the user maintains the field context.
Usage: add the .form-float-label
to a form item. Note that the label
must follow the form element.
Requires:
dist/js/foreach-nodelist/vendors/foreach-nodelist.js
dist/js/form-float-label.bundle.js
To make a form item required, add the required
attribute to the element and the form-item__required
span to the label same as the normal form-item. In
addition make sure the form-item wrapper contains the is-required
class so the labels are formatted correctly.
Drupal Usage: Within the form build add a '#element_class', change the title (label) display to after and attach the float label library.
Example:
$form['formcta_state'] = [
'#type' => 'select',
...
'#element_class' => 'form-float-label',
'#title_display' => 'after',
'#attached' => [
'library' => 'h4h_theme/float-label',
],
];
disabled
to the form element as well.
{% import '@h4h_theme/icons/icons.twig' as icons %}
<div class="form-item form-float-label {{ modifier_class }}">
{% if modifier_class == 'is-required' -%}
<input class="form-item__text" required type="text" id="{{ id|default('form-item-name') }}" value="">
<label class="form-item__label" for="{{ id|default('form-item-name') }}">{{ icons.get('asterisk', 'icon form-item__required') }} First Name</label>
{% elseif modifier_class == 'is-disabled' -%}
<input class="form-item__text" disabled type="text" id="{{ id|default('form-item-name-disabled') }}" value="">
<label class="form-item__label" for="{{ id|default('form-item-name-disabled') }}">Address</label>
{% else %}
<input class="form-item__text" type="text" id="{{ id|default('form-item-phone') }}" value="">
<label class="form-item__label" for="{{ id|default('form-item-phone') }}">Phone</label>
{% endif -%}
</div>
Form Group
Allows form text inputs and buttons to sit on the same line.
<div class="form-item {{modifier_class}}">
<label class="form-item__label form-group__label" for="form-group-input">Label</label>
<div class="form-group">
<input class="form-group__field form-item__text js-form-item-focus" type="text" id="form-group-input" value="Text value">
<div class="form-group__btn"><button class="btn btn--reversed" type="submit">Search</button></div>
</div>
</div>
Form item layout
Add form items to general layouts.
<form>
<div class="l-grid__wrapper">
<div class="l-grid l-grid--clean">
<div class="l-grid__col l-grid__col-half">
{%
include "@h4h_theme/forms/form-float-label/form-float-label.twig" with {
modifier_class: 'form-item--wide',
id: 'form-item-test'
} only
%}
</div>
<div class="l-grid__col l-grid__col-half">
{%
include "@h4h_theme/forms/form-item/form-item.twig" with {
modifier_class: 'form-item--wide is-required'
} only
%}
</div>
</div>
<div class="l-grid l-grid--clean">
<div class="l-grid__col">
{%
include "@h4h_theme/forms/form-item/form-item.twig" with {
modifier_class: 'form-item--wide'
} only
%}
</div>
</div>
<div class="l-grid l-grid--clean">
<div class="l-grid__col l-grid__col-half">
{%
include "@h4h_theme/forms/form-item/form-item.twig" with {
modifier_class: 'form-item--wide'
} only
%}
</div>
<div class="l-grid__col l-grid__col-half">
{%
include "@h4h_theme/forms/form-float-label/form-float-label.twig" with {
modifier_class: 'is-required',
id: 'form-item-zip'
} only
%}
</div>
</div>
</div>
</form>
Form Select
This is a custom select form element. This element reuses the form float label styles and JavaScript in order to provide the float label interaction.
Requires:
dist/js/foreach-nodelist/vendors/foreach-nodelist.js
dist/js/form-float-label.bundle.js
form-item__required
icon to the label.
disabled
to the form element as well.
{% import '@h4h_theme/icons/icons.twig' as icons %}
<div class="form-item form-float-label {{modifier_class}}">
{% if modifier_class == 'is-required' -%}
<select required id="form-item-country-{{ modifier_class }}" class="form-item__text form-select">
{% elseif modifier_class == 'is-disabled' -%}
<select required id="form-item-country-{{ modifier_class }}" class="form-item__text form-select" disabled>
{% else %}
<select id="form-item-country-{{ modifier_class }}" class="form-item__text form-select {{ modifier_class == 'form-select--white' ? modifier_class }}">
{% endif -%}
<option selected value="">Select One</option>
<optgroup label="Regions">
<option value="1">International Fund</option>
<option value="2">Europe, the Middle East and Africa</option>
<option value="3">Asia and the Pacific</option>
<option value="4">Latin America and the Caribbean</option>
</optgroup>
<optgroup label="Countries">
<option value="5">United States</option>
<option value="6">Argentina</option>
</optgroup>
</select>
{% if modifier_class == 'is-required' -%}
<label class="form-item__label" for="{{ id|default('form-item-country-' ~ modifier_class ) }}">{{ icons.get('asterisk', 'icon form-item__required') }} Select country or region</label>
{% else %}
<label class="form-item__label" for="{{ id|default('form-item-country-' ~ modifier_class ) }}"> Select country or region</label>
{% endif -%}
</div>