Autocompletado de direcciones con Google Maps (Blazor)
Ejemplo muestra cómo implementar un formulario de dirección en una aplicación Blazor
Este ejemplo muestra cómo implementar un formulario de dirección en una aplicación Blazor utilizando la API de Google Maps para autocompletado. Se utiliza el componente RadzenTextBox
y el modelo de datos Dinaup.AddressModel
para capturar los datos introducidos por el usuario.
1
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
Este fragmento usa componentes de Radzen y enlaza automáticamente con Dinaup.AddressModel
.
@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