Tip: Country Selector for Web Apps

Published May 20, 2020 by
Javier Menendez

All of us are used to dealing with that web form where we select a country from a long, long list of more than 200 hundred countries. It would certainly be more useful, less stressful and a better usability practice to preselect the country name from the IP of the client visitor. Continue reading to learn how you can put a bit of intelligence into your web forms using a WebPopupMenu subclass.

In order to get the Country ISO code from the IP address we will need to use any of the many web services ables to bring us that data; for example FreeGeoIP.

As always, start by launching Xojo. Select the Web project template and drag and drop a WebPopupMenu control from the Library into the Project Navigator. This action will bring us a new subclass item we can model as we need.

Select the (probably named) “CustomWebPopupMenu” in the Project Browser and change its name from the Inspector Panel to something more in accordance with is function, maybe “CountrySelectorPopup“.

Next add a new Constant to our brand new subclass and name it, for example, “kCountries“. Don’t forget to select “String” as its Type and “Private” for its Scope.

This one will be the constant including all the countries’ names together with their respective ISO country codes; but let’s assume you have typed them using the following format (you’ll find that constant set in the downloaded project):

countryName#ISOcode_countryName#ISOcode…

That is, I’m using the “#” character as the separator character between the country name and its ISO country code (I’m pretty sure that that character isn’t used by any country name); while using the “_” character as the separator between the countries themselves.

Next, let’s add the “Open” event to the subclass, so we can run the initialization code in order to select the client’s country when the webpage loads and the control is shown.

This is the code that will be executed:

Var countries() As String = kCountries.ToArray("_")
Var index As Integer
Var found As Boolean
Var country As String
Var request As New URLConnection
country = request.SendSync("GET","https://freegeoip.app/json/"+Session.RemoteAddress)
country = country.DefineEncoding(encodings.UTF8)
Try
Var jReply As xojo.core.dictionary = xojo.data.ParseJSON(country.totext)
country = jReply.Value("country_code")
Catch e As JSONException
System.DebugLog(e.Message)
End Try
For Each s As String In countries
Me.AddRow s.NthField("#",1)
If s.NthField("#",2) = country Then
Me.listindex = index
found = True
End If
index = index + 1
Next
If Not found Then Me.listindex = 0
RaiseEvent open

Last, let’s add a new “Open” event definition, just because the consumer of the subclass may want to do its own initialization there.

And that’s how your users can avoid navigating a long list of items. As you can see, nothing really magical here … just a better experience for your users.