Alle indlæg af Tobias Hinnerup

Stolte gazeller

Erhvervsavisen Børsen har kåret Hinnerup Net A/S som Gazellevirksomhed – på baggrund af en dokumenteret sund og bæredygtig udvikling i virksomheden over en længere periode.

Særlig i en tid hvor “finanskrise” er blevet et hverdagsord, er det naturligvis noget vi i høj grad er stolte af, og som vi håber at kunne leve op til også fremadrettet.

Vi tager det som en cadeau til vores medarbejdere, kunder og øvrige samarbejdspartnere, der har båret vores strategi om langsigtede samarbejder, baseret på exceptionelle kompetencer ud i livet – med overbevisende success.

Med det som afsæt, forventer vi også fremadrettet at kunne understøtte og videreudvikle den base af viden og færdigheder inden for vores virkefelt der har bragt os hertil. Vi glæder os til også de næste mange år at være en værdifuld støtte og foretrukken samarbejdspartner for vores kunder.

 

Autocomplete med Ajax på adresse med jQuery og OIO

Indtastning af adresseoplysninger er notorisk noget bøvlet: Der er flere indbyrdes forbundne felter og erfaringsvis opstår der meget hurtigt mangel på sammenhæng – hvilket fører til manuelle processer for opfølgning og fejlretning, for ikke at glemme muligheden for tabte forsendelser.

Heldigvis har den offentlige digitalisering i danmark resulteret i gratis & ubetinget adgang til services, der kan sammensættes til en gevaldig hjælp i forhold til at ramme rigtigt: Med et par kombinationer af jQuery, Ajax, JSONP og autocomplete er det muligt ud fra et delvist vejnavn at få postnummer og bynavn givet, med samt en liste over gyldige vejnumre.

Herunder et eksempel på et sæt adressefelter der hjælper hvor hjælpes kan. Prøv eventuelt først at taste vejnavn og lade autocomplete klare “resten” – og derefter i postnummerfeltet at skrive et nyt/andet postnummer og derefter konstatér, at autocomplete i vejnavne-feltet nu kun giver navne i det pågældende postnummer.









Givet, at de rette inkludes er gjort, kan den fulde funktionalitet af ovenstående implementeres med et kald ala

$().ready(function() {
  $("#streetname").autocompleteAddress();
});

Ovenstående under forudsætning af at der er defineret input felter i HTML’en som herunder.

<div class="ui-widget"> 
	<label for="streetname">Vejnavn: </label> 
	<input type="text" name="streetname" id="streetname"/>
	<label for="streetnumber">Nr.: </label> 
	<input type="text" name="streetnumber" id="streetnumber" size="4" />
</div>
<div class="ui-widget"> 
	<label for="zipcode">Postnummer: </label> 
	<input type="text" name="zipcode" id="zipcode" size="4"  />
	<input type="text" name="city" id="city" size="45" disabled="disabled" />
</div>

Såfremt det ønskes at benytte andre feltnavne/id’er en de her angivne, kan de angives eksplicit:

  $("#streetname").autocompleteAddress({
    streetNumber: "#streetnumber",
    zipCode : "#zipcode",
    city: "#city"
});

Såfremt en eller flere af adresse-felterne ikke kan findes (eller angives med null i argumentet) udelades autocomplete-funktionaliteten for dét. Særligt er tilfældet, hvor det eksempelvis kun ønskes at benytte plugin’et til at lave autocomplete på postnummer/bynavn: Her skal blot sørges for, at instantiere fra et vilkårligt element der IKKE er et input felt (eksempelvis “body”).

Værd at bemærke er også følgende options:

matchAnywhere Default: false
Afgør hvorvidt det indtastede kan matche et vilkårligt sted i vejnavnet (true), eller kun i begyndelsen (false).

maxSuggestions Default: 12
Angiver hvor mange valgmuligheder der maksimalt vises.

De nødvendige inkludes er “de gængse” for brug af jQuery og tilhørende UI, med tilføjelse af en lille smule bogholderi (style) og den til formålet udviklede widget: autocompleteAddress.js.

<link rel="stylesheet" href="http://code.jquery.com/ui/1.8.13/themes/base/jquery-ui.css"> 
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://code.jquery.com/ui/1.8.13/jquery-ui.min.js"></script>
<script src="http://www.hinnerup.net/2011/06/oiorest/jquery.ui.plugin_autocompleteAddress.js"></script>
<link rel="stylesheet" href="jquery.ui.plugin_autocompleteAddress.css"> 

Bag kulisserne er der tale om, at jQuery UI’s autocomplete er kædet til JSONP opslag mod “.json”-udgaverne af OIO’s REST-baserede webservices, jævnfør deres dokumentation for henholdsvis Vejnavne, Adresser og Postnummer.

Værd at bemærke er, at OIO’s implementation af vejnavne-servicen returnerer resultater på matches hvorsomhelst i navnet – og i autocomplete sammenhæng er det mest intuitive for de fleste formentlig at det er starten af vejnavnet man søger på. Såfremt matchAnywhere er false, ganges maxSuggestions med to ved opslag til Geoservicen, for at tilstræbe at “have nok”, når overflødige resultater frasorteres (idet Geoservicen kun understøtter søgninger af typen “matchAnywhere”). Det har den uheldige effekt, at idet 2 og 3 bogstavskombinationer forekommer i rigtig mange vejnavne, vil de første (mange) resultater fra OIO ofte IKKE være med matches i begyndelsen – hvorfor autocomplete ikke altid udnyttes af plugin’et. Bemærk, at denne uhensigtsmæssighed vil kunne omgås ved blot at fjerne maxantal begrænsningen på kaldet mod OIO – med performance fald som den eneste pris.

Situationen kan eksemplificeres ved i ovenstående at lave søgning efter eksempelvis “Bygm” og “By” henholdsvis med og uden at have angivet postnummeret “2400”.

Rent praktisk håndteres sagen i koden med kald af .filter og derefter .slice som illustreret herunder.

var serviceUri = "http://geo.oiorest.dk/vejnavne.json";
var serviceArguments = {
	/* Note; Custom filtering on success may reduce this */
	maxantal: matchAnywhere ? maxSuggestions : eStreetName.val().length < 4 ? 20*maxSuggestions : 2*maxSuggestions ,
	vejnavn: request.term
};

if(eZipCode.length) {
	var zipCode = eZipCode.val();
	if(zipCode.length == 4) {
		serviceArguments.postnr = zipCode;
	}
}

$.ajax({
	url: serviceUri,
	dataType: "jsonp",
	data: serviceArguments,
	success: function( data ) {
		if(!matchAnywhere) {
			//Remove matches that are not in the beginning of navn
			data = data.filter(function (vej) {
				var pattern = new RegExp("^" + eStreetName.val(), "i");
				return pattern.test(vej.navn);
			});
		}
		
		//Reduce to max number of suggestions for display
		data = data.slice(0, maxSuggestions); 

		//Map OIO object to label/value for jQuery autocomplete
		data = $.map(data, function( vej ) {
			return {
				label: vej.navn + " (" + vej.postnummer.nr + ")",
				value: vej.navn
			}
		})
		
		response(data);
	}
});

For optimering af brugeroplevelsen benyttes kun et enkelt opslag i forhold til autocomplete af vejnummeret – resultatet caches lokalt. Dette muliggør både en mere logisk sortering end den alfanumeriske (1, 10, 11, 2a, 20 …) som OIO leverer data i. Desuden omgås derved det “problem” der ligger i at adressse-servicen hos OIO matcher eksakt på husnummer-angivelse, og dermed ikke i udgangspunktet er synderligt velegnet til den nærværende autocomplete-anvendelse.

Dette plugin er tilføjet jQuery repository med navnet autocompleteAddress.

Øverst på listen over kommende features står:

  • Version 16 (?)
    • Forslag modtages gerne!
  • Version 1.5 (2014-02-03 Mathias Vielwerth)
    • Sortering af husnumre justeret & korrigeret
    • Afprøvet fungerende med jQuery 1.10.4
  • Version 1.4 (2011-08-22)
    • Sortering på vejnavn/postnummer tilføjet
  • Version 1.3 (2011-07-27)
    • Optimeret mapning og filtrering af vejnavne & numre
    • Optimeret parsning og sortering af vejnumre
    • Optimeret logik omkring maxantal (tilføjet missFactor)
    • Tilføjet “caller id” til alle requests mod Geoservien
  • Version 1.2 (2011-07-04)
    • Logisk sortering af husnumre (tak til Michael Schøler)
    • Mere intelligent håndtering af opslag til OIO vedrørende maxantal ved matchAnywhere = false
    • Stylesheet opsætning udtrukket til separat fil
  • Version 1.1 (2011-06-28)
    • Valgfri anvendelse af de 4 adressefelter
    • Valgfri angivelse af metode for selektion af vejnavne (start|alle)
    • Valgfri angivelse af maks antal indgange i dropdown
  • Version 1.0 (2011-06-23)
    • Første version

Yderligere forslag og kommentarer er meget velkomne.

Brug ikke hverken Gmail eller Hotmail

De sidste 14 dage har de to haft mindst een defekt mailserver i deres DNS rotation, hvilket effektivt fører til at det er umuligt at udtale sig om hvorvidt en modtager på domænerne kan/vil modtage mails man sender til dem.

Kombineret med det faktum, at det kan konstateres at have været tilfældet temmelig mange gange over de seneste par år, samt at det (selvsagt) er 100% umuligt at komme igennem med en fejlmelding til de to giganter, kan jeg vanskeligt konkludere andet end at det er en usædvanlig dårlig idé at benytte deres services, med mindre man er indstillet på at acceptere at mails periodisk og uden meldinger eller advarsler vil gå tabt.

Dog vil gælde, at afsenderen af mails der ikke afleveres må forventes at modtage en tilbagemelding om, at den/de pågældende mails ikke kunne afleveres – men hvis ikke afsender derefter finder en anden måde at kontakte modtager på, og orienterer om problemet, vil man aldrig blive opmærksom på at der er noget galt.

Supplerende ovenstående, for at give det lidt mere tekniske indblik, er mailserver-administrationen for systemer så store som de to, naturligvis ikke en enkel og simpel sag. Jævnfør det her indsatte øjebliksbillede af et opslag med nslookup, fordeler Hotmail sine mailservere over 5 indgange, hver med cirka 10 IP numre. Hvorvidt det i praksis bliver til 50 servere er vanskeligt at udtale sig om udefra – men det er indlysende at kompleksiteten af en sådan opsætning ikke er ubetydelig.

Opdatering 2014-01-27, af Tobias Hinnerup

Så har uheldet være ude igen – endnu engang var det hundredevis af mennesker og virksomheder, der havde valg at stole på Eniro, der brændte sig: Eniro: Utilgivelig fejl.

Opdatering 2013-04-05, af Tobias Hinnerup

Eniro lavede en smutter –hundredevis af mennesker mister alle deres emails uigenkaldeligt.

Opdatering 2010-06-25, af Michael Schøler

Vi er ikke de eneste der har opdaget problemer med Gmail, og man kan i dag på Computerworld læse en artikel om lange modtage- og leveringstider, ligesom at der i April i Secure Computing magazine blev udgivet en artikel om at der var opstået panik blandt alle Hotmail’s brugere da de ved forsøg på login fik af vide at de ikke havde en konto.

Opdatering 2010-09-05, af Michael Schøler

Til mængden af overvejelser man bør drøne igennem inden valget faldet på gmail, kan der tilføjes at vi har erfaret at gmail konti tilsyneladende i øjeblikket systematisk overtages fjendtligt og herefter eksempelvis anvendes til udsendelse af spam i email kontohaverens navn. Endvidere opsættes en blog i dit navn, hvorfra alverdens interessante blog posteringer om dig sikkert kan være at finde. Slutteligt kan der indsættes gadgets på din iGoogle side når din konto er overtaget, ligesom dine mails lagret i din indbakke med videre vil kunne læses af den uvenlige sjæl du er ramlet ind i.

Opdatering 2010-10-28, af Tobias Hinnerup

Som endnu et bræt til kisten, er der desværre også eksempler på at Google ikke kan håndtere den del af deres services som de tager penge for – Computerword har for nyligt fortalt om en uheldig virksomhed, der valgte at placere forretningskritiske services hos Google, med mildest talt uheldige konsekvenser.