Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions js/address_change.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* Populate Central Hub Selected Address
*
* Adds the selected address to drupalSettings.centralhub.selectedAddress.
*
* @param {jQuery} selectList
* Address selectlist element.
*/
Expand Down Expand Up @@ -87,7 +88,7 @@
var searchButton = addressLookupElement.find('.js-address-searchbutton');
var selectListContainer = addressLookupElement.find('.js-address-select-container');
var selectList = selectListContainer.find('.js-address-select');
var error = selectListContainer.find('.js-address-error');
var error = selectListContainer.find('.js-address-error, .error');

// Change the search button to normal button.
searchButton.attr('type', 'button');
Expand Down Expand Up @@ -154,7 +155,7 @@
var searchButton = addressLookupElement.find('.js-address-searchbutton');
var selectListContainer = addressLookupElement.find('.js-address-select-container');
var selectList = selectListContainer.find('.js-address-select');
var error = selectListContainer.find('.js-address-error');
var error = selectListContainer.find('.js-address-error, .error');
var resetButton = addressLookupElement.find('.js-reset-address');
var manualButton = addressLookupElement.find('.js-manual-address');
var manualAddressContainer = addressLookupElement.find('+ .js-address-entry-container');
Expand Down
13 changes: 1 addition & 12 deletions js/address_select.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
function hideManualAddress(centralHubElement, type, settings) {
var manualAddressContainer = centralHubElement.find('.js-address-entry-container');
var manualButton = centralHubElement.find('.js-manual-address');
var addressSelectContainer = centralHubElement.find('.js-address-select-container');
manualAddressContainer.addClass('hidden');

if (type == 'hard') {
Expand All @@ -63,24 +62,18 @@

/**
* Show the manual address form elements.
*
* @param {jQuery} centralHubElement
* Centralhub address element.
*/
function showManualAddress(centralHubElement) {
var manualAddressContainer = centralHubElement.find('.js-address-entry-container');
var manualButton = centralHubElement.find('.js-manual-address');
var addressSelectContainer = centralHubElement.find('.js-address-select-container');
var addressSelect = addressSelectContainer.find('select');
var searchElement = centralHubElement.find('.js-address-searchstring');
var addressError = addressSelectContainer.find('.js-address-error');
manualAddressContainer.removeClass('hidden');
// manualAddressContainer.find('input').val('');
manualButton.hide();
// addressSelectContainer.addClass('hidden');
// addressSelect.val('0');
// Clear the search element when entering a manual address.
// This is to pass validation.
// searchElement.val('');
// Remove the error element when making a manual address.
addressError.remove();
}
Expand Down Expand Up @@ -174,7 +167,6 @@
central_hub_webform_address_container.find('input.js-localgov-forms-webform-uk-address--' + value).val(addressSelected[value]);
});

// hideManualAddress(centralHubElement, 'soft');
showManualAddress(centralHubElement);
} else if ($(this).val() == 0) {
// If choosing the empty option, clear out the address fields.
Expand Down Expand Up @@ -211,9 +203,6 @@
hideManualAddress(centralHubElement, 'soft', settings);
}

// centralHubElement.find('.js-address-searchstring').change(function() {
// hideManualAddress(centralHubElement, 'hard');
// });
centralHubElement.find('.js-reset-address').click(function () {
hideManualAddress(centralHubElement, 'hard', settings);
});
Expand Down
6 changes: 4 additions & 2 deletions src/Element/AddressLookupElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ public static function processAddressLookupElement(&$element, FormStateInterface

$element['address_search']['address_searchstring'] = [
'#type' => 'textfield',
'#title' => t('Postcode or Street'),
'#title' => t('Postcode or street'),
'#description' => $element['#address_search_description'] ?? t('Enter the postcode…'),
'#required_error' => t('You must enter a postcode or street.'),
'#maxlength' => 64,
'#size' => 64,
'#weight' => '0',
Expand Down Expand Up @@ -164,6 +165,7 @@ public static function processAddressLookupElement(&$element, FormStateInterface
$element['address_select']['address_select_list'] = [
'#type' => 'select',
'#title' => $element['#address_select_title'] ?? t('Select the address'),
'#required_error' => t('You must select an address.'),
'#options' => [],
'#empty_option' => '-' . t('Please choose an address') . '-',
'#empty_value' => 0,
Expand All @@ -189,7 +191,7 @@ public static function processAddressLookupElement(&$element, FormStateInterface
$parent_container = $parent_container[$keyval];
}

// Extract the parent values form container.
// Extract the parent values from container.
$parent_container_values = $form_values;
foreach ($parents as $keyval) {
$parent_container_values = $parent_container_values[$keyval];
Expand Down
55 changes: 45 additions & 10 deletions src/Element/UKAddressLookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public static function getCompositeElements(array $element) {
$element_list['address_1']['#prefix'] = '<div class="js-address-entry-container">';
$element_list['postcode']['#suffix'] = '</div>';

// Custom error message for address line 1.
$element_list['address_1']['#required_error'] = t('You must enter an address.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking this. But might be worth moving to StringTranslationTrait at some point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It caused me some unease as well. But eventually stuck to the t() function for consistency with the rest of the file. I have just raised a ticket to replace the entire lot.


// Extras to store information for webform builders to access in
// computed twig.
// @See DRUP-1287.
Expand Down Expand Up @@ -98,14 +101,22 @@ public static function validateWebformComposite(&$element, FormStateInterface $f
return;
}

// Temporarily reset the #limit_validation_errors property. Otherwise we
// can't safely set and manipulate errors below.
//
// @see Drupal\Core\Form\FormState::setErrorByName()
// @see AddressLookupElement::processAddressLookupElement()
$orig_limit_validation_errors = $form_state->getLimitValidationErrors();
$form_state->setLimitValidationErrors(NULL);

// If the element or any of its parent containers are hidden by conditions,
// Bypass validation and clear any required element errors generated
// for this element.
if (!WebformHelper::isElementVisibleThroughParent($element, $form_state, $complete_form)) {
$form_errors = $form_state->getErrors();
$form_state->clearErrors();
foreach ($form_errors as $error_key => $error_value) {
if (strpos($error_key, $element_key . ']') !== 0) {
if (strpos($error_key, $element_key . ']') === FALSE) {
$form_state->setErrorByName($error_key, $error_value);
}
}
Expand All @@ -115,6 +126,7 @@ public static function validateWebformComposite(&$element, FormStateInterface $f
// Get the search string and selected value.
$search_string = $value['address_lookup']['address_search']['address_searchstring'];
$selected = $value['address_lookup']['address_select']['address_select_list'] ?? [];
$is_address_lookup_op = $form_state->getTriggeringElement()['#name'] === $element_key . '[address_lookup][address_search][address_actions][address_searchbutton]';

// Check to see if there are values in the address element form.
$has_address_values = FALSE;
Expand All @@ -126,9 +138,8 @@ public static function validateWebformComposite(&$element, FormStateInterface $f
}
}

// If the select is empty, and the manual address elements are filled in,
// validate the parent element.
if (empty($selected) && $has_address_values) {
// If the manual address elements are filled in, validate the parent.
if (!$is_address_lookup_op && $has_address_values) {
// Clear the address search string.
// This is to avoid the select box maintaing a value
// (it's cleared if search string is empty).
Expand All @@ -151,26 +162,46 @@ public static function validateWebformComposite(&$element, FormStateInterface $f
// 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.'));
$form_state->setError($element['address_lookup']['address_search']['address_searchstring'], t('Enter a local address, or select "Can\'t find the address".'));

// Inline form errors don't work well for this element in Ajax calls.
// This is because the Ajax callback attached to the `Find address`
// button updates only *part* of the address lookup element. As a
// result, any error set on any other part of the address lookup element
// is lost. To avoid this, we disable inline errors here. There is an
// assumption here that the `Find address` button is using Ajax. This
// assumption is good enough for most cases but degrades without Ajax.
if ($is_address_lookup_op) {
$complete_form['#disable_inline_form_errors'] = TRUE;
}
}
// Else if there is a search but no address selected,
// set the select box as required.
elseif (!empty($search_string) && empty($selected)) {
elseif (!empty($search_string) && empty($selected) && !$is_address_lookup_op) {
WebformElementHelper::setRequiredError($element['address_lookup']['address_select']['address_select_list'], $form_state);

// UI needs a hint that we are in the middle of a search.
$element['address_lookup']['address_search']['address_actions']['address_searchbutton']['#attributes']['class'][] = 'js-searching';
}
// Else mark the entire element as required.
elseif (empty($search_string) && empty($selected)) {
WebformElementHelper::setRequiredError($element, $form_state);
WebformElementHelper::setRequiredError($element['address_lookup']['address_search']['address_searchstring'], $form_state);

// As explained above, inline form errors don't work well for this
// element in Ajax calls.
if ($is_address_lookup_op) {
$complete_form['#disable_inline_form_errors'] = TRUE;
}
}

// 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.
// and search query elements.
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') {
if (strpos($error_key, $element_key . ']') === 0 && ($error_key !== $element_key . '][address_lookup][address_select][address_select_list' && $error_key !== $element_key . '][address_lookup][address_search][address_searchstring')) {
unset($form_errors[$error_key]);
}
}
Expand All @@ -181,13 +212,17 @@ public static function validateWebformComposite(&$element, FormStateInterface $f
unset($form_errors[$element_key . '][address_lookup][address_select][address_select_list']);
}

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

// Restore original value of the `limit_validation_errors` property now that
// we are done with manipulating errors.
$form_state->setLimitValidationErrors($orig_limit_validation_errors);

// Clear empty composites value.
if (empty(array_filter($value))) {
$element['#value'] = NULL;
Expand Down
2 changes: 2 additions & 0 deletions src/Element/WebformUKAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public static function getCompositeElements(array $element) {
$elements['town_city'] = [
'#type' => 'textfield',
'#title' => t('Town/City'),
'#required_error' => t('You must enter the town/city.'),
'#attributes' => [
'data-webform-composite-id' => $html_id . '--town_city',
// Add a namespaced class for setting the address fields
Expand All @@ -78,6 +79,7 @@ public static function getCompositeElements(array $element) {
$elements['postcode'] = [
'#type' => 'textfield',
'#title' => t('Postcode'),
'#required_error' => t('You must enter the postcode.'),
'#attributes' => [
'data-webform-composite-id' => $html_id . '--postcode',
// Add a namespaced class for setting the address fields
Expand Down
Loading