|
| 1 | +/* |
| 2 | + * @license |
| 3 | + * Copyright 2025 Google LLC. All Rights Reserved. |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +// [START maps_address_validation] |
| 8 | +// --- DOM Refs --- |
| 9 | +const addressForm = document.getElementById('address-form'); |
| 10 | +const validateButton = document.getElementById('validate-button'); |
| 11 | +const clearFormButton = document.getElementById('clear-form-button'); |
| 12 | +const resultDisplay = document.getElementById('result-display'); |
| 13 | +const loadingText = document.getElementById('loading-text'); |
| 14 | +// --- Input field refs --- |
| 15 | +const streetAddress1Input = document.getElementById('street-address-1') as HTMLInputElement; |
| 16 | +const streetAddress2Input = document.getElementById('street-address-2') as HTMLInputElement; |
| 17 | +const cityInput = document.getElementById('city') as HTMLInputElement; |
| 18 | +const stateInput = document.getElementById('state') as HTMLInputElement; |
| 19 | +const zipCodeInput = document.getElementById('zip-code') as HTMLInputElement; |
| 20 | +const regionSelect = document.getElementById('region-select') as HTMLSelectElement; |
| 21 | +const exampleSelect = document.getElementById('example-select') as HTMLSelectElement; |
| 22 | + |
| 23 | +// --- Core Initialization --- |
| 24 | +async function init() { |
| 25 | + // Load the Address Validation library |
| 26 | + await google.maps.importLibrary('addressValidation'); |
| 27 | + // Set event listeners |
| 28 | + addressForm!.addEventListener('submit', handleValidationSubmit); |
| 29 | + exampleSelect!.addEventListener('change', handleExampleSelectChange); |
| 30 | + clearFormButton!.addEventListener('click', handleClearForm); |
| 31 | +} |
| 32 | + |
| 33 | +// [START maps_address_validation_form_handler] |
| 34 | +// --- Validation Handler --- |
| 35 | +async function handleValidationSubmit(event) { |
| 36 | + event.preventDefault(); // Prevent default form submission |
| 37 | + resultDisplay!.textContent = 'Validating...'; // Clear previous results |
| 38 | + |
| 39 | + // Validate the address |
| 40 | + try { |
| 41 | + //@ts-ignore |
| 42 | + const result = await google.maps.addressValidation.AddressValidation.fetchAddressValidation({ |
| 43 | + address: { |
| 44 | + regionCode: regionSelect!.value.trim(), |
| 45 | + languageCode: 'en', |
| 46 | + addressLines: [ |
| 47 | + streetAddress1Input!.value.trim(), |
| 48 | + streetAddress2Input!.value.trim() |
| 49 | + ].filter(line => line), // Filter out empty lines |
| 50 | + locality: cityInput!.value.trim(), |
| 51 | + administrativeArea: stateInput!.value.trim(), |
| 52 | + postalCode: zipCodeInput!.value.trim(), |
| 53 | + }, |
| 54 | + }); |
| 55 | + |
| 56 | + resultDisplay!.textContent = |
| 57 | + "Verdict summary\n================\n" + |
| 58 | + `Formatted address: ${result.address.formattedAddress}\n` + |
| 59 | + `Entered: ${result.verdict.inputGranularity}\n` + |
| 60 | + `Validated: ${result.verdict.validationGranularity}\n` + |
| 61 | + `Geocoded: ${result.verdict.geocodeGranularity}\n\n` + |
| 62 | + `${getVerdictMessage(result.verdict, 'addressComplete')}\n` + |
| 63 | + `${getVerdictMessage(result.verdict, 'hasUnconfirmedComponents')}\n` + |
| 64 | + `${getVerdictMessage(result.verdict, 'hasInferredComponents')}\n` + |
| 65 | + `${getVerdictMessage(result.verdict, 'hasReplacedComponents')}\n\n` + |
| 66 | + `Raw JSON response\n=================\n` + |
| 67 | + JSON.stringify(result, null, ' '); |
| 68 | + |
| 69 | + } catch (error) { |
| 70 | + console.error('Validation failed:', error); |
| 71 | + if (error instanceof Error) { |
| 72 | + resultDisplay!.textContent = `Error: ${error.message}`; |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | +// [END maps_address_validation_form_handler] |
| 77 | + |
| 78 | +// --- Verdict Messages --- |
| 79 | +const verdictMessages = { |
| 80 | + addressComplete: { |
| 81 | + trueMessage: |
| 82 | + '- The API found no unresolved, unexpected, or missing address elements.', |
| 83 | + falseMessage: |
| 84 | + '- At least one address element is unresolved, unexpected, or missing.', |
| 85 | + }, |
| 86 | + hasUnconfirmedComponents: { |
| 87 | + trueMessage: '- The API can\'t confirm at least one address component.', |
| 88 | + falseMessage: '- The API confirmed all address components.', |
| 89 | + }, |
| 90 | + hasInferredComponents: { |
| 91 | + trueMessage: '- The API inferred (added) at least one address component.', |
| 92 | + falseMessage: '- The API did not infer (add) any address components.', |
| 93 | + }, |
| 94 | + hasReplacedComponents: { |
| 95 | + trueMessage: '- The API replaced at least one address component.', |
| 96 | + falseMessage: '- The API did not replace any address components.', |
| 97 | + }, |
| 98 | +}; |
| 99 | + |
| 100 | +// Helper function to get the verdict message for a given verdict key |
| 101 | +function getVerdictMessage(verdict, key) { |
| 102 | + if (!verdict || !verdictMessages[key]) return 'Unknown'; |
| 103 | + return verdict[key] ? verdictMessages[key].trueMessage : |
| 104 | + verdictMessages[key].falseMessage; |
| 105 | +} |
| 106 | + |
| 107 | +// Handler for Dropdown Change |
| 108 | +function handleExampleSelectChange(event) { |
| 109 | + const selectedValue = event.target.value; // e.g., "google", "suite", "" |
| 110 | + if (selectedValue && examples[selectedValue]) { |
| 111 | + populateAddressFields(examples[selectedValue]); |
| 112 | + } else if (!selectedValue) { |
| 113 | + // Optional: Clear fields if the "-- Select --" option is chosen |
| 114 | + populateAddressFields(null); // Pass null to clear fields |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +// Clear Form Handler |
| 119 | +function handleClearForm() { |
| 120 | + streetAddress1Input!.value = ''; |
| 121 | + streetAddress2Input!.value = ''; |
| 122 | + cityInput!.value = ''; |
| 123 | + stateInput!.value = ''; |
| 124 | + zipCodeInput!.value = ''; |
| 125 | + regionSelect!.value = ''; |
| 126 | + exampleSelect!.value = ''; |
| 127 | + resultDisplay!.textContent = 'Result will appear here...'; |
| 128 | + console.log('Cleared form'); |
| 129 | +} |
| 130 | + |
| 131 | +// Example Address Data |
| 132 | +const examples = { |
| 133 | + google: { |
| 134 | + streetAddress1: '1600 Amphitheatre Parkway', |
| 135 | + streetAddress2: '', // Explicitly empty |
| 136 | + city: 'Mountain View', |
| 137 | + state: 'CA', |
| 138 | + zipCode: '94043', |
| 139 | + region: 'US' |
| 140 | + }, |
| 141 | + nonExistentSubpremise: { |
| 142 | + streetAddress1: '2930 Pearl St.', |
| 143 | + streetAddress2: 'Suite 100', |
| 144 | + city: 'Boulder', |
| 145 | + state: 'CO', |
| 146 | + zipCode: '', // Explicitly empty |
| 147 | + region: 'US' |
| 148 | + }, |
| 149 | + missingSubpremise: { |
| 150 | + streetAddress1: '500 West 2nd Street', |
| 151 | + streetAddress2: null, // Can use null or undefined too |
| 152 | + city: 'Austin', |
| 153 | + state: 'TX', |
| 154 | + zipCode: '78701', |
| 155 | + region: 'US' |
| 156 | + }, |
| 157 | + misspelledLocality: { |
| 158 | + streetAddress1: '1600 Amphitheatre Pkwy', |
| 159 | + streetAddress2: '', |
| 160 | + city: 'Montan View', |
| 161 | + state: 'CA', |
| 162 | + zipCode: '94043', |
| 163 | + region: 'US' |
| 164 | + }, |
| 165 | + missingLocality: { |
| 166 | + streetAddress1: 'Brandschenkestrasse 110 8002', |
| 167 | + streetAddress2: '', |
| 168 | + city: '', |
| 169 | + state: '', |
| 170 | + zipCode: '', |
| 171 | + region: '' |
| 172 | + }, |
| 173 | + usPoBox: { |
| 174 | + streetAddress1: 'PO Box 1108', |
| 175 | + streetAddress2: '', |
| 176 | + city: 'Sterling', |
| 177 | + state: 'VA', |
| 178 | + zipCode: '20166-1108', |
| 179 | + region: 'US' |
| 180 | + }, |
| 181 | +}; |
| 182 | + |
| 183 | +// Helper function to populate form fields with example address data |
| 184 | +function populateAddressFields(exampleAddress) { |
| 185 | + if (!exampleAddress) { |
| 186 | + console.warn("No example address data provided."); |
| 187 | + return; |
| 188 | + } |
| 189 | + |
| 190 | + // Get values from example, providing empty string as default |
| 191 | + streetAddress1Input!.value = exampleAddress.streetAddress1 || ''; |
| 192 | + streetAddress2Input!.value = exampleAddress.streetAddress2 || ''; |
| 193 | + cityInput!.value = exampleAddress.city || ''; |
| 194 | + stateInput!.value = exampleAddress.state || ''; |
| 195 | + zipCodeInput!.value = exampleAddress.zipCode || ''; |
| 196 | + regionSelect!.value = exampleAddress.region || ''; |
| 197 | + |
| 198 | + // Clear previous results and errors |
| 199 | + resultDisplay!.textContent = 'Result will appear here...'; |
| 200 | + |
| 201 | + console.log("Populated fields with example:", exampleAddress); |
| 202 | +} |
| 203 | + |
| 204 | +init(); |
| 205 | +// [END maps_address_validation] |
0 commit comments