1import { Controller } from "@hotwired/stimulus" 2 3// Drives the inline "edit shipping address" form on the customer order page. 4// - Pre-fills fields when a saved address radio is selected. 5// - Replaces the state/province <select> options when the country changes, 6// using the shipping_states JSON endpoint. 7export default class extends Controller { 8 static targets = [ 9 "savedRadio", "firstName", "lastName", "address1", "address2", 10 "city", "province", "zip", "country", "provinceWrapper", "provinceText" 11 ] 12 static values = { statesUrl: String } 13 14 async countryChanged() { 15 await this.loadStatesFor(this.countryTarget.value) 16 } 17 18 async loadStatesFor(country) { 19 if (!country) return 20 try { 21 const res = await fetch(`${this.statesUrlValue}?country=${encodeURIComponent(country)}`, { 22 headers: { "Accept": "application/json" } 23 }) 24 if (!res.ok) return 25 const data = await res.json() 26 const states = data.states || [] 27 const current = this.provinceTarget.value 28 29 if (states.length === 0) { 30 this.provinceTarget.classList.add("hidden") 31 this.provinceTarget.disabled = true 32 this.provinceTarget.innerHTML = "" 33 if (this.hasProvinceTextTarget) { 34 this.provinceTextTarget.classList.remove("hidden") 35 this.provinceTextTarget.disabled = false 36 } 37 } else { 38 this.provinceTarget.classList.remove("hidden") 39 this.provinceTarget.disabled = false 40 this.provinceTarget.innerHTML = 41 `<option value="">Select stateâ¦</option>` + 42 states.map(s => `<option value="${s.code}" ${s.code === current ? "selected" : ""}>${s.name}</option>`).join("") 43 if (this.hasProvinceTextTarget) { 44 this.provinceTextTarget.classList.add("hidden") 45 this.provinceTextTarget.disabled = true 46 } 47 } 48 } catch (e) { 49 // Network error â leave the field as-is 50 console.warn("[order-shipping-editor] failed to load states", e) 51 } 52 } 53 54 useSaved(event) { 55 const radio = event.currentTarget 56 if (!radio.checked) return 57 const d = radio.dataset 58 59 if (this.hasFirstNameTarget) this.firstNameTarget.value = d.firstName || "" 60 if (this.hasLastNameTarget) this.lastNameTarget.value = d.lastName || "" 61 if (this.hasAddress1Target) this.address1Target.value = d.address1 || "" 62 if (this.hasAddress2Target) this.address2Target.value = d.address2 || "" 63 if (this.hasCityTarget) this.cityTarget.value = d.city || "" 64 if (this.hasZipTarget) this.zipTarget.value = d.zip || "" 65 if (this.hasCountryTarget && d.country) { 66 this.countryTarget.value = d.country 67 // Load states for the new country, then set province 68 this.loadStatesFor(d.country).then(() => { 69 if (this.hasProvinceTarget && d.province) this.provinceTarget.value = d.province 70 if (this.hasProvinceTextTarget && d.province) this.provinceTextTarget.value = d.province 71 }) 72 } else if (this.hasProvinceTarget && d.province) { 73 this.provinceTarget.value = d.province 74 } 75 } 76 77 clearSaved() { 78 this.savedRadioTargets.forEach(r => { r.checked = false }) 79 } 80}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.