Sample code for address lookup
This page provides sample code to help you set up Postcoder address lookup and autocomplete.
Copy any example below and then insert your own API key to make it work. Sign up to get an API key.
Address lookup using JavaScript
This example uses the address endpoint to provide UK postcode lookup, Irish Eircode lookup and global address lookup in a single form. It can be customised using the config settings at the end of the HTML.
.Ireland and Eircode: Enable access on your API key using the Features page or by contacting us.
class PostcoderAddress{
constructor(config) {
this.config = config
this.init()
}
init = () => {
this.endpoint = 'https://ws.postcoder.com/pcw/' + this.config.apikey + '/address/'
this.addresses = {}
this.searchbutton = document.querySelector(this.config.searchbutton)
this.searchterminput = document.querySelector(this.config.searchterm)
//hide the no result message
this.noresultmessage = document.querySelector(this.config.noresultmessage)
this.noresultmessage.style.display = 'none'
// create an empty select and place it hidden in the page
this.select = document.createElement('select')
this.select.style.display = 'none'
document.querySelector(this.config.addressselectioncontainer).appendChild(this.select)
// create and append the top 'select an address' option.
let option = document.createElement('option')
option.text = 'Select an address'
this.select.appendChild(option)
// add select change event listener to the dropdown
this.select.addEventListener('change', this.handleSelectChange )
// add click event listener to the search button, to call the search function
this.searchbutton.addEventListener('click', this.search)
// add 'enter' event listener to the search input, to call the search function
this.searchterminput.addEventListener('keyup', event =>{
if (event.keyCode === 13) {
event.preventDefault()
this.search()
}
})
// determine the number of addresslines required
this.addresslines = 0
for (let i = 1; i <= 4; i++) {
if( this.config['addressline'+i] !== ''){
this.addresslines ++
}
}
}
handleSelectChange = event => {
// check to see if this selection was to load the next page of results
if( this.select.value.charAt(0) === 'p'){
// search the next page of results
let page = this.select.value.substring(1)
this.search(event, page)
}else{
this.selectAddress( this.select.value )
}
}
search = (event, page = 0) => {
let searchterm = encodeURIComponent(this.searchterminput.value)
//hide the no result message
this.noresultmessage.style.display = 'none'
// hide the select
this.select.style.display = 'none'
//determine the country
if(typeof this.config.countrycode !== 'undefined' && this.config.countrycode !== ''){
// defined in config
var country = this.config.countrycode
}else{
// get from dropdown
var country = document.querySelector(this.config.country).value
}
// if page 0, remove any previous options
if(page === 0){
while (this.select.options.length > 1) {
this.select.remove(1)
}
}else{
// remove the bottom 'next page' option
this.select.remove(this.select.options.length - 1)
}
// fetch the json formatted result from Postcoder and pass it to processResult
fetch(this.endpoint + country + '/' + searchterm + '?lines='+this.addresslines + '&exclude=organisation,country&page=' + page)
.then( response => {
if (!response.ok) {
throw response
}
return response.json()
})
.then( json => {
this.processResult(json)
})
.catch( err => {
if(typeof err.text === 'function'){
err.text().then( errorMessage => {
console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
})
}else{
console.log(err)
}
})
}
processResult = addresses =>{
this.addresses = addresses
//if zero results, ask for manual address entry
if( addresses.length === 0 ){
//show the no result message
this.noresultmessage.style.display = 'block'
}
// if one result, populate the form
else if(addresses.length === 1){
this.selectAddress(0)
}
// multiple addresses, show drop down to select from
else{
// create and append the address options, using the summaryline of the returned addresses
for (let i = 0; i < addresses.length; i++) {
let option = document.createElement('option')
option.value = i
option.text = addresses[i].summaryline
this.select.appendChild(option)
}
// if there are morevalues, add paging
if(this.addresses[this.addresses.length - 1]['morevalues'] === 'true'){
// add a 'load next page' option
let option = document.createElement('option')
option.value = 'p' + this.addresses[this.addresses.length - 1]['nextpage']
// last address contains total number of results, show the user how many are remaining
let remainingresults = this.addresses[this.addresses.length - 1]['totalresults'] - this.select.options.length + 1
option.text = 'Load more results, ' + remainingresults + ' of ' + this.addresses[this.addresses.length - 1]['totalresults'] + ' remaining'
this.select.appendChild(option)
}
// ensure the select is visible
this.select.style.display = 'block'
}
}
selectAddress = i =>{
// get the selected address
let address = this.addresses[i]
let fields = ['organisation','addressline1','addressline2','addressline3','addressline4','posttown','county','postcode']
//populate the address form
for (let i = 0; i < fields.length; i++) {
let field_selector = this.config[fields[i]]
if(typeof field_selector !== 'undefined' && field_selector !== ''){
document.querySelector(field_selector).value = (typeof address[fields[i]] !== 'undefined') ? address[fields[i]] : ''
}
}
}
}
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="postcoder.css" >
<script src="postcoder_address.js"></script>
</head>
<body>
<form>
<label for="txt_country">Country</label>
<select id="txt_country">
<option value="AU">Australia</option>
<option value="AT">Austria</option>
<option value="BE">Belgium</option>
<option value="BZ">Belize</option>
<option value="BJ">Benin</option>
<option value="BM">Bermuda</option>
<option value="BT">Bhutan</option>
<option value="BO">Bolivia (Plurinational State of)</option>
<option value="BQ">Bonaire, Sint Eustatius and Saba</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="BW">Botswana</option>
<option value="BV">Bouvet Island</option>
<option value="BR">Brazil</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="BN">Brunei Darussalam</option>
<option value="BG">Bulgaria</option>
<option value="BF">Burkina Faso</option>
<option value="BI">Burundi</option>
<option value="CV">Cabo Verde</option>
<option value="KH">Cambodia</option>
<option value="CM">Cameroon</option>
<option value="CA">Canada</option>
<option value="KY">Cayman Islands</option>
<option value="CF">Central African Republic</option>
<option value="TD">Chad</option>
<option value="CL">Chile</option>
<option value="CN">China</option>
<option value="CX">Christmas Island</option>
<option value="CC">Cocos (Keeling) Islands</option>
<option value="CO">Colombia</option>
<option value="KM">Comoros</option>
<option value="CD">Congo (the Democratic Republic of the)</option>
<option value="CG">Congo</option>
<option value="CK">Cook Islands</option>
<option value="CR">Costa Rica</option>
<option value="HR">Croatia</option>
<option value="CU">Cuba</option>
<option value="CW">Curaçao</option>
<option value="CY">Cyprus</option>
<option value="CZ">Czechia</option>
<option value="CI">Côte d'Ivoire</option>
<option value="DK">Denmark</option>
<option value="DJ">Djibouti</option>
<option value="DM">Dominica</option>
<option value="DO">Dominican Republic</option>
<option value="EC">Ecuador</option>
<option value="EG">Egypt</option>
<option value="SV">El Salvador</option>
<option value="GQ">Equatorial Guinea</option>
<option value="ER">Eritrea</option>
<option value="EE">Estonia</option>
<option value="SZ">Eswatini</option>
<option value="ET">Ethiopia</option>
<option value="FK">Falkland Islands [Malvinas]</option>
<option value="FO">Faroe Islands</option>
<option value="FJ">Fiji</option>
<option value="FI">Finland</option>
<option value="FR">France</option>
<option value="GF">French Guiana</option>
<option value="PF">French Polynesia</option>
<option value="TF">French Southern Territories</option>
<option value="GA">Gabon</option>
<option value="GM">Gambia</option>
<option value="GE">Georgia</option>
<option value="DE">Germany</option>
<option value="GH">Ghana</option>
<option value="GI">Gibraltar</option>
<option value="GR">Greece</option>
<option value="GL">Greenland</option>
<option value="GD">Grenada</option>
<option value="GP">Guadeloupe</option>
<option value="GU">Guam</option>
<option value="GT">Guatemala</option>
<option value="GG">Guernsey</option>
<option value="GN">Guinea</option>
<option value="GW">Guinea-Bissau</option>
<option value="GY">Guyana</option>
<option value="HT">Haiti</option>
<option value="HM">Heard Island and McDonald Islands</option>
<option value="VA">Holy See</option>
<option value="HN">Honduras</option>
<option value="HK">Hong Kong</option>
<option value="HU">Hungary</option>
<option value="IS">Iceland</option>
<option value="IN">India</option>
<option value="ID">Indonesia</option>
<option value="IR">Iran (Islamic Republic of)</option>
<option value="IQ">Iraq</option>
<option value="IE">Ireland</option>
<option value="IM">Isle of Man</option>
<option value="IL">Israel</option>
<option value="IT">Italy</option>
<option value="JM">Jamaica</option>
<option value="JP">Japan</option>
<option value="JE">Jersey</option>
<option value="JO">Jordan</option>
<option value="KZ">Kazakhstan</option>
<option value="KE">Kenya</option>
<option value="KI">Kiribati</option>
<option value="KP">Korea (the Democratic People's Republic of)</option>
<option value="KR">Korea (the Republic of)</option>
<option value="KW">Kuwait</option>
<option value="KG">Kyrgyzstan</option>
<option value="LA">Lao People's Democratic Republic</option>
<option value="LV">Latvia</option>
<option value="LB">Lebanon</option>
<option value="LS">Lesotho</option>
<option value="LR">Liberia</option>
<option value="LY">Libya</option>
<option value="LI">Liechtenstein</option>
<option value="LT">Lithuania</option>
<option value="LU">Luxembourg</option>
<option value="MO">Macao</option>
<option value="MG">Madagascar</option>
<option value="MW">Malawi</option>
<option value="MY">Malaysia</option>
<option value="MV">Maldives</option>
<option value="ML">Mali</option>
<option value="MT">Malta</option>
<option value="MH">Marshall Islands</option>
<option value="MQ">Martinique</option>
<option value="MR">Mauritania</option>
<option value="MU">Mauritius</option>
<option value="YT">Mayotte</option>
<option value="MX">Mexico</option>
<option value="FM">Micronesia (Federated States of)</option>
<option value="MD">Moldova (the Republic of)</option>
<option value="MC">Monaco</option>
<option value="MN">Mongolia</option>
<option value="ME">Montenegro</option>
<option value="MS">Montserrat</option>
<option value="MA">Morocco</option>
<option value="MZ">Mozambique</option>
<option value="MM">Myanmar</option>
<option value="NA">Namibia</option>
<option value="NR">Nauru</option>
<option value="NP">Nepal</option>
<option value="NL">Netherlands</option>
<option value="NC">New Caledonia</option>
<option value="NZ">New Zealand</option>
<option value="NI">Nicaragua</option>
<option value="NE">Niger</option>
<option value="NG">Nigeria</option>
<option value="NU">Niue</option>
<option value="NF">Norfolk Island</option>
<option value="MP">Northern Mariana Islands</option>
<option value="NO">Norway</option>
<option value="OM">Oman</option>
<option value="PK">Pakistan</option>
<option value="PW">Palau</option>
<option value="PS">Palestine, State of</option>
<option value="PA">Panama</option>
<option value="PG">Papua New Guinea</option>
<option value="PY">Paraguay</option>
<option value="PE">Peru</option>
<option value="PH">Philippines</option>
<option value="PN">Pitcairn</option>
<option value="PL">Poland</option>
<option value="PT">Portugal</option>
<option value="PR">Puerto Rico</option>
<option value="QA">Qatar</option>
<option value="MK">Republic of North Macedonia</option>
<option value="RO">Romania</option>
<option value="RU">Russian Federation</option>
<option value="RW">Rwanda</option>
<option value="RE">Réunion</option>
<option value="BL">Saint Barthélemy</option>
<option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
<option value="KN">Saint Kitts and Nevis</option>
<option value="LC">Saint Lucia</option>
<option value="MF">Saint Martin (French part)</option>
<option value="PM">Saint Pierre and Miquelon</option>
<option value="VC">Saint Vincent and the Grenadines</option>
<option value="WS">Samoa</option>
<option value="SM">San Marino</option>
<option value="ST">Sao Tome and Principe</option>
<option value="SA">Saudi Arabia</option>
<option value="SN">Senegal</option>
<option value="RS">Serbia</option>
<option value="SC">Seychelles</option>
<option value="SL">Sierra Leone</option>
<option value="SG">Singapore</option>
<option value="SX">Sint Maarten (Dutch part)</option>
<option value="SK">Slovakia</option>
<option value="SI">Slovenia</option>
<option value="SB">Solomon Islands</option>
<option value="SO">Somalia</option>
<option value="ZA">South Africa</option>
<option value="GS">South Georgia and the South Sandwich Islands</option>
<option value="SS">South Sudan</option>
<option value="ES">Spain</option>
<option value="LK">Sri Lanka</option>
<option value="SD">Sudan</option>
<option value="SR">Suriname</option>
<option value="SJ">Svalbard and Jan Mayen</option>
<option value="SE">Sweden</option>
<option value="CH">Switzerland</option>
<option value="SY">Syrian Arab Republic</option>
<option value="TW">Taiwan (Province of China)</option>
<option value="TJ">Tajikistan</option>
<option value="TZ">Tanzania, United Republic of</option>
<option value="TH">Thailand</option>
<option value="TL">Timor-Leste</option>
<option value="TG">Togo</option>
<option value="TK">Tokelau</option>
<option value="TO">Tonga</option>
<option value="TT">Trinidad and Tobago</option>
<option value="TN">Tunisia</option>
<option value="TR">Turkey</option>
<option value="TM">Turkmenistan</option>
<option value="TC">Turks and Caicos Islands</option>
<option value="TV">Tuvalu</option>
<option value="UG">Uganda</option>
<option value="UA">Ukraine</option>
<option value="AE">United Arab Emirates</option>
<option value="GB" selected>United Kingdom</option>
<option value="UM">United States Minor Outlying Islands</option>
<option value="US">United States of America</option>
<option value="UY">Uruguay</option>
<option value="UZ">Uzbekistan</option>
<option value="VU">Vanuatu</option>
<option value="VE">Venezuela (Bolivarian Republic of)</option>
<option value="VN">Viet Nam</option>
<option value="VG">Virgin Islands (British)</option>
<option value="VI">Virgin Islands (U.S.)</option>
<option value="WF">Wallis and Futuna</option>
<option value="EH">Western Sahara</option>
<option value="YE">Yemen</option>
<option value="ZM">Zambia</option>
<option value="ZW">Zimbabwe</option>
</select>
<label for="txt_search">Search for an address or postcode</label>
<button type="button" id="btn_search">
Search
</button>
<div class="search_wrap">
<input type="text" id="txt_search">
</div>
<div id="address_selection_container"></div>
<div id="no_result_message">
Address not found, please enter manually.
</div>
<label for="txt_organsation">Organisation</label>
<input type="text" id="txt_organsation">
<label for="txt_addressline1">Address</label>
<input type="text" id="txt_addressline1">
<input type="text" id="txt_addressline2">
<input type="text" id="txt_addressline3">
<label for="txt_posttown">Town</label>
<input type="text" id="txt_posttown">
<label for="txt_postcode">Postcode</label>
<input type="text" id="txt_postcode">
</form>
<script>
new PostcoderAddress({
apikey: 'PCW45-12345-12345-1234X',
searchterm: '#txt_search', // query selector of the searchterm input field
addressselectioncontainer: '#address_selection_container', // container for the address selection drop down
noresultmessage: '#no_result_message',
country: '#txt_country', // Country select list; leave blank if not using a country select list
countrycode: '', // Hard code if not using a country select list; leave blank otherwise
searchbutton: '#btn_search',
organisation: '#txt_organsation', // Leave blank if form does not have a separate organisation field
addressline1: '#txt_addressline1',
addressline2: '#txt_addressline2', // Leave blank if form does not have an addressline2
addressline3: '#txt_addressline3', // Leave blank if form does not have an addressline3
//addressline4: '', // Leave blank if form does not have an addressline4
county: '', // Leave blank if form does not have a county
posttown: '#txt_posttown',
postcode: '#txt_postcode'
})
</script>
</body>
</html>
input, select {
display: block;
box-sizing: border-box;
width: 100%;
padding: 10px;
height: 40px;
margin-bottom: 0.5em;
border-width: 1px;
border-style: solid;
border-color: lightgray;
}
.search_wrap {
overflow: hidden;
}
.search_wrap div {
font-size: 0.75em;
}
button {
padding: 8px;
margin-left: 0.5em;
float: right;
font-family: sans-serif;
}
label {
display: block;
margin-top: 1.25em;
margin-bottom: 0.25em;
}
select {
position: relative;
z-index: 1;
padding-right: 40px;
}
.isvalid:after {
content: '\2713';
color: green;
}
.notvalid:after {
content: '\2717';
color: red;
}
#successindicator {
float: right;
margin-left: 0.5em;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
height: 40px;
}
#json_result_container {
margin: 5em 0 0;
background-color: #eee;
color: #333;
/* border: solid lightgrey 1px; */
padding: 1em;
overflow: auto;
}
#autocomplete_wrap{
position: relative;
}
#suggestion_list{
position: absolute;
background-color: #fff;
outline: -webkit-focus-ring-color auto 1px;
list-style-type: none;
margin: 0;
padding: 0;
max-height: 400px;
overflow-y: auto;
}
#suggestion_list li{
cursor: pointer;
padding: 10px 5px;
}
#suggestion_list li.header{
border-bottom: 2px solid #ddd;
}
#suggestion_list li:hover, #suggestion_list li.selected{
background-color: #ddd;
}
#suggestion_list li span.location{
font-size: 0.75em;
color: #666;
}
.arrow {
border: solid black;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 3px;
}
.left {
margin-left: 3px;
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.address{
height: 140px;
margin: 8px;
}
.map {
height: 300px;
width: 100%;
}
body {
font-family: sans-serif;
padding: 0;
margin: 0;
}
Address autocomplete using JavaScript
This example uses the autocomplete/find endpoint to provide real-time suggestions as a user types in a UK or Irish address, and the autocomplete/retrieve endpoint to lookup the full version of a selected address.
Ireland and Eircode: Enable access on your API key using the Features page or by contacting us.
class PostcoderAutocomplete{
constructor(config) {
this.config = config
this.init()
}
init = () => {
this.suggestionendpoint = 'https://ws.postcoder.com/pcw/autocomplete/find?apikey=' + this.config.apikey
this.retrieveendpoint = 'https://ws.postcoder.com/pcw/autocomplete/retrieve?apikey=' + this.config.apikey
this.cache = []
this.suggestionhierarchy = []
this.suggestions = []
this.searchterm = ''
this.selectedoptiontext = ''
this.pathfilter = ''
this.selectedIndex = -1
this.no_results_message = 'No addresses found'
this.inputdelay = 300
this.suggestionlist = document.querySelector(this.config.suggestions)
this.input = document.querySelector(this.config.searchterm)
this.input.setAttribute('type', 'search')
this.input.setAttribute('autocomplete', 'off')
this.input.setAttribute('autocapitalize', 'off')
this.input.setAttribute('autocorrect', 'off')
this.input.setAttribute('spellcheck', 'false')
this.input.addEventListener('input', this.handleInput)
this.input.addEventListener('focus', this.handleFocus)
this.input.addEventListener('keydown', this.handleKeyDown)
this.suggestionlist.addEventListener('click', this.handleSuggestionClick)
// add click event listener to the document, to hide the suggestions when clicked away
document.body.addEventListener('click', this.handleDocumentClick)
// determine the number of addresslines required
this.addresslines = 0
for (let i = 1; i <= 4; i++) {
if( this.config['addressline'+i] !== ''){
this.addresslines ++
}
}
}
getSuggestions = event =>{
this.searchterm = encodeURIComponent(this.input.value.trim())
// require a minimum of three characters
if(this.searchterm.length < 3){
this.hideSuggestions()
return
}
let url = this.suggestionendpoint + '&country=' + this.getCountry() + '&query=' + this.searchterm
if(this.pathfilter){
url += '&pathfilter=' + this.pathfilter
}else{
this.selectedoptiontext = this.searchterm
}
let index = this.cache.findIndex(c => c.url === url)
if( index >= 0){
// use cached data
this.suggestions = this.cache[index].suggestions
this.addSuggestionHierarchy(index)
this.showSuggestions()
}else{
fetch(url)
.then( response => {
if (!response.ok) {
throw response
}
return response.json()
})
.then( json => {
this.suggestions = json
this.addCache(url)
this.addSuggestionHierarchy(this.cache.length - 1)
this.showSuggestions()
})
.catch( err => {
if(typeof err.text === 'function'){
err.text().then( errorMessage => {
console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
})
}else{
console.log(err)
}
})
}
}
addCache = url => {
let obj = {}
obj.url = url
obj.suggestions = this.suggestions
obj.label = this.selectedoptiontext
this.cache.push(obj)
}
newSuggestionsReset = () => {
// remove previous options
this.hideSuggestions()
this.pathfilter = ''
this.suggestionlist.scrollTop = 0
this.selectedIndex = -1
}
suggestionsHierarchyReset = () => {
//reset suggestionHierarchy
this.suggestionhierarchy = []
}
addSuggestionHierarchy = index => {
// store the cache entry index for each suggestion level selected
this.suggestionhierarchy.push(index)
}
handleSuggestionClick = event => {
event.stopPropagation()
let target = event.target
// if click was not directly on the <li>, but a child, find the <li> in parent
while(target.tagName.toLowerCase() !== 'li' ){
target = target.parentNode
}
this.selectSuggestion(target)
}
selectSuggestion = target => {
this.selectedoptiontext = target.innerHTML
if(target.getAttribute('data-type') == 'CACHE'){
// back to previous results using cached suggestions
this.suggestions = this.cache[target.getAttribute('data-id')].suggestions
this.suggestionhierarchy.pop()
this.showSuggestions()
}else if(target.getAttribute('data-type') == 'ADD'){
// if the type is an address, retrieve it using the id
this.retrieve(target.getAttribute('data-id'))
}else{
// get more suggestions, using the id
this.pathfilter = target.getAttribute('data-id')
this.getSuggestions()
}
}
retrieve = id => {
var url = this.retrieveendpoint + '&country=' + this.getCountry() + '&query=' + this.searchterm + '&id=' + id + '&lines='+this.addresslines + '&exclude=organisation,country'
// fetch the json formatted result from Postcoder and pass it to processResult
fetch(url)
.then( response => {
if (!response.ok) {
throw response
}
return response.json()
})
.then( addresses => {
// always one result, use the first array item
this.cache[url] = addresses[0]
this.processResult(addresses[0])
})
.catch( err => {
if(typeof err.text === 'function'){
err.text().then( errorMessage => {
console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
})
}else{
console.log(err)
}
})
}
showSuggestions = () => {
this.newSuggestionsReset()
if( this.suggestions.length === 0 ){
// show no results message in ul
let option = document.createElement('li')
option.innerHTML = this.no_results_message
this.suggestionlist.appendChild(option)
}
else{
if(this.suggestionhierarchy.length > 1){
// a suggestion was selected so show previous option
let cacheid = this.suggestionhierarchy[this.suggestionhierarchy.length - 2] // .length -1 is current suggestions
let option = document.createElement('li')
option.classList.add('header')
option.innerHTML = '<i class="arrow left"></i> ' + unescape(this.cache[cacheid].label)
option.setAttribute('data-id', cacheid)
option.setAttribute('data-type', 'CACHE')
this.suggestionlist.appendChild(option)
}
for (let i = 0; i < this.suggestions.length; i++) {
let option = document.createElement('li')
let suggestiontext = this.suggestions[i].summaryline + ' ' + '<span class="location">' + this.suggestions[i].locationsummary + '</span>'
if(this.suggestions[i].count > 1){
let count = this.suggestions[i].count > 100 ? '100+' : this.suggestions[i].count
suggestiontext += ' <span class="count">(' + count + ' addresses)</span>'
}
option.innerHTML = suggestiontext
// add the id and type attibutes to the option
option.setAttribute('data-id', this.suggestions[i].id)
option.setAttribute('data-type', this.suggestions[i].type)
this.suggestionlist.appendChild(option)
}
}
}
getCountry = () => {
return (typeof this.config.countrycode !== 'undefined' && this.config.countrycode !== '')
? this.config.countrycode
: document.querySelector(this.config.country).value
}
processResult = address => {
this.hideSuggestions()
let fields = ['organisation','addressline1','addressline2','addressline3','addressline4','posttown','county','postcode']
//populate the address form
for (let i = 0; i < fields.length; i++) {
let field_selector = this.config[fields[i]]
if(typeof field_selector !== 'undefined' && field_selector !== ''){
document.querySelector(field_selector).value = (typeof address[fields[i]] !== 'undefined') ? address[fields[i]] : ''
}
}
}
handleDocumentClick = event => {
if (this.suggestionlist.contains(event.target) || this.input.contains(event.target)) {
return
}
this.hideSuggestions()
}
hideSuggestions = () => {
// clear the ul list
this.suggestionlist.innerHTML = ''
}
handleKeyDown = event => {
const { key } = event
switch (key) {
case 'Up':
case 'Down':
case 'ArrowUp':
case 'ArrowDown': {
const selectedIndex =
key === 'ArrowUp' || key === 'Up'
? this.selectedIndex - 1
: this.selectedIndex + 1
event.preventDefault()
this.handleArrows(selectedIndex)
break
}
case 'Tab': {
this.handleTab(event)
break
}
case 'Enter': {
this.selectSuggestion( this.suggestionlist.querySelectorAll('li')[this.selectedIndex] )
break
}
case 'Esc':
case 'Escape': {
this.hideSuggestions()
this.setValue()
break
}
default:
return
}
}
handleArrows = selectedIndex => {
// Loop selectedIndex back to first or last result if out of bounds
let suggestionsCount = this.suggestions.length
if(this.suggestionhierarchy.length > 1){
// add previous suggestion
suggestionsCount++
}
if(this.suggestionlist.querySelectorAll('li').length > 0){
if(this.selectedIndex >= 0){
// clear the previously selected class
this.suggestionlist.querySelectorAll('li')[this.selectedIndex].classList.remove('selected')
}
this.selectedIndex = ((selectedIndex % suggestionsCount) + suggestionsCount) % suggestionsCount
// set the selected class
this.suggestionlist.querySelectorAll('li')[this.selectedIndex].classList.add('selected')
// scroll into view
this.suggestionlist.querySelectorAll('li')[this.selectedIndex].scrollIntoView(false)
}
}
handleTab = event => {
if(this.selectedIndex >= 0){
event.preventDefault()
this.selectSuggestion( this.suggestionlist.querySelectorAll('li')[this.selectedIndex] )
}else{
this.hideSuggestions()
}
}
handleInput = () => {
this.suggestionsHierarchyReset()
clearTimeout(this.debounce);
this.debounce = setTimeout(() => this.getSuggestions(), this.inputdelay)
}
handleFocus = () => {
if(this.suggestions.length > 0){
this.showSuggestions()
}else{
this.getSuggestions()
}
}
}
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="postcoder.css" >
<script src="postcoder_autocomplete.js"></script>
</head>
<body>
<form>
<label for="txt_country">Country</label>
<select id="txt_country">
<option value="IE">Ireland</option>
<option value="GB" selected>United Kingdom</option>
</select>
<div class="autocomplete_wrap">
<label for="txt_search">Search for an address or postcode</label>
<input id="txt_search">
<ul id="suggestion_list"></ul>
</div>
<label for="txt_organsation">Organisation</label>
<input type="text" id="txt_organsation">
<label for="txt_addressline1">Address</label>
<input type="text" id="txt_addressline1">
<input type="text" id="txt_addressline2">
<input type="text" id="txt_addressline3">
<label for="txt_posttown">Town</label>
<input type="text" id="txt_posttown">
<label for="txt_postcode">Postcode</label>
<input type="text" id="txt_postcode">
</form>
<script>
new PostcoderAutocomplete({
apikey: 'PCW45-12345-12345-1234X',
searchterm: '#txt_search', // query selector of the searchterm input field
suggestions: '#suggestion_list', // query selector for preview datalist
country: '#txt_country', // Country select list; leave blank if not using a country select list
countrycode: '', // Hard code if not using a country select list; leave blank otherwise
organisation: '#txt_organsation', // Leave blank if form does not have a separate organisation field
addressline1: '#txt_addressline1',
addressline2: '#txt_addressline2', // Leave blank if form does not have an addressline2
addressline3: '#txt_addressline3', // Leave blank if form does not have an addressline3
//addressline4: '', // Leave blank if form does not have an addressline4
county: '', // Leave blank if form does not have a county
posttown: '#txt_posttown',
postcode: '#txt_postcode'
})
</script>
</body>
</html>
input, select {
display: block;
box-sizing: border-box;
width: 100%;
padding: 10px;
height: 40px;
margin-bottom: 0.5em;
border-width: 1px;
border-style: solid;
border-color: lightgray;
}
.search_wrap {
overflow: hidden;
}
.search_wrap div {
font-size: 0.75em;
}
button {
padding: 8px;
margin-left: 0.5em;
float: right;
font-family: sans-serif;
}
label {
display: block;
margin-top: 1.25em;
margin-bottom: 0.25em;
}
select {
position: relative;
z-index: 1;
padding-right: 40px;
}
.isvalid:after {
content: '\2713';
color: green;
}
.notvalid:after {
content: '\2717';
color: red;
}
#successindicator {
float: right;
margin-left: 0.5em;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
height: 40px;
}
#json_result_container {
margin: 5em 0 0;
background-color: #eee;
color: #333;
/* border: solid lightgrey 1px; */
padding: 1em;
overflow: auto;
}
#autocomplete_wrap{
position: relative;
}
#suggestion_list{
position: absolute;
background-color: #fff;
outline: -webkit-focus-ring-color auto 1px;
list-style-type: none;
margin: 0;
padding: 0;
max-height: 400px;
overflow-y: auto;
}
#suggestion_list li{
cursor: pointer;
padding: 10px 5px;
}
#suggestion_list li.header{
border-bottom: 2px solid #ddd;
}
#suggestion_list li:hover, #suggestion_list li.selected{
background-color: #ddd;
}
#suggestion_list li span.location{
font-size: 0.75em;
color: #666;
}
.arrow {
border: solid black;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 3px;
}
.left {
margin-left: 3px;
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.address{
height: 140px;
margin: 8px;
}
.map {
height: 300px;
width: 100%;
}
body {
font-family: sans-serif;
padding: 0;
margin: 0;
}
Address lookup using Python, PHP or C#
These examples show how to make a request to the address endpoint to look up a UK address.
from urllib.parse import quote
import requests
import json
# Request parameters
api_key = "PCW45-12345-12345-1234X"
country_code = "UK"
search_term = "NR1 1NE"
# Prepare request and encode user-entered parameters with %xx encoding
request_url = f"https://ws.postcoder.com/pcw/{api_key}/address/{country_code}/{quote(search_term, safe='')}"
# Send request
response = requests.get(request_url)
# Process response
if response.status_code == 200:
json = response.json()
if len(json) > 0:
for address in json:
print(address["summaryline"])
else:
print("No results")
else:
print(f"Request error: {response.content.decode()}")
// Request parameters
$api_key = "PCW45-12345-12345-1234X";
$country_code = "UK";
$search_term = "NR1 1NE";
// Prepare request and encode user-entered parameters with %xx encoding
$request_url = "https://ws.postcoder.com/pcw/$api_key/address/$country_code/" . urlencode($search_term);
// Send request
$result = file_get_contents($request_url, false, stream_context_create(["http" => ["ignore_errors" => true]]));
// Process response
$status_line = $http_response_header[0];
preg_match("{HTTP\/\S*\s(\d{3})}", $status_line, $match);
$status_code = $match[1];
if ($status_code == 200) {
$json = json_decode($result);
if (count($json) > 0) {
foreach ($json as $address) {
echo($address->summaryline . "<br>");
}
} else {
echo("No results");
}
} else {
echo("Request error");
}
using System;
using System.Threading.Tasks;
using System.Web;
using System.Net.Http;
using Newtonsoft.Json.Linq;
public class Program
{
public static async Task Main()
{
// Request parameters
string apiKey = "PCW45-12345-12345-1234X";
string countryCode = "UK";
string searchTerm = "NR1 1NE";
// Prepare request and encode user-entered parameters with %xx encoding
string requestUrl = $"https://ws.postcoder.com/pcw/{apiKey}/address/{countryCode}/{HttpUtility.UrlEncode(searchTerm)}";
using (HttpClient client = new HttpClient())
{
// Send request
var response = await client.GetAsync(requestUrl);
var responseContent = await response.Content.ReadAsStringAsync();
// Process response
if (response.IsSuccessStatusCode)
{
JArray responseJson = JArray.Parse(responseContent);
if (responseJson.Count > 0)
{
foreach (JObject address in responseJson)
{
Console.WriteLine($"{address["summaryline"]}");
}
}
else
{
Console.WriteLine("No results");
}
}
else
{
Console.WriteLine($"Request error: {responseContent}");
}
}
}
}