Skip to content

Commit b8429d2

Browse files
committed
set address programitclaly
1 parent e7eacab commit b8429d2

File tree

5 files changed

+296
-51
lines changed

5 files changed

+296
-51
lines changed

forms-flow-rsbcservice/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ module.exports = {
44
"^.+\\.(j|t)sx?$": "babel-jest",
55
},
66
moduleNameMapper: {
7-
"\\.(css)$": "identity-obj-proxy",
7+
"\\.(css|scss)$": "identity-obj-proxy",
88
},
99
};

forms-flow-rsbcservice/src/component/BCMapSelector/AddressSearch.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,29 @@ interface AddressSearchProps {
66
onLocationSelect: (coordinates: { lat: number; lng: number }, address?: string) => void;
77
onError: (error: string) => void;
88
disabled?: boolean;
9+
initialAddress?: string;
910
}
1011

1112
const AddressSearch: React.FC<AddressSearchProps> = ({
1213
geocodingService,
1314
onLocationSelect,
1415
onError,
15-
disabled = false
16+
disabled = false,
17+
initialAddress = ''
1618
}) => {
17-
const [query, setQuery] = useState('');
19+
const [query, setQuery] = useState(initialAddress);
1820
const [results, setResults] = useState<GeocodingResult[]>([]);
1921
const [isSearching, setIsSearching] = useState(false);
2022
const [showResults, setShowResults] = useState(false);
2123
const [selectedIndex, setSelectedIndex] = useState(-1);
2224
const searchInputRef = useRef<HTMLInputElement>(null);
2325
const resultsRef = useRef<HTMLDivElement>(null);
2426

27+
// Update query when initialAddress changes
28+
useEffect(() => {
29+
setQuery(initialAddress);
30+
}, [initialAddress]);
31+
2532
// Handle search input change with debouncing
2633
useEffect(() => {
2734
if (!query.trim() || disabled || !geocodingService.isEnabled()) {

forms-flow-rsbcservice/src/component/BCMapSelector/BCMapSelector.settingsForm.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,11 @@ const settingsForm = (...extend) => {
446446
<ul style="margin-bottom: 15px; color: #6c757d;">
447447
<li><strong>mapSelected</strong> - Fired when a location is selected on the map. Event data contains lat/long coordinates.</li>
448448
<li><strong>mapCleared</strong> - Fired when the selected location is cleared from the map.</li>
449+
<li><strong>addressSet</strong> - Fired when an address is programmatically set using the setAddress method. Event data contains the address string.</li>
450+
</ul>
451+
<h5 style="color: #495057;">Public Methods:</h5>
452+
<ul style="margin-bottom: 15px; color: #6c757d;">
453+
<li><strong>setAddress(address: string)</strong> - Public method to set address programmatically. This method can be called externally to update the map location based on an address string.</li>
449454
</ul>
450455
<h5 style="color: #495057;">Example Event Listeners:</h5>
451456
<pre style="background-color: #f1f3f4; padding: 10px; border-radius: 4px; font-size: 12px; overflow-x: auto;"><code>if(instance && !instance.mapSelectedListner){
@@ -459,7 +464,15 @@ const settingsForm = (...extend) => {
459464
instance.root.getComponent("lat").setValue('')
460465
instance.root.getComponent("long").setValue('')
461466
});
467+
468+
instance.root.on('addressSet', async (event) => {
469+
const address = event.data;
470+
console.log('Address set programmatically:', address);
471+
});
462472
}</code></pre>
473+
<h5 style="color: #495057;">Example Method Usage:</h5>
474+
<pre style="background-color: #f1f3f4; padding: 10px; border-radius: 4px; font-size: 12px; overflow-x: auto;"><code>// Set address programmatically
475+
await instance.setAddress('123 Main St, Vancouver, BC');</code></pre>
463476
</div>
464477
`,
465478
},

forms-flow-rsbcservice/src/component/BCMapSelector/BCMapSelector.tsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import settingsForm from './BCMapSelector.settingsForm';
55
import MapModal from './MapModal';
66
import { MapProviderFactory, MapProviderConfig } from './mapProviders';
77
import { BCBoundaries, DEFAULT_BC_BOUNDARIES, validateCoordinatesWithinBoundaries } from './boundaryUtils';
8+
import { GeocodingService, createGeocodingConfig } from './geocodingUtils';
89
import './BCMapSelector.scss';
910
import './mapModal.scss';
1011

@@ -284,6 +285,85 @@ export default class BCMapSelector extends ReactComponent {
284285
}
285286
};
286287

288+
// Set address and coordinates programmatically (for form.io component integration)
289+
private setAddressInternal = async (address: string): Promise<void> => {
290+
if (!address || !address.trim()) {
291+
this.clearSelection();
292+
return;
293+
}
294+
295+
try {
296+
// Create geocoding service to search for the address
297+
const geocodingConfig = this.getGeocodingConfig();
298+
const geocodingService = new GeocodingService(geocodingConfig, this.getBCBoundaries());
299+
300+
if (!geocodingService.isEnabled()) {
301+
console.warn('Geocoding service is disabled, cannot set address');
302+
return;
303+
}
304+
305+
// Search for the address
306+
const results = await geocodingService.searchAddress(address);
307+
308+
if (!results || results.length === 0) {
309+
console.warn('No results found for address:', address);
310+
// Emit event for no results found
311+
(this as any).emit('addressNotFound', {
312+
data: {
313+
address: address,
314+
message: 'No results found for the provided address'
315+
}
316+
});
317+
return;
318+
}
319+
320+
// Use the first result
321+
const result = results[0];
322+
323+
// Update component data
324+
this.data = {
325+
coordinates: {
326+
lat: result.lat.toString(),
327+
long: result.lng.toString(),
328+
},
329+
address: result.address || result.display_name,
330+
selectionTimestamp: new Date().toISOString(),
331+
boundaryViolation: false,
332+
};
333+
334+
// Trigger form.io change event
335+
this.updateComponentValue(this.data);
336+
337+
// Emit addressSet event
338+
(this as any).emit('addressSet', {
339+
data: {
340+
lat: result.lat.toString(),
341+
long: result.lng.toString(),
342+
address: result.address || result.display_name,
343+
originalQuery: address
344+
}
345+
});
346+
347+
// Re-render to show updated coordinates
348+
this.renderComponent();
349+
350+
} catch (error) {
351+
console.error('Error setting address:', error);
352+
// Emit error event
353+
(this as any).emit('addressError', {
354+
data: {
355+
address: address,
356+
error: error.message || 'Failed to set address'
357+
}
358+
});
359+
}
360+
};
361+
362+
// Get geocoding configuration
363+
private getGeocodingConfig() {
364+
return createGeocodingConfig(this.component);
365+
}
366+
287367
// Clear the selected coordinates
288368
private clearSelection = () => {
289369
this.data = {
@@ -438,6 +518,11 @@ export default class BCMapSelector extends ReactComponent {
438518
}
439519
}
440520

521+
// Public method to set address programmatically (exposed for external use)
522+
public async setAddress(address: string): Promise<void> {
523+
return this.setAddressInternal(address);
524+
}
525+
441526
// Renders the BC Map Selector component within the given HTML element
442527
attachReact(element: HTMLElement): void {
443528
try {

0 commit comments

Comments
 (0)