Skip to content

Commit

Permalink
Merge pull request #48 from localgovdrupal/feature/1.x/token-support
Browse files Browse the repository at this point in the history
Feature: Token support
  • Loading branch information
finnlewis committed Dec 4, 2023
2 parents 842c1c2 + 97df034 commit 64da889
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 100 deletions.
21 changes: 8 additions & 13 deletions js/address_select.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
/**
* Hide manual address form.
*
* @param {jQuery} centralHubElement
* @param {jQuery} centralHubElement
* Central hub address lookup element.
* @param {String} type
* @param {String} type
* 'soft' = Do not clear the address values.
* (used when an address is selected)
* 'hard' = Clear the address values.
Expand Down Expand Up @@ -87,7 +87,8 @@

/**
* Check if a manual address has been entered.
* @param {jQuery} centralHubElement
*
* @param {jQuery} centralHubElement
* Centralhub address element.
* @return {Boolean}
* True if the a manual address is present and the search box is empty.
Expand All @@ -110,7 +111,8 @@

/**
* Hide errors on an element
* @param {jQuery} indvElement
*
* @param {jQuery} indvElement
* The individual form input element to hide errors.
*/
function hideErrorsOnElement(indvElement) {
Expand Down Expand Up @@ -165,12 +167,9 @@
central_hub_webfrom_address_entry.find('input.js-localgov-forms-webform-uk-address--town-city').val(addressSelected.town);
central_hub_webfrom_address_entry.find('input.js-localgov-forms-webform-uk-address--postcode').val(addressSelected.postcode);

// add UPRN
central_hub_webfrom_address_entry.find('input.js-localgov-forms-webform-uk-address--uprn').val(addressSelected.uprn);

// Add any extra fields from centrahub for Twig access.
// @See DRUP-1287.
var extra_elements = ['lat', 'lng', 'ward'];
var extra_elements = ['lat', 'lng', 'uprn', 'ward'];
$.each(extra_elements, function (index, value) {
central_hub_webform_address_container.find('input.js-localgov-forms-webform-uk-address--' + value).val(addressSelected[value]);
});
Expand All @@ -191,14 +190,10 @@
*/
var localgov_forms_webform_manual_address_change_handler = function () {
var central_hub_webform_address_container = $(this).closest('.js-webform-type-localgov-webform-uk-address');
var central_hub_webfrom_address_entry = $(this).closest('.js-address-entry-container');

// Clear UPRN.
central_hub_webfrom_address_entry.find('input.js-localgov-forms-webform-uk-address--uprn').val('');

// Clear any extra fields from centrahub for Twig access.
// @See DRUP-1287.
var extra_elements = ['lat', 'lng', 'ward'];
var extra_elements = ['lat', 'lng', 'uprn', 'ward'];
$.each(extra_elements, function (index, value) {
central_hub_webform_address_container.find('input.js-localgov-forms-webform-uk-address--' + value).val('');
});
Expand Down
39 changes: 30 additions & 9 deletions localgov_forms.module
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,52 @@
* Hook implementations.
*/

use Drupal\Core\Render\Element;

/**
* Implements hook_theme().
*/
function localgov_forms_theme() {
return [
// Form element: localgov_webform_uk_address.
'localgov_forms_uk_address_lookup' => [
'render element' => 'element',
],
// Form element: webform_uk_address.
'localgov_forms_uk_address' => [
'render element' => 'element',
],
];
}

/**
* Prepares variables for BHCC Webform templates.
* Implements hook_preprocess_localgov_forms_uk_address_lookup().
*
* Default template: localgov-forms-uk-address.html.twig.
* Prepares variables for the Address lookup element template.
*
* Makes sub-elements available within the `content` variable. Mostly lifted
* from _template_preprocess_webform_composite().
*/
function localgov_forms_preprocess_localgov_forms_uk_address_lookup(array &$variables) {

$element = $variables['element'];
foreach (Element::children($element) as $key) {
if (!isset($element[$key]['#access']) || $element[$key]['#access']) {
$variables['content'][$key] = $element[$key];
}
}

$variables['flexbox'] = $element['#flexbox'] ?? FALSE;
}

/**
* Implements hook_preprocess_localgov_forms_uk_address().
*
* @param array $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Prepares variables for the UK address element template.
*/
function template_preprocess_localgov_forms_uk_address(array &$variables) {
// Here you can get the composite element and alter it.
Drupal::moduleHandler()->loadInclude('webform', 'inc', 'includes/webform.theme.template');
function localgov_forms_preprocess_localgov_forms_uk_address(array &$variables) {

_template_preprocess_webform_composite($variables);
localgov_forms_preprocess_localgov_webform_uk_address($variables);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\localgov_forms\WebformHelper;
use Drupal\webform\Element\WebformCompositeBase;
use Drupal\webform\Utility\WebformElementHelper;

/**
Expand All @@ -17,27 +18,34 @@
* Webform composite can not contain multiple value elements (i.e. checkboxes)
* or composites (i.e. webform_address)
*
* Tokens for sub-elements of composite webform elements are available
* from webform submissions. For this element, available sub-elements include:
* address_1, address_2, town_city, postcode, lat, lng, uprn, and ward. The
* address_lookup sub-element always return empty token values. Example
* token: [webform_submission:values:WEBFORM-ELEMENT-ID-GOES-HERE:uprn]
*
* @FormElement("localgov_webform_uk_address")
*
* @see \Drupal\webform\Element\WebformCompositeBase
* @see \Drupal\webform_example_composite\Element\WebformExampleComposite
*/
class LocalgovWebformUKAddress extends WebformUKAddress {
class UKAddressLookup extends WebformCompositeBase {

/**
* {@inheritdoc}
*/
public function getInfo() {

return parent::getInfo() + ['#theme' => 'localgov_webform_uk_address'];
return parent::getInfo() + ['#theme' => 'localgov_forms_uk_address_lookup'];
}

/**
* {@inheritdoc}
*/
public static function getCompositeElements(array $element) {

$elements['address_lookup'] = [
$element_list = [];
$element_list['address_lookup'] = [
'#type' => 'localgov_forms_address_lookup',
'#address_type' => $element['#address_type'] ?? 'residential',
'#address_search_description' => $element['#address_search_description'] ?? NULL,
Expand All @@ -46,38 +54,16 @@ public static function getCompositeElements(array $element) {
'#always_display_manual_address_entry_btn' => $element['#always_display_manual_address_entry_btn'] ?? 'yes',
];

$elements['address_entry'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['js-address-entry-container'],
],
'#tree' => TRUE,
] + parent::getCompositeElements($element);

// Add UPRN element.
// Seperate element as the select box is dynamic and can get erased.
// This should also allow the default support in case management handler.
$elements['address_entry']['uprn'] = [
'#type' => 'hidden',
'#title' => 'UPRN',
'#default_value' => '',
'#attributes' => [
'class' => ['js-localgov-forms-webform-uk-address--uprn'],
],
];

if (!empty($element['#webform_composite_elements']['address_entry']['#required'])) {
$elements['address_entry']['address_1']['#required'] = TRUE;
$elements['address_entry']['town_city']['#required'] = TRUE;
$elements['address_entry']['postcode']['#required'] = TRUE;
}
$element_list += WebformUKAddress::getCompositeElements($element);
$element_list['address_1']['#prefix'] = '<div class="js-address-entry-container">';
$element_list['postcode']['#suffix'] = '</div>';

// Extras to store information for webform builders to access in
// computed twig.
// @See DRUP-1287.
$extra_elements = ['lat', 'lng', 'ward'];
$extra_elements = ['lat', 'lng', 'uprn', 'ward'];
foreach ($extra_elements as $extra_element) {
$elements[$extra_element] = [
$element_list[$extra_element] = [
'#type' => 'hidden',
'#default_value' => '',
'#attributes' => [
Expand All @@ -86,10 +72,10 @@ public static function getCompositeElements(array $element) {
];
}

$elements['#attached']['library'][] = 'localgov_forms/localgov_forms.address_select';
$elements['#attached']['drupalSettings']['centralHub']['isManualAddressEntryBtnAlwaysVisible'] = isset($element['#always_display_manual_address_entry_btn']) ? ($element['#always_display_manual_address_entry_btn'] === 'yes') : TRUE;
$element_list['#attached']['library'][] = 'localgov_forms/localgov_forms.address_select';
$element_list['#attached']['drupalSettings']['centralHub']['isManualAddressEntryBtnAlwaysVisible'] = isset($element['#always_display_manual_address_entry_btn']) ? ($element['#always_display_manual_address_entry_btn'] === 'yes') : TRUE;

return $elements;
return $element_list;
}

/**
Expand Down Expand Up @@ -152,49 +138,52 @@ public static function validateWebformComposite(&$element, FormStateInterface $f

// Only validate composite elements that are visible.
$has_access = (!isset($element['#access']) || $element['#access'] === TRUE);
if ($has_access) {
// If the address entry element is required.
if (!empty($element['#webform_composite_elements']['address_entry']['#required'])) {
// If there is an address search, but no elements to select
// (its a markup error)
// Then show an error to search for a local address or select can't find
// the address.
if (!empty($search_string) && $element['address_lookup']['address_select']['address_select_list']['#type'] == 'markup') {
$form_state->setError($element, t('Search for a local address, or select "Can\'t find the address" to enter an address.'));
}
// Else if there is a search but no address selected,
// set the select box as required.
elseif (!empty($search_string) && empty($selected)) {
WebformElementHelper::setRequiredError($element['address_lookup']['address_select']['address_select_list'], $form_state);
}
// Else mark the entire element as required.
elseif (empty($search_string) && empty($selected)) {
WebformElementHelper::setRequiredError($element, $form_state);
}
$is_any_address_line_required =
!empty($element['#webform_composite_elements']['address_1']['#required']) ||
!empty($element['#webform_composite_elements']['address_2']['#required']) ||
!empty($element['#webform_composite_elements']['town_city']['#required']) ||
!empty($element['#webform_composite_elements']['postcode']['#required']);

if ($has_access && $is_any_address_line_required) {
// If there is an address search, but no elements to select
// (its a markup error)
// Then show an error to search for a local address or select can't find
// the address.
if (!empty($search_string) && $element['address_lookup']['address_select']['address_select_list']['#type'] == 'markup') {
$form_state->setError($element, t('Search for a local address, or select "Can\'t find the address" to enter an address.'));
}
// Else if there is a search but no address selected,
// set the select box as required.
elseif (!empty($search_string) && empty($selected)) {
WebformElementHelper::setRequiredError($element['address_lookup']['address_select']['address_select_list'], $form_state);
}
// Else mark the entire element as required.
elseif (empty($search_string) && empty($selected)) {
WebformElementHelper::setRequiredError($element, $form_state);
}

// Fetch errors, to allow any generated errors for the child elements
// to be removed.
$form_errors = $form_state->getErrors();
// Fetch errors, to allow any generated errors for the child elements
// to be removed.
$form_errors = $form_state->getErrors();

// Loop through errors and remove child elements, except the select
// element.
foreach ($form_errors as $error_key => $error_value) {
if (strpos($error_key, $element_key . ']') === 0 && $error_key != $element_key . '][address_lookup][address_select][address_select_list') {
unset($form_errors[$error_key]);
}
// Loop through errors and remove child elements, except the select
// element.
foreach ($form_errors as $error_key => $error_value) {
if (strpos($error_key, $element_key . ']') === 0 && $error_key != $element_key . '][address_lookup][address_select][address_select_list') {
unset($form_errors[$error_key]);
}
}

// If the search string and the select is empty, also remove the select
// error.
if (empty($search_string) && empty($selected)) {
unset($form_errors[$element_key . '][address_lookup][address_select][address_select_list']);
}
// If the search string and the select is empty, also remove the select
// error.
if (empty($search_string) && empty($selected)) {
unset($form_errors[$element_key . '][address_lookup][address_select][address_select_list']);
}

// Reset form errors and reset them with the cleaned ones.
$form_state->clearErrors();
foreach ($form_errors as $error_key => $error_value) {
$form_state->setErrorByName($error_key, $error_value);
}
// Reset form errors and reset them with the cleaned ones.
$form_state->clearErrors();
foreach ($form_errors as $error_key => $error_value) {
$form_state->setErrorByName($error_key, $error_value);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Plugin/WebformElement/AddressLookupElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @WebformElement(
* id = "localgov_forms_address_lookup",
* label = @Translation("LocalGov Address lookup"),
* label = @Translation("LocalGov Address select"),
* description = @Translation("Address lookup element."),
* category = @Translation("LocalGov Forms"),
* hidden = TRUE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
namespace Drupal\localgov_forms\Plugin\WebformElement;

use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformElement\WebformCompositeBase;
use Drupal\webform\WebformSubmissionInterface;

/**
* Provides a 'localgov_webform_uk_address' Webform element.
*
* @WebformElement(
* id = "localgov_webform_uk_address",
* label = @Translation("Localgov address lookup"),
* label = @Translation("LocalGov address lookup"),
* description = @Translation("Provides a UK address lookup element."),
* category = @Translation("Composite elements"),
* multiline = TRUE,
Expand All @@ -24,7 +25,7 @@
* @see \Drupal\webform\Plugin\WebformElementInterface
* @see \Drupal\webform\Annotation\WebformElement
*/
class LocalgovWebformUKAddress extends WebformUKAddress {
class UKAddressLookup extends WebformCompositeBase {

/**
* Declares our properties.
Expand Down Expand Up @@ -110,12 +111,11 @@ protected function formatHtmlItemValue(array $element, WebformSubmissionInterfac
protected function formatTextItemValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
$value = $this->getValue($element, $webform_submission, $options);

$lines = [];
$lines[] =
($value['address_1'] ? $value['address_1'] : '') .
$full_address_line = ($value['address_1'] ? $value['address_1'] : '') .
($value['address_2'] ? ' ' . $value['address_2'] : '') .
($value['town_city'] ? ' ' . $value['town_city'] : '') .
($value['postcode'] ? ' ' . $value['postcode'] : '');
$lines = $full_address_line ? [$full_address_line] : [];
return $lines;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Plugin/WebformElement/WebformUKAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @WebformElement(
* id = "webform_uk_address",
* label = @Translation("UK Address"),
* description = @Translation("Provides a UK address lookup webform element."),
* description = @Translation("Provides a UK address entry webform element."),
* category = @Translation("Composite elements"),
* multiline = TRUE,
* composite = TRUE,
Expand Down
15 changes: 15 additions & 0 deletions templates/localgov-forms-uk-address-lookup.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{#
/**
* @file
* Default theme implementation of our Address lookup element.
*
* Available variables:
* - content: The webform example composite to be output.
*
* @ingroup themeable
*/
#}

{{ attach_library('localgov_forms/localgov_forms_uk_address') }}

{{ content }}

0 comments on commit 64da889

Please sign in to comment.