Autocompletado de direcciones con Google Maps (Blazor)
Ejemplo muestra cómo implementar un formulario de dirección en una aplicación Blazor
2
3
Funciones JavaScript necesarias
function googleMapsIsAvailable() {
const script = document.querySelector('#maps-api');
const cargado = !!(window.google && google.maps && google.maps.places);
if (!cargado && script) {
console.warn("Google Maps cargado pero Places no disponible — posible error de referrer o clave.");
return false;
}
return cargado;
}
function initAutocomplete(uniqueIdSuffix, dotNetHelper) {
if (!googleMapsIsAvailable()) { return; }
const input = document.getElementById('autocomplete_' + uniqueIdSuffix);
const options = { types: ['geocode'], };
const autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.addListener('place_changed', function () {
const place = autocomplete.getPlace();
if (place.address_components) {
const address = {
city: '',
province: '',
postalCode: '',
country: '',
countryCode: ''
};
place.address_components.forEach(component => {
const types = component.types;
if (types.includes('route')) {
} else if (types.includes('locality')) {
address.city = component.long_name;
} else if (types.includes('administrative_area_level_2')) {
address.province = component.long_name;
} else if (types.includes('postal_code')) {
address.postalCode = component.long_name;
} else if (types.includes('country')) {
address.country = component.long_name;
address.countryCode = component.short_name;
}
});
dotNetHelper.invokeMethodAsync('SetAddress', address);
}
});
}
4
Componente Blazor
@inject IJSRuntime JS
<RadzenFormField class=@("w-100 m-2 " + (AddressData.AddressLine1.IsEmpty() ? "obli" : "")) Text="Dirección" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"autocomplete_{uniqueIdSuffix}")" @bind-Value="AddressData.AddressLine1" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
<RadzenFormField class="w-100 m-2" Text="Dirección 2" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled Placeholder="Piso, Planta..." id="@($"direccion2_{uniqueIdSuffix}")" @bind-Value="AddressData.AddressLine2" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
<div class="d-flex gap-2">
<RadzenFormField class=@("w-50 m-2 " + (AddressData.City.IsEmpty() ? "obli" : "")) Text="Municipio" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"city_{uniqueIdSuffix}")" @bind-Value="AddressData.City" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
<RadzenFormField class=@("w-25 m-2 " + (AddressData.Province.IsEmpty() ? "obli" : "")) Text="Provincia" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"province_{uniqueIdSuffix}")" @bind-Value="AddressData.Province" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
<RadzenFormField class=@("w-25 m-2 " + (AddressData.PostalCode.IsEmpty() ? "obli" : "")) Text="Código Postal" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"postalCode_{uniqueIdSuffix}")" @bind-Value="AddressData.PostalCode" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
</div>
<div class="d-flex gap-2">
<RadzenFormField class=@("w-50 m-2 " + (AddressData.Country.IsEmpty() ? "obli" : "")) Text="País" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"country_{uniqueIdSuffix}")" @bind-Value="AddressData.Country" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
@if (WithCountryCode)
{
<RadzenFormField class=@("w-50 m-2 " + (AddressData.CountryCode.IsEmpty() ? "obli" : "")) Text="Código País" Variant="Variant.Flat">
<RadzenTextBox Disabled=@Disabled id="@($"countrycode_{uniqueIdSuffix}")" @bind-Value="AddressData.CountryCode" Style="width: 100%;" @bind-Value:after=@onChange />
</RadzenFormField>
}
</div>
@code {
private string uniqueIdSuffix = Guid.NewGuid().ToString("N");
[Parameter]
public bool Disabled { get; set; }
[Parameter]
public bool WithCountryCode { get; set; } = true;
[Parameter]
public EventCallback OnChange { get; set; }
[Parameter]
public Dinaup.AddressModel AddressData { get; set; }
bool prevenChange = false;
void onChange()
{
if (AddressData.CountryCode.IsNotEmpty())
AddressData.CountryCode = AddressData.CountryCode.ToUpper();
if (prevenChange == false)
OnChange.InvokeAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
await JS.InvokeVoidAsync("initAutocomplete", uniqueIdSuffix, DotNetObjectReference.Create(this));
}
[JSInvokable]
public void SetAddress(AddressDTO address)
{
if (Disabled) return;
prevenChange = true;
AddressData.City = Dinaup.ValidationUtils.NormalizeLocationName(address.City);
AddressData.Province = address.Province;
AddressData.PostalCode = address.PostalCode;
AddressData.Country = address.Country;
AddressData.CountryCode = address.countryCode;
StateHasChanged();
prevenChange = false;
onChange();
}
public class AddressDTO
{
public string Address { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string countryCode { get; set; }
}
}
Última actualización