netcarver

Released: Street Address Fieldtype + Inputfield

Recommended Posts

Hello All,

I've been working on a new Fieldtype + Inputfield combination that handles street addresses. I've been using it now for about 3 months on my latest administration system for a charity and, so far, it seems to be working really well for them.

It's based on the meta-data from Google's LibAddressInput project and uses the data feeds from that to build a cache of address formats used by various countries. My initial testing was aided by @Macrura and @adrian - and they were later joined by @mel47 and @BFD Calendar - so a big thank-you to them all.

You can access the repository on GitHub and the Module Repository.

Here's a few images from the project. First up: config screen. Here's an early version...

screenshot-streetaddress-config.thumb.png.e3aac7901aad02337bea854319184088.png

...and a more recent update...

s002-new-control.png.c6ff1a13f49374525ef5194d15e44549.png

Here's a UK-based address. The module can integrate with my tag parser, if installed.

screenshot-streetaddress-in-use.png

Note that the output is formatted according to the output meta-data from the feed - which should match the preferred postal preferences of the destination country. Which subfields are required, and their regex expressions (if any) are also pulled from the feed and used as validation rules on the input side.

Here's an address in the Netherlands - inputfield layout is currently adjusted on save - if you've configured it to adjust based on the destination country. Hopefully this will eventually be ajax driven.

screenshot-streetaddress-netherlands.thumb.png.d06b1ac520fa780863c6eddb4bc82df7.png

Use of the address preview is configurable and the HTML output can include micro-format data. Address sub-fields can also be used in selectors...

s003-output.png.d49d6726134bb6990f9a6b338c57cd15.png

Back with inputs, if you prefer a table-based input - you can have it...

s001-table-layout.png.eca12ae2d11eb39a91453898a0e48591.png

Format hints (unfortunately, I've found that many users need these)...

screeny-0001.png.4f008e16f9bee5d1a57aa57d455829f8.pngscreeny-0003.png.e2f00a826d00caab48268e55af8ba798.png  screeny-0002.png.1aafba66ef04a3b11ba5f4c1756b85fa.png

Let me know if you find any issues or if you have any feature requests. So far, I have this from the previous testers...

  • Allow multi-lingual address input for countries that support a multi-lingual postal system (like Canada.)
  • Like 13

Share this post


Link to post
Share on other sites

This module has just been made public under a MIT license. The opening post has been updated to reflect its release.

  • Like 5

Share this post


Link to post
Share on other sites

@arjen Thank you, I spent some time tweaking the inter-field delete. I am aiming for something that seems nearly as free-form as a textarea, yet is more guided.

How's it working out for addresses in the Netherlands? Is the layout as you'd expect?

Share this post


Link to post
Share on other sites

The lay-out works fine, but unfortunately no hints on the wrongly spelled address or postal codes. Is this supposed to work in Dutch? Also, when I type in a city and thereafter empty the field I am getting an js error:

864915337_ScreenShot2018-09-10at06_43_52.png.210780b3f31adce9e88eec224a2558e1.png

Share this post


Link to post
Share on other sites

@arjen

Thanks for the report - I'll look at fixing your JS report tonight.

2 hours ago, arjen said:

...unfortunately no hints on the wrongly spelled address or postal codes. Is this supposed to work in Dutch?

Regarding spelling, no. I do not have any spellcheck control set on the fields, so whatever spell-checking your browser normally does should be applied to those fields. Also, there is no ajax postal code -> city lookup going on, so if you are expecting that, you'll be disappointed.

However, postal codes should be checked as long as the dutch meta-data from google includes a regular expression for that field.

Again, I'll check when I'm free tonight.

Share this post


Link to post
Share on other sites

Thanks, I wasn't looking at spelling per se, but more like the ones in your example. For instance the "eastVILLe street" example. 

2 hours ago, netcarver said:

dutch meta-data from google

I've looked (the LibAddressInput repo and Google) this morning, but can't seem to find where I can check this. Any clue?

Share this post


Link to post
Share on other sites
1 hour ago, arjen said:

Thanks, I wasn't looking at spelling per se, but more like the ones in your example. For instance the "eastVILLe street" example.

Ah, yes, that should work. Will take a look this evening. Thanks for the clarification.

Share this post


Link to post
Share on other sites

@arjen

I've uploaded version 1.0.1 that should fix the JS error you reported. 

Regarding the Postal Code, the cached Dutch address metadata (look in the formats.php file for the "NL" entry) does have a regex for the post code - so this should be checked and an error shown for non-matching input. Once you've installed version 1.0.1, could you please test it again.

Regarding the corrections of capitalisation, those should be shown when you click on the "?" icon. Were you clicking or just hovering over the "?" before?

Share this post


Link to post
Share on other sites

Thanks! I have a rather long commute this evening, so if my phone carrier won't fail me, lot's of time to update and test it.

Share this post


Link to post
Share on other sites

Hi, Steve. Thx for the module. Is there a way to prevent adding the country code to the zip? eg. from "SI- 2000 Maribor" to "2000 Maribor"?

Here are some examples of correct addressing in Slovenia:

Maja Čebelica
Vrtna ulica 1
5000 Nova Gorica

Gospa
Milena Galeb
Morska cesta 11 a
6000 Koper

Stanovanje 14/II
Gospa
Nada Skok
Cvetlična ulica 8
2270 Ormož

Prodajalna AVTO
p. p. 1635
1001 Ljubljana

Pošta Slovenije d.o.o
2500 Maribor

Firma AG
Hauptstrasse 28
CH–5400 Baden
Schweiz

As seen from examples, street address is not mandatory.

Stupid question: what's the benefit of using this field instead of plain textarea?

Share this post


Link to post
Share on other sites

Hello @matjazp

The metadata for postal formatting of the addresses comes from Google's libaddressinput project. I note that the "SI-" prefix to the Slovenian postal code is actually coming from Google's postal address format metadata for Slovenia. Please reference line 1324 of the formats.php file and you'll see that "...%nSI- %Z..." appears in the format string. This forces the literal "SI- " to appear at the start of a new line, just before the zip/postal code.

Essentially this is an upstream library issue and you can open an issue against libaddressinput to attempt to get it resolved, though I note there is an old, closed, issue regarding the prefix to the Slovenian postal code.

However, I anticipated situations like this and there is a mechanism built in to the module code you can use to override the upstream format.

If you edit your local copy of formats_overrides.php and add the following to the returned array, you will be able to customise the format as you require until Google fixes (or doesn't) the upstream repo...

    'SI' => [
        'fmt'=>'%N%n%O%n%A%n%Z %C', // Prevent "SI - " from prefixing the postal code.
    ],

The metadata for Slovenia marks non of the fields as mandatory - so you should find this input works for you as is.

In fact, from version 1.0.2, you need to rename the example.formats_overrides.php file to formats_overrides.php as I am currently working on making the installed overrides file persist across upgrades (something it doesn't do quite correctly yet.)

 

Also; just in case you haven't worked out how to suppress the country in the input and output of domestic addresses, you should be able to do so by setting the config options for the street address field as follows...

  • Allowable countries: select just Slovenia.
  • Show destination country field?: Set to "Never".

 

Regarding benefits over a free-form textarea, here are some I can think of...

  • Address subfields can be used in PW selectors: $addresses = $pages->find('address.locality=Paris');
  • Automatic compliance with layout requirements (including capitalisation and required fields) of the destination countries postal format (where correct in the meta data). Slovenia seems quite relaxed in which fields are required and which should be capitalised. Many European countries require certain fields, and require them to be output capitalised when used as postal addresses.
  • Aids data cleaning on input over a free-form textarea (lots of my users type with caps-lock on, for example!)
  • Automatic zipcode/regex application to subfields.
  • Direct access to subfields, if you want to use them in your own template output other than in a full address label.
  • Assorted format() functions for single/multiline, plain/html output.
  • Automatic inclusion of address microformat metadata to the fields.

 

I did read various UI/UX forums about this issue before I started, many of them came to the conclusion that a free-form input is best from the UX point of view - and I can understand that point of view. This module is my attempt to meld as close to a free-form input experience as I can, with structured data that accepts just about any country's postal code format. 

I hope that helps.
Best wishes,
Steve

  • Like 6

Share this post


Link to post
Share on other sites

I've just pushed version 1.0.4 that should fix the persistence of your custom override files between updates. Adrian has also pointed out that this could be brought into the module config settings - something that I will consider for a later release.

Please let me know if your custom formats_overrides.php files are not being successfully persisted between updates.

Thank you!

Share this post


Link to post
Share on other sites

Upgraded from1.0.3 to 1.0.4, the content of the formats_overrides.php is preserved.

Pages: Successfully copied C:/inetpub/wwwroot/site/modules/.FieldtypeStreetAddress/formats_overrides.php to C:\inetpub\wwwroot\site\modules\FieldtypeStreetAddress/formats_overrides.php

 

  • Like 1

Share this post


Link to post
Share on other sites

@matjazp

Just took a second look at your examples. I see that the last one is international - and that I need to do some more work with regard to using the localised language name for the destination country. Will add this to the to-do list.  

Share this post


Link to post
Share on other sites
On 9/10/2018 at 10:03 PM, netcarver said:

I've uploaded version 1.0.1 that should fix the JS error you reported. 

 

👍 Thanks!

23 hours ago, netcarver said:

I did read various UI/UX forums about this issue before I started, many of them came to the conclusion that a free-form input is best from the UX point of view - and I can understand that point of view.

This is a difficult one. I've have created so many times different fields and used textareas. Each choice will bite you in the end. It really depends. When you have a several addresses for a company you want to output on a website I would not use this field. When you are building a directory/database of companies or other users I would definitely use this, because you want the data to be structured.

  • Like 1

Share this post


Link to post
Share on other sites

I am curious about the word used for the country in @matjazp's last example: "Schweiz" which, I assume, is Switzerland (CH). However, this is not what I would expect Switzerland to be called in Slovenia.

In the past I've used Umpirsky's country code localisations. In them, the Slovenian word for Switzerland seems to be "Švica" and not what was used in that example. So, If the example is correct - which it probably is - then it means my assumption that I should use the language of the originating country to spell the destination country in the address is wrong, and the inputfield needs to allow for this.

Would anybody care to comment on this?

 

@arjen

Thank you for the feedback, glad the JS problem is resolved. Curious about your meaning here...

37 minutes ago, arjen said:

When you have a several addresses for a company you want to output on a website I would not use this field.

...could you expand on this a little?

Best regards,
Steve 

Share this post


Link to post
Share on other sites

Of course. For instance when I have a website for a company called "Hello Inc" and this company is located in three addresses I would create a Multiplier field for the textareas. This field is only used for outputting the three addresses on the contact page. This Street Address field would feel a bit too much for the editors to maintain. Also an error is quickly spotted since there are only three addresses.

On the other hand I'm prototyping a database which may hold 1000's of companies. I would definitely use this field because I want it to be accessible and queryable. Therefore the data structure is more essential.

  • Like 1

Share this post


Link to post
Share on other sites

@arjen

Thank you for explaining! 

For what it's worth I use the StreetAddress field in a repeater matrix for a contact DB in the charity I originally wrote this for, and it works very well.

Also, if you want to output an address in different ways - including the Postal format of the destination country - then StreetAddress does allow that too. Now, this may not be applicable to your situation, but in the case of the charity, they have to send letters so the postal format is needed (multiline, some fields have to be capitalised etc), but the same address data can appear in their letterhead and footer formatted in a totally different way (single line, using title-case rather than uppercase town names etc.) This is really easy to do using StreetAddress but would be difficult to do using a single textarea for an address. Formatting of the charity address can be similarly tweaked for outgoing email.

  • Thanks 1

Share this post


Link to post
Share on other sites

Very nice and much appreciated new Fieldtype. Is there a simple way to convert or import existing textfields to Street Address?

Share this post


Link to post
Share on other sites

Hi @thlinna

Thank you for your kind words. Regarding importing data: is your current data...

    A) in a single textarea field?
    B) in a set of text fields?

If the answer is A), then is each address in exactly the same format? If so, then you could write a custom import script.

If the answer is B). then you could write a custom import script - and it would probably be easier than the first case.

There is nothing built in to the field to do this for you.

Share this post


Link to post
Share on other sites

Thanks @netcarver for quick response. The address is stored in three different fields (street, zip, postal code). 

I am not that experienced in scripting or coding in PHP. Though I am able to execute code, fix bugs, change logic or modify functionality with try and error with my history in C++, C# and Java.

Do you know if there is a good source for such scripting to start with? I believe I would not be the only one considering modifying my existing implementation to utilise this very much appreciated improvement in PW.

Share this post


Link to post
Share on other sites
12 minutes ago, thlinna said:

Do you know if there is a good source for such scripting to start with? I believe I would not be the only one considering modifying my existing implementation to utilise this very much appreciated improvement in PW.

Should be as simple as this:

foreach($page->children as $p) {
    $p->of(false);
    $p->street_address->recipient = $p->recipient;
    $p->street_address->organization = $p->organization;
    $p->street_address->street_address = $p->street_address;
    $p->street_address->street_address_2 = $p->street_address_2;    
    $p->street_address->street_address_3 = $p->street_address_3;    
    $p->street_address->locality = $p->locality;
    $p->street_address->dependent_locality = $p->dependent_locality;
    $p->street_address->admin_area = $p->admin_area; //state, province, etc
    $p->street_address->postal_code = $p->postal_code;
    $p->street_address->country_iso = $p->country_iso;    
    $p->save('street_address');
}

I would go to the parent page of all your people or businesses or whatever and run that in Tracy's Console panel and you'll be done!

Obviously you want to keep the name of the subfield on the left as I have them, but you may need to change the names of the fields on the right side of the "="

Also, in my example, the name of the field in my system is "street_address" - all occurrences of that would need to be changed to match the name of the field you create using this fieldtype.

Does that make sense?

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now