diff --git a/assets/js/autocomplete.js b/assets/js/autocomplete.js
index 62d5e9c9f..aa16b0941 100644
--- a/assets/js/autocomplete.js
+++ b/assets/js/autocomplete.js
@@ -66,6 +66,7 @@ const getTranslation = (fullName) => {
parent.classList.add('hds-text-input--invalid');
const errorSpan = document.createElement('span');
errorSpan.classList.add('hds-text-input__error-text');
+ errorSpan.id = 'js-locate-error';
errorSpan.textContent = Drupal.t(
"We couldn't retrieve your current location. Try entering an address.",
{},
@@ -229,6 +230,11 @@ const getTranslation = (fullName) => {
});
// Hide location error input when changing input
element.addEventListener('change', removeLocationError);
+
+ // Focus input if there is a validation error on page load.
+ if (element.classList.contains('error')) {
+ element.focus();
+ }
};
Drupal.behaviors.helfi_location_autocomplete = {
diff --git a/dist/js/autocomplete.min.js b/dist/js/autocomplete.min.js
index 01f8bc31b..6733fb3d6 100644
--- a/dist/js/autocomplete.min.js
+++ b/dist/js/autocomplete.min.js
@@ -1 +1 @@
-(()=>{var t=Object.defineProperty;var e=(e,o)=>t(e,"name",{value:o,configurable:true});var o=Drupal.t("Use current Location",{},{context:"Location autocomplete"});var n="https://api.hel.fi/servicemap/v2/address/";var a="location-loading";var{currentLanguage:s}=drupalSettings.path;var r=`\n
\n \n ${o}\n
\n`;var i=new AbortController;var c=e(t=>{if(t[s]){return t[s]}if(t.fi){return t.fi}return Object.values(t)[0]},"getTranslation");((Drupal,once)=>{const t=e(t=>{if(!A11yAutocomplete){throw new Error("A11yAutocomplete object not found. Make sure the library is loaded.")}let s="geolocation"in navigator?[{label:r,value:o,index:0,item:{label:o,value:o}}]:[];const l=t.closest(".hds-text-input");const u=e(()=>{l.classList.add("hds-text-input--invalid");const t=document.createElement("span");t.classList.add("hds-text-input__error-text");t.textContent=Drupal.t("We couldn't retrieve your current location. Try entering an address.",{},{context:"Location autocomplete"});l.appendChild(t);s=[]},"displayLocationError");const d=e(()=>{l.classList.remove("hds-text-input--invalid");l.querySelector(".hds-text-input__error-text")?.remove()},"removeLocationError");const p=Drupal.t("Type @count or more characters for results",{},{context:"Location autocomplete"});const h=Drupal.t("When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.",{},{context:"Location autocomplete"});const v=Drupal.t("No address suggestions were found",{},{context:"Location autocomplete"});const g=Drupal.t("There are @count results available.",{},{context:"Location autocomplete"});const m=Drupal.t("There is one result available.",{},{context:"Location autocomplete"});const f=Drupal.t("@selectedItem @position of @count is highlighted",{},{context:"Location autocomplete"});const L=t.dataset.autocompletePath;const w=A11yAutocomplete(t,{allowRepeatValues:true,classes:{inputLoading:"loading",wrapper:"helfi-location-autocomplete"},highlightedAssistiveHint:f,inputAssistiveHint:h,minCharAssistiveHint:p,minChars:0,noResultsAssistiveHint:v,oneResultAssistiveHint:m,someResultsAssistiveHint:g,source:e(async(t,e)=>{try{i.abort();i=new AbortController;if(t.length<3){return e(s)}const o=new URL(L,window.location.origin);o.searchParams.set("q",t);const n=await fetch(o.toString(),{signal:i.signal});const a=await n.json();e(s.concat(a))}catch(t){if(t.name==="AbortError"){return}console.error(t);e(s)}},"source")});const y=w._internal_object;const x=e(e=>{y.close();if(e){t.classList.toggle(a,true);return}t.classList.toggle(a,false)},"setLoading");t.addEventListener("autocomplete-select",e=>{if(e.detail.selected.value!==o){return}e.preventDefault();x(t,y,true);navigator.geolocation.getCurrentPosition(async t=>{const{coords:{latitude:o,longitude:a}}=t;const s=new URLSearchParams({lat:o,lon:a});const r=new URL(n);r.search=s.toString();try{const t=await fetch(r.toString());const o=await t.json();e.target.value=c(o.results[0].full_name)}catch(t){u()}finally{x(false)}},()=>{u();x(false)})});t.addEventListener("focus",()=>{if(t.classList.contains(a)){return}if(y.input.value===""&&s.length){y.displayResults(s)}});t.addEventListener("keydown",t=>{if(y.input.value===""&&s.length&&y.suggestions.length===0&&t.key==="ArrowDown"){y.displayResults(s)}});t.addEventListener("change",d)},"init");Drupal.behaviors.helfi_location_autocomplete={attach(e){once("a11y_autocomplete_element","[data-helfi-location-autocomplete]",e).forEach(t)}}})(Drupal,once)})();
\ No newline at end of file
+(()=>{var t=Object.defineProperty;var e=(e,o)=>t(e,"name",{value:o,configurable:true});var o=Drupal.t("Use current Location",{},{context:"Location autocomplete"});var n="https://api.hel.fi/servicemap/v2/address/";var a="location-loading";var{currentLanguage:s}=drupalSettings.path;var r=`\n \n \n ${o}\n
\n`;var i=new AbortController;var c=e(t=>{if(t[s]){return t[s]}if(t.fi){return t.fi}return Object.values(t)[0]},"getTranslation");((Drupal,once)=>{const t=e(t=>{if(!A11yAutocomplete){throw new Error("A11yAutocomplete object not found. Make sure the library is loaded.")}let s="geolocation"in navigator?[{label:r,value:o,index:0,item:{label:o,value:o}}]:[];const l=t.closest(".hds-text-input");const u=e(()=>{l.classList.add("hds-text-input--invalid");const t=document.createElement("span");t.classList.add("hds-text-input__error-text");t.id="js-locate-error";t.textContent=Drupal.t("We couldn't retrieve your current location. Try entering an address.",{},{context:"Location autocomplete"});l.appendChild(t);s=[]},"displayLocationError");const d=e(()=>{l.classList.remove("hds-text-input--invalid");l.querySelector(".hds-text-input__error-text")?.remove()},"removeLocationError");const p=Drupal.t("Type @count or more characters for results",{},{context:"Location autocomplete"});const h=Drupal.t("When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.",{},{context:"Location autocomplete"});const v=Drupal.t("No address suggestions were found",{},{context:"Location autocomplete"});const g=Drupal.t("There are @count results available.",{},{context:"Location autocomplete"});const m=Drupal.t("There is one result available.",{},{context:"Location autocomplete"});const f=Drupal.t("@selectedItem @position of @count is highlighted",{},{context:"Location autocomplete"});const L=t.dataset.autocompletePath;const w=A11yAutocomplete(t,{allowRepeatValues:true,classes:{inputLoading:"loading",wrapper:"helfi-location-autocomplete"},highlightedAssistiveHint:f,inputAssistiveHint:h,minCharAssistiveHint:p,minChars:0,noResultsAssistiveHint:v,oneResultAssistiveHint:m,someResultsAssistiveHint:g,source:e(async(t,e)=>{try{i.abort();i=new AbortController;if(t.length<3){return e(s)}const o=new URL(L,window.location.origin);o.searchParams.set("q",t);const n=await fetch(o.toString(),{signal:i.signal});const a=await n.json();e(s.concat(a))}catch(t){if(t.name==="AbortError"){return}console.error(t);e(s)}},"source")});const y=w._internal_object;const x=e(e=>{y.close();if(e){t.classList.toggle(a,true);return}t.classList.toggle(a,false)},"setLoading");t.addEventListener("autocomplete-select",e=>{if(e.detail.selected.value!==o){return}e.preventDefault();x(t,y,true);navigator.geolocation.getCurrentPosition(async t=>{const{coords:{latitude:o,longitude:a}}=t;const s=new URLSearchParams({lat:o,lon:a});const r=new URL(n);r.search=s.toString();try{const t=await fetch(r.toString());const o=await t.json();e.target.value=c(o.results[0].full_name)}catch(t){u()}finally{x(false)}},()=>{u();x(false)})});t.addEventListener("focus",()=>{if(t.classList.contains(a)){return}if(y.input.value===""&&s.length){y.displayResults(s)}});t.addEventListener("keydown",t=>{if(y.input.value===""&&s.length&&y.suggestions.length===0&&t.key==="ArrowDown"){y.displayResults(s)}});t.addEventListener("change",d);if(t.classList.contains("error")){t.focus()}},"init");Drupal.behaviors.helfi_location_autocomplete={attach(e){once("a11y_autocomplete_element","[data-helfi-location-autocomplete]",e).forEach(t)}}})(Drupal,once)})();
\ No newline at end of file
diff --git a/helfi_platform_config.module b/helfi_platform_config.module
index 1c49fd6b8..01e901ad9 100644
--- a/helfi_platform_config.module
+++ b/helfi_platform_config.module
@@ -502,3 +502,12 @@ function helfi_platform_config_preprocess_page(array &$variables) : void {
$variables['#attached']['library'][] = 'helfi_platform_config/heading_anchor_buttons';
}
}
+
+/**
+ * Implements hook_preprocess_HOOK().
+ */
+function helfi_platform_config_preprocess_form_element__helfi_location_autocomplete(array &$variables):void {
+ if (isset($variables['element']['#errors']) && empty($variables['errors'])) {
+ $variables['errors'] = $variables['element']['#errors'];
+ }
+}
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index ffcb59c0a..6059196e9 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -75,6 +75,11 @@ parameters:
count: 1
path: helfi_platform_config.module
+ -
+ message: "#^Function helfi_platform_config_preprocess_form_element__helfi_location_autocomplete\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#"
+ count: 1
+ path: helfi_platform_config.module
+
-
message: "#^Function helfi_platform_config_preprocess_html\\(\\) has parameter \\$variables with no type specified\\.$#"
count: 1