jQuery Logo

JavaScript wrappen in herbruikbare jQuery plugins

0

In mijn vorige blog Gebruikersergernis: verspringende scrollbars is een oplossing in JavaScript uitgewerkt. jQuery is een veelgebruikte JavaScript library die gebruik maakt van een plugin architectuur. Daarmee kun je uitbreidingen realiseren. Plugins maken het mogelijk om functionaliteit en programmatuur eenvoudig herbruikbaar te maken. De JavaScript-oplossing om scrollbarposities te onthouden, kan in een jQuery plugin verwerkt worden om de herbruikbaarheid en het onderhoud van de functionaliteit te verbeteren. Ook zijn er nieuwe mogelijkheden door gebruik te maken van jQuery. Zo is het eenvoudig om configuraties en extra functionaliteit toe te voegen en deze netjes te bundelen binnen de namespace van de plugin.

jQuery plugins

jQuery heeft een standaardarchitectuur voor het schrijven van plugins. Andere plugins en libraries, zoals jQuery UI, maken hier eveneens gebruik van. Een plugin heeft een eigen namespace waarin de methodes van de plugin ook binnen dezelfde namespace blijven. Dit voorkomt onduidelijkheden en conflicten met andere plugins en jQuery functionaliteiten. Het framework van de plugin architectuur ziet er als volgt uit:

(function($){

    var methods = {
        init : function(options) {
        scrollpositionSave : function() {
        scrollpositionRestoreAll : function() {
        scrollpositionClearAll : function() {
    };

    //Plugin namespace 'scrollPosition' within jQuery
    $.fn.scrollPosition = function(method) {

        // Method calling logic
        if  methods[method]) {
            return methods[ method ].apply( this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || ! method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.scrollPosision');
        }    

    };

})(jQuery);

Methodes en events koppelen

De scrollbarmethodes scrollpositionSave(), scrollpositionRestoreAll() en scrollpositionClearAll() worden verwerkt in de plugin architectuur. De werking en benaming van deze methodes zal iets wijzigen door de nieuwe plugin structuur. Ook het koppelen van het scroll event van de HTML DOM-elementen wordt naar de plugin verplaatst. Het koppelen van het event met scrollpositionSave() ziet er in de plugin structuur als volgt uit:

var methods = {
    remember: function () {
        var obj = $(this);

        obj.each(function () {
            $(this).scroll(function () {
                var element = this;
                if (elementCanBeIdentified(element) && elementHasScrolled(element)) {
                    setCookie(element.id, element.scrollTop);
                }
            });
        });

        $(this).scrollPosition("restore");
    }
};

Vervolgens wordt een ‘remember’-methode gemaakt die voor ieder object in de jQuery selectie, logica koppelt aan de scrollmethode. Hierin wordt, net zoals in de oude situatie, de schuifbalkpositie in een cookie opgeslagen. De overige methodes worden op dezelfde manier verwerkt in de ‘methods’ array variabele.

Elementen selecteren

Wat verder opvalt is de context van geselecteerde DOM-elementen waarin de plugin zich bevindt. Dit gebeurt op de gebruikelijke jQuery selectie-manier. De gewenste elementen worden op de pagina geselecteerd en doorgegeven aan de plugin:

$().ready(function () {
   $('.RememberScrollPosition').scrollPosition('remember');
});

Met $(‘.RememberScrollPosition’) worden DOM-elementen geselecteerd welke ‘RememberScrollPosititon’ als waarde hebben voor het class attribuut. Vervolgens wordt op deze selectie met .scrollPosition(‘remember’) de jQuery plugin ‘scrollPosition’ gestart en en de methode ‘remember’ aangeroepen. Hierdoor is het mogelijk om in de plugin met .each de geselecteerde elementen te doorlopen en per element uit te voeren. Alle bewerkingen in de methodes gebeuren op basis van de geselecteerde elementen. Het is dus niet meer nodig om alle cookies te doorlopen.

Configureren

In jQuery plugins is het gebruikelijk om de werking instelbaar te maken zodat de plugin breed inzetbaar is. Het wordt bijvoorbeeld mogelijk conflicten met naamgevingen van cookies te voorkomen door eenvoudig een prefix toe te voegen aan de cookienaam, aangevuld met een identificatie van de pagina waarop het element zich bevindt. Wanneer een element met hetzelfde ID zich op een andere pagina bevindt zal de scrollpositie niet worden ingesteld. In de oude situatie was dit nog wel het geval. Ook zullen we,  in de vorm van een namespace, gebruik maken van een koppelkarakter tussen de cookie prefix, de paginanaam en het ID van het DOM-element. Verder zullen we debug/log informatie geven voor ontwikkelaars. Deze instellingen en hun standaardwaarden nemen we als volgt op in de jQuery-plugin in de ‘settings’ variabele:

(function ($) {

    // Default/initial settings for this jQuery plugin.
    var settings = {
        cookiePrefix: "scrollpos",
        page: "default",
        concatChar: "::",
        debug: false
    };

    var methods = {
    //...

})(jQuery);

Deze plugin instellingen kunnen we meegeven in de aanroep van de methode:

$().ready(function () {
    $('.RememberScrollPosition').scrollPosition('remember', { page: "Default.aspx", debug: true });
});

In de plugin methodes moeten de parameters in de methodeaanroep dan enkel nog verwerkt worden in de standaardwaarden van de jQuery-plugin:

var methods = {
    remember: function (options) {
        options = $.extend(settings, options);
 //...

Private methods

Debug informatie en andere logica die enkel binnen de plugin beschikbaar hoeft te zijn, houden we binnen de namespace van de plugin en publiceren we niet met behulp van de methods-constructie. Het verwerken van debug functionaliteit en het toevoegen van de cookie namespace ziet er dan als volgt uit:

(function ($) {
    // Default/initial settings for this jQuery plugin.
    var settings = {
        cookiePrefix: "scrollpos",
        page: "default",
        concatChar: "::",
        debug: false
    };

    // Public methods

    var methods = {
        remember: function (options) {
            _debug("Calling jQuery.scrollPosition.remember");
            options = $.extend(settings, options);

            var obj = $(this);

            obj.each(function () {
                $(this).scroll(function () {
                    var element = this;
                    if (_elementCanBeIdentified(element)) {
                        if (_elementHasScrolled(element)) {
                            var elementStorageKey = _getElementStoragePropertyName(element);
                            var elementScrollPosition = element.scrollTop;
                            _setCookie(elementStorageKey, elementScrollPosition);
                            _debug("Remembered scroll position in cookie: " + _getElementStorageProperty(element));
                        } else {
                            $(this).scrollPosition("forget", options);
                        }
                    }
                });
            });

            $(this).scrollPosition("restore", options);
        }
    };

    $.fn.scrollPosition = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.scrollPosition');
        }
    };

    // Private methods

    function _debug(logMessage) {
        if (settings._debug == false) {
            return;
        }

        if (window.console != undefined) {
            console.log(logMessage);
        } else {
            //alert(logMessage);
        }
    }

    function _getElementStorageProperty(element) {
        return _getElementStoragePropertyName(element) + "=" + element.scrollTop;
    };
    function _getElementStoragePropertyName(element) {
        return _getElementStoragePropertyPrefix() + element.id;
    };
    function _getElementStoragePropertyPrefix() {
        return settings.cookiePrefix + settings.concatChar + settings.page + settings.concatChar;
    };

    function _setCookie(key, value) {
        document.cookie = key + "=" + value;
    }

    function _elementCanBeIdentified(element) {
        try {
            return document.getElementById(element.id) && element.id.length > 0;
        }
        catch (e) {
            return false;
        }
    }

    function _elementHasScrolled(element) {
        try {
            return element.scrollTop > 0;
        }
        catch (e) {
            return null;
        }
    }
})(jQuery);

De debug logging informatie – die de werking van de programmatuur inzichtelijker maakt voor ontwikkelaars – ziet er als volgt uit:

Conclusies

Zoals je kunt zien is het vrij eenvoudig om bestaande JavaScript-functionaliteit in een jQuery plugin te wrappen. De voordelen zijn direct duidelijk; de code is volgens een duidelijke, vaste en (ook voor andere ontwikkelaars) herkenbare structuur uitgewerkt, hetgeen de onderhoudbaarheid en kwaliteit van de code ten goede komt. Ook kunnen we de standaard functionaliteit van jQuery eenvoudig gebruiken in de plugins. Door gebruik te maken van de plugin hebben we eenvoudig uitbreidingen kunnen realiseren. Deze functionaliteit is in meerdere situaties te gebruiken.

» Download hier het demo project (Visual Studio 2010)

  • Visual Studio 2010
  • ASP.NET 4.0 Web Application
  • jQuery 1.4.1 (standaard beschikbaar in ASP.NET 4.0 Web Application)

De volledige jQuery plugin ziet er als volgt uit:

(function ($) {

    // Default/initial settings for this jQuery plugin.
    var settings = {
        cookiePrefix: "scrollpos",
        page: "default",
        concatChar: "::",
        debug: false
    };

    // Public methods

    var methods = {
        // Initialize plugin
        init: function (options) {

        },

        // Store scrollbar position on each scroll of the selected elements
        // and restores known scrollbar positions (useful when script is fired, e.g. on request/postback).
        // Uses cookie storage.
        remember: function (options) {
            _debug("Calling jQuery.scrollPosition.remember");
            options = $.extend(settings, options);

            var obj = $(this);

            obj.each(function () {
                $(this).scroll(function () {
                    var element = this;
                    if (_elementCanBeIdentified(element)) {
                        if (_elementHasScrolled(element)) {
                            var elementStorageKey = _getElementStoragePropertyName(element);
                            var elementScrollPosition = element.scrollTop;
                            _setCookie(elementStorageKey, elementScrollPosition);
                            _debug("Remembered scroll position in cookie: " + _getElementStorageProperty(element));
                        } else {
                            $(this).scrollPosition("forget", options);
                        }

                    }
                });
            });

            $(this).scrollPosition("restore", options);
        },

        // Restores known scrollbar positions. Uses cookie storage.
        restore: function (options) {
            _debug("Calling jQuery.scrollPosition.restore");
            options = $.extend(settings, options);

            var obj = $(this);

            obj.each(function () {
                var element = this;
                var cookies = _getCookiesAsArray();
                try {
                    var elementStorageKey = _getElementStoragePropertyName(element);
                    var elementScrollPosition = cookies[elementStorageKey];
                    _elementSetScrollPosition(element.id, elementScrollPosition);
                    _debug("Restored scroll position: " + element.id + "=" + elementScrollPosition);
                }
                catch (e) {
                }
            });
        },

        // Forget known scrollbar positions. Expire cookie storage.
        // Note: does not decouple the scroll event which may store the scroll
        // position again if 'remember' is called on the element!
        forget: function (options) {
            _debug("Calling jQuery.scrollPosition.forget");
            options = $.extend(settings, options);

            var obj = $(this);

            obj.each(function () {
                var element = this;
                try {
                    var elementStorageKey = _getElementStoragePropertyName(element);
                    _clearCookie(elementStorageKey);
                    _debug("Cleared scroll position: " + element.id);
                }
                catch (e) {
                }
            });
        }
    };

    // Private methods

    function _debug(logMessage) {
        if (settings.debug == false) {
            return;
        }

        if (window.console != undefined) {
            console.log(logMessage);
        } else {
            //alert(logMessage);
        }
    }

    function _getElementStorageProperty(element) {
        return _getElementStoragePropertyName(element) + "=" + element.scrollTop;
    };
    function _getElementStoragePropertyName(element) {
        return _getElementStoragePropertyPrefix() + element.id;
    };
    function _getElementStoragePropertyPrefix() {
        return settings.cookiePrefix + settings.concatChar + settings.page + settings.concatChar;
    };

    function _getCookiesAsArray() {
        var result = {};
        var cookieContent = document.cookie;
        if (cookieContent.length > 0) {
            var cookies = cookieContent.split(";");
            for (var i = 0; i < cookies.length; i++) {
                var keyValuePair = cookies[i].split("=");
                try {
                    var key = keyValuePair[0].replace(" ", "");
                    var value = keyValuePair[1];
                    result[key] = value;
                }
                catch (e) {
                }
            }
        }
        return result;
    }

    function _setCookie(key, value) {
        document.cookie = key + "=" + value;
    }

    function _clearCookie(key) {
        try {
            var date = new Date();
            document.cookie = key + "=0;expires=" + date.toGMTString() + ";";
            return true;
        }
        catch (e) {
            return false;
        }
    }

    function _elementCanBeIdentified(element) {
        try {
            return document.getElementById(element.id) && element.id.length > 0;
        }
        catch (e) {
            return false;
        }
    }

    function _elementHasScrolled(element) {
        try {
            return element.scrollTop > 0;
        }
        catch (e) {
            return null;
        }
    }

    function _elementSetScrollPosition(elementId, position) {
        try {
            document.getElementById(elementId).scrollTop = position;
            return true;
        }
        catch (e) {
            return false;
        }
    }

    //Prevent jQuery namespacing cluttering by using the suggested jQuery plugin architecture.
    //http://docs.jquery.com/Plugins/Authoring#Plugin_Methods
    $.fn.scrollPosition = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.scrollPosition');
        }
    };

})(jQuery);
Mediaan-Mobile Development Avatar

Mobile Development

0

Een trend uit 2011 die zeker zal doorzetten in 2012 is de ontwikkeling van apps. Mobile is immers hot, er komen dan ook steeds meer apps beschikbaar voor diverse platformen.  In deze blog delen wij graag onze ervaringen met je over het bouwen van mobiele applicaties, ook wel “apps” genoemd. We zullen het hebben over de verschillende user interfaces van de diverse platformen en hoe je ervoor kunt zorgen dat je zoveel mogelijk de logica hiervan kunt delen tussen de verschillende applicaties. Tot slot behandelen we het onderwerp security voor mobiele applicaties.

Mobile Development Architectuur

User Experience en Interface

Een veel gestelde vraag bij het ontwikkelen van applicaties voor mobiele apparaten is hoe je om moet gaan met de user interfaces van de verschillende platformen. Elk platform heeft haar eigen ‘look and feel’ en een Android-applicatie werkt anders dan een iPhone- of iPad-applicatie. Vraag bijvoorbeeld eens aan een collega met een Android-toestel om een app op een iPhone te openen en terug te keren naar het hoofdscherm. De kans is groot dat deze Android-gebruiker zal zoeken naar een back knop, terwijl de iPhone-gebruiker zich afvraagt waarom de Android-smartphone een home én een back knop heeft.

Uniek

Elk platform heeft een eigen layout en vormgeving en daarmee ook  een unieke manier voor het presenteren van informatie en het bewerkstelligen van gebruikersinteractie. Dit is de vormgeving en layout waaraan de gebruikers gewend zijn. Dat geldt ook voor de gebruikers van jouw (toekomstige) applicatie. Dit heeft er onder andere voor gezorgd dat wij besloten hebben om apps zo “native” mogelijk te houden. De leercurve is minimaal. Voor iOS, Android en Windows Phone 7 worden object georiënteerde talen gebruikt. Die komen qua structuur overeen met de talen van overige projecten. Het is daarna wel noodzakelijk om de betreffende frameworks en syntaxes te leren kennen en hiermee ervaring op te doen. Er zijn voldoende cursussen en online resources beschikbaar die hier uitkomst bieden.

Herbruikbaarheid

Hoe zorgen we ervoor dat we zo min mogelijk onderhoud moeten uitvoeren als we straks drie verschillende apps hebben?

Dat  is een vraag die je vaak zult tegenkomen in projecten, vooral wanneer je ontwikkelt voor meerdere platformen. De eerste maatregel die wij hebben genomen is om zoveel mogelijk logica en business rules te verplaatsen naar centraal beheerde webservices. Bij een dergelijke opzet dien je rekening te houden met wijzingen in de webservice. Na een wijziging moeten de applicaties namelijk wél blijven werken. Je moet er daarom voor zorgen dat de applicatie, ook na een wijziging, de response correct kan afhandelen. De applicatie vormt de presentatielaag waarmee de gebruiker ‘communiceert’. De verantwoordelijkheid van de applicatie blijft daarmee beperkt tot het versturen van berichten naar de webservice en het afhandelen van het antwoord dat deze service geeft. Een groot voordeel van deze manier van ontwikkelen is dat alle apps dezelfde controles uitvoeren. Deze gebeuren immers door de webservices. Onze ervaring is dat het ontwikkelen van user interfaces minder tijd kost dan het ontwikkelen van de webservices. Op deze manier is het mogelijk om snel apps uit te rollen voor nieuwe platformen.

Mediaan ontwikkelt zoveel mogelijk standaardfunctionaliteiten. Het voordeel daarvan is dat deze tevens te gebruiken zijn bij andere projecten. Het is dan ook de truc om elk onderdeel van een applicatie in (kleine) aparte componenten te ontwikkelen. Hierdoor kun je makkelijk onderdelen die je ooit al eens ontwikkeld hebt gebruiken in een nieuw project met relatief weinig overhead. Daarnaast heb je op deze manier een mooi overzicht van je project en is de kans op vervelende bugs aanzienlijk kleiner.

Security

Hoe zit het dan met privacy gevoelige informatie?

Je kunt natuurlijk geen data versturen zonder goed na te denken over beveiliging. Er zijn talloze voorbeelden te vinden van uitgelekte informatie of gehackte websites. Sommige hiervan waren (te) slecht beveiligd, terwijl andere dachten goed beveiligd te zijn. Denk hierbij aan het voorval met de SSL-certificaten van Diginotar. Niets is tegenwoordig meer veilig genoeg.

Om een ander voorbeeld te noemen: Ontwikkelaars ontrafelen protocol Siri-spraakherkenning. Apple hecht veel waarde aan securiteit. Toch komen gebruikers erachter hoe ze deze data moeten benaderen. Feit is dat je alles zoveel kunt beveiligen als je wilt, wanneer iemand echt je data wilt opsporen komt hij of zij daar toch wel aan. De vraag hoe je hiermee omgaat is dan ook minstens zo belangrijk.  Apple heeft met zekerheid gelet op beveiliging. Het bedrijf kan zien welke telefoon de service benadert en daarmee zou je in theorie kunnen achterhalen welke apparaten je moet blokkeren. Voorwaarde is natuurlijk wel dat je een systeem hebt geïmplementeerd waarmee je apparaten daadwerkelijk kunt blokkeren. Of Apple wel of niet over een dergelijk systeem heeft, laten we in het midden. Het is dan ook meer een kwestie van de mogelijkheid hebben om op een effectieve manier op een inbraak te reageren, dan te proberen een inbraak volledig te voorkomen.

Een ander voorbeeld van maart vorig jaar: Ontwikkelaar verkrijgt toegang tot NS-api voor treintijden. NS gebruikte voor deze api een http-verbinding. Die is niet beveiligd met een SSL-certificaat. Daardoor was het relatief eenvoudig om de gebruikersnaam en het wachtwoord te achterhalen. De NS heeft als reactie hierop de API op een veilige en gecontroleerde manier beschikbaar gesteld voor ontwikkelaars.

Om een extra beveiliging toe te passen kun je gebruik maken van een het OAuth principe. Hierbij communiceer je met de server om via een gebruikersnaam en wachtwoord een token te verkrijgen. Je kunt pas gebruik maken van services nadat je deze token hebt verkregen. Twitter en Facebook gebruiken dit principe om een applicatie toegang te geven tot bepaalde  informatie over een gebruiker. Tevens wordt op deze manier bepaald of de applicatie een tweet/status update mag plaatsen namens de gebruiker. Deze moet hier wel eerst toestemming voor hebben gegeven. Ditzelfde principe wordt vaker toegepast bij de communicatie tussen een applicatie en een webservice om zo een extra beveiliging te bewerkstelligen.

Er zijn dus meerdere mogelijkheden om je data veilig te stellen. Deze methoden kunnen zowel geïmplementeerd worden aan de gebruikerszijde als bij de applicatie- en servicezijde. Daarnaast dien je ervoor te zorgen dat je snel en effectief kunt handelen op het moment dat er toch een inbraak heeft plaatsgevonden. Zorg ervoor dat je een calamiteitenplan hebt, dat bekend is bij de betrokken personen. Dit laatste is minstens zo belangrijk als een goede beveiliging van je applicatie.

Conclusie

Als je mobiele applicaties gaat ontwikkelen is het belangrijk om eerst goed na te denken over het ontwerp. Probeer zoveel mogelijk terugkerende zaken als business rules in een omgeving te plaatsen die beschikbaar gesteld kan worden aan een selecte groep applicaties. Dit kan met behulp van webservices. Denk er hierbij wel aan om de juiste beveiligingsmaatregelen te nemen. Beperk de hoeveelheid data tot een minimum en zorg ervoor dat je kunt inhaken op toekomstige ontwikkelingen. Door je app te laten aansluiten op de UI-guidelines van het platform waar je voor ontwikkelt, vergroot je de bruikbaarheid van je app.

Wil je meer weten over mobile development of security-maatregelen? Lees dan het artikel in de Mediaanspraak over security geschreven door onze collega Paul Roomberg. Of neem vrijblijvend contact op via ons contactformulier, of natuurlijk via Twitter (@Mediaan) of Facebook.

linkedin-logo

Social Branding met LinkedIn

0

Social branding houdt in dat je via sociale media je eigen merk promoot. Bekende voorbeelden zijn het versturen van berichten via Twitter of het ‘liken’ op Facebook. Het zakelijk netwerk LinkedIn is eveneens een goed medium voor social branding. Veel Nederlanders, inmiddels ruim 2,5 miljoen, hebben een profiel op LinkedIn om hun CV en/of (eigen) bedrijf te vertegenwoordigen. En hoewel LinkedIn goede tips geeft over de inrichting van je profiel, zijn de pagina’s vaak ‘kaal’. Ook de mogelijkheden binnen LinkedIn om te netwerken, jezelf en het bedrijf waar je voor werkt te promoten worden weinig gebruikt.

Benut je profiel optimaal

Er zijn veel LinkedIn-profielen die minimaal ingevuld worden. Als je verder kijkt naar de mogelijkheden die LinkedIn te bieden heeft, kun je echter veel meer van jezelf en je bedrijf tonen.

Om te beginnen moet er een (duidelijke) foto van jezelf te zien zijn. Namen worden snel vergeten tijdens de bekende voorstelrondes op borrels en evenementen, een gezicht daarentegen is veel herkenbaarder. Laat dit dus ook zien! Het is, in combinatie met je titel en je competenties, dé toegangspoort naar je profiel.

Daarnaast laten veel gebruikers binnen hun LinkedIn-profiel, vaak in 1 of 2 regels samengevat, zien wie ze zijn. Een korte samenvatting als deze, is natuurlijk veel te weinig voor bestaande en/of potentiële klanten en andere interessante relaties om erachter te komen of jij de persoon bent die hen kan helpen. Gebruik daarom de ruimte die je hebt bij de “Past” en “Current” experience om bijvoorbeeld opdrachten die je hebt gerealiseerd toe te lichten. Doe dit voor iedereen binnen het bedrijf of de afdeling. Elke werknemer heeft immers zijn of haar specifieke kwaliteiten en kennis.

Vul, buiten de standaard “Past” en “Current” experience je profiel ook aan met zogenaamde Sections. De keuzes die je uit de verschillende onderdelen kunt maken is groot. Je kunt bijvoorbeeld een “Summary” toevoegen waarin je meer over jezelf of over de ideeën en plannen die je hebt vertelt. Een andere interessante section is bedoeld voor het toevoegen van certificaten en publicaties. Hierin staat duidelijk vermeld welke certificaten je hebt behaald en wanneer dit is gebeurd of waarover je hebt gepubliceerd.

Bekijk tenslotte de completeness van je profiel om te zien wat je nog kunt toevoegen.

Relaties & Groepen

Heb je iemand ontmoet tijdens een borrel, evenement of een andere meeting? Voeg deze persoon toe aan je netwerk en schrijf bij de uitnodiging aan hem of haar een klein, persoonlijk bericht. Bijvoorbeeld “Hallo Karel, ik vond het erg leuk je te ontmoeten op de softwarebeurs!”. Dat geldt al helemaal als je de persoon in kwestie maar kort of eenmalig hebt ontmoet. Wacht niet af tot jij wordt toegevoegd, maar ga ook zelf actief op zoek naar nieuwe contacten.
Het is vaak een discussiepunt of je bijvoorbeeld ook vrienden en familie moet toevoegen. LinkedIn is immers een zakelijk netwerk en is niet bedoeld voor privézaken zoals bijvoorbeeld Facebook. Ik ben er zelf voorstander van om wel je vrienden, familie en kennissen toe te voegen. Ze werken in een andere sector dan ik en kennen andere mensen. Deze nieuwe relaties zijn voor mij misschien ook wel interessant. Het contact dat ik met mijn vrienden, kennissen en familie via LinkedIn onderhoud, is strikt zakelijk. Als ik ze voor een feestje wil uitnodigen, of vakantie foto’s met ze wil delen, gebruik ik daar andere sociale media voor zoals e-mail, Twitter en Facebook.

Daarnaast helpt LinkedIn je in de zoektocht naar nieuwe contacten. LinkedIn stelt je namelijk de nieuwe contacten voor die voortkomen uit de contacten en bedrijven die je al eerder aan je profiel hebt toegevoegd. Deze optie vind je via “Contacts”> “Add contacts” en het tabblad “People you may know”. Je kunt vervolgens binnen de resultaten diverse filters toepassen, bijvoorbeeld je huidige werkgever(s), vorige werkgever(s) of de opleidingsinsituten die je hebt toegevoegd aan je profiel.

Verder heb je branche specifieke groepen waarvoor je je kunt aanmelden. Via deze groepen kun je in contact komen met concullega ’s uit jouw sector en discussies onderhouden over onderwerpen die in jullie branche spelen.

Privacy & Zichtbaarheid

Omwille van hun privacy kiezen veel mensen ervoor zo min mogelijke gegevens openbaar te maken, bij social branding wil je juist een open profiel hebben. Daarom is het handig dat LinkedIn een aantal instellingen heeft die jouw vindbaarheid vergroten. Deze instellingen vind je onder je account-settings. Een voorbeeld van een belangrijke privacy instelling is omtrent de profielfoto. Zodra je die hebt toegevoegd stel je je profiel zo in, dat iedereen je foto kan zien.  Dus niet alleen je eigen connections of network.

Het openstellen van je profiel heeft natuurlijk als consequentie dat je goed moet nadenken over wat je wel of juist niet openbaar maakt. Niet elke klant zal het bijvoorbeeld waarderen als je een opdracht die je voor hem hebt uitgevoerd, uitgebreid beschrijft.

Leads zoeken via LinkedIn

LinkedIn bevat tal van mogelijkheden voor het zoeken naar leads. Je kunt je bijvoorbeeld abonneren op interessante bedrijfspagina’s en berichten sturen naar werknemers van dat bedrijf. Je kunt ook werknemers van een bedrijf zelf toevoegen of gebruik van maken de “get introduced” knop.  Deze functionaliteit zoekt iemand binnen jouw eigen contacten die tegelijkertijd een contact is van de ander. Hoe meer connections je hebt, des te gemakkelijker je iemand vindt die jou kan introduceren.

Een andere functionaliteit is “Advanced Search”, waarmee je uitgebreid kan zoeken. Eén manier om dit te gebruiken is het invullen van de zoekvelden op de pagina voor “Advanced People Search”. Handiger en sneller daarentegen zijn de keywords die je kunt gebruiken. Ik kan bijvoorbeeld zoeken naar iedereen die “Salesmanager” in zijn of haar titel heeft staan door te zoeken op “ctitle: Salesmanager”.  Hier kan ik vervolgens nog verder op filteren door “Country: Netherlands” erbij te zetten. Dit kun je in de “kleinere” zoekbox invullen die je in de menubalk ziet. Met deze snelle zoekopdracht krijg ik de salesmanagers in Nederland te zien. Het aantal resultaten dat je te zien krijgt is afhankelijk van het account dat je hebt.

LinkedIn bevat ook een optie om te adverteren, met als focus het vinden van nieuwe klanten. Als je van die mogelijkheid gebruik wil maken kun je stapsgewijs je advertentie instellen zoals de plaats van de advertentie en je budget. Weet dat LinkedIn regels hanteert rondom het plaatsen van advertenties, bijvoorbeeld dat ze in het Engels geschreven moeten zijn. Adverteren bij LinkedIn is natuurlijk niet gratis. Dat roept meteen de vraag op hoe kosten en baten zich tot elkaar verhouden. M.a.w. hoeveel potentiële klanten bereik ik onder de huidige richtlijnen via LinkedIn, wat kost dat en is het dat wel waard? Meer informatie over dit adverteren vind je op deze pagina.

Tips

  • Maak een bedrijfspagina aan en zorg ervoor dat werknemers het juiste bedrijf noemen in hun profiel en doorlinken naar deze bedrijfspagina. Geïnteresseerden kunnen hierdoor meteen doorklikken naar jouw bedrijf en er meer over lezen. Ze zien bovendien direct wie er behalve jij zelf nog meer werkt. Vergeet naast de bedrijfspagina niet je company website toe te voegen aan je profiel.
  • Sinds kort kun je de taal van LinkedIn naar Nederlands zetten.  Dit is de taal die de meeste van ons dagelijks gebruiken. Het voordeel van die meertaligheid is dat je sneller de opties en de mogelijkheden herkent die er binnen LinkedIn zijn. De Engelse taal zorgt nog wel eens voor twijfels bij het maken van bepaalde instellingen. Om je LinkedIn naar Nederlands om te zetten ga je naar je account instellingen en klik je onder de tab “Account” op “Select your language”.
  • Ben je account- of sales manager overweeg dan eens om een Premium Account te nemen.  De mogelijkheden zijn, in vergelijking met het gratis account, gelijk.  Het grote verschil met een gratis account is dat je meer resultaten ziet tijdens je zoektocht naar nieuwe contacten.
  • Heb je een opdracht bij een klant goed afgerond? Vraag dan om een recommendation op LinkedIn. Positieve recensies van andere klanten zijn van grote waarde voor je Social Branding.
  • Volg de Timeline in LinkedIn. Hier kun je, buiten de e-mails die je krijgt, zien wat er binnen jouw netwerk is gebeurd. Al deze updates vind je onder “Home”.
  • Een nieuwe baan, een nieuwe opdracht, cursus gevolgd, een certificaat of een andere prestatie behaald? Werk je profiel bij! De wereld staat niet stil, jij en jouw bedrijf ook niet.
  • Voeg alleen relevantie informatie van je profiel toe. Een beroep in het verleden, bijv. “vakkenvuller bij de plusmarkt”, heeft weinig van doen met je huidige dagelijkse werkzaamheden en voegt niets toe.
  • Bepaal je eigen doelgroep. Heb je veel internationale relaties, schrijf je profiel dan in het Engels of in meerdere talen (bijv. Nederlands, Engels, Duits).
  • Kijk tenslotte eens goed naar andere profielen. Zo vind je weer interessante, nieuwe onderdelen die je zelf nog niet hebt gebruikt.

Samenvatting

Vaak zijn profielen leeg en wordt LinkedIn niet optimaal benut. Kijk naar de mogelijkheden, vul je profiel zo goed mogelijk in, laat jezelf en je bedrijf zien!

Betrek iedereen binnen je bedrijf of afdeling bij jouw LinkedIn strategie. Elke lead naar een huidige klant en naar een nieuwe klant is goed. Beperk niet de grenzen tot de managers van je bedrijf, maar laat iedereen een steentje bijdragen met de zoektocht naar nieuwe opdrachten voor het bedrijf. Actief gebruik en niet passief afwachten is het kernpunt van Social Branding in elk medium, zo ook bij LinkedIn.

scrollbars

Gebruikersergernis: verspringende scrollbars

0

Gebruikersergernissen zitten vaak in een klein hoekje. Eén daarvan is dat de positie van de schuifbalk verloren gaat wanneer je een webpagina ververst, bijvoorbeeld bij het aanvinken van een selectiebox of een keuzeveld. In deze blogpost laat ik zie hoe je met behulp van JavaScript hiervoor eenvoudig een oplossing kunt realiseren.

Waarom dit probleem?

Soms kun je het verversen van (delen van) webpagina’s niet vermijden. Ontwikkelaars houden hier meestal rekening mee en proberen requests bij dit soort gebruikersacties te vermijden of zoveel mogelijk te beperken. Soms kan het echter niet anders. Er kunnen bijvoorbeeld afhankelijkheden zitten tussen de verschillende invoervelden en andere formulierelementen. Zie onderstaand voorbeeld:

In het voorbeeld zijn twee containers te zien met een scrollbar. Om functionele redenen worden bij iedere selectie van een item de gegevens verstuurd waarmee iets gedaan moet worden. Voorbeelden daarvan zijn het tonen van informatie over de huidige selectie of het bijwerken van de waarden van een ander afhankelijk formulierelement. Microsoft ASP.NET verstuurt deze data met ‘Postbacks’. Andere implementaties, in bijvoorbeeld PHP, versturen direct een page request terwijl AJAX de inhoud van de formulierelementen vervangt. Ongeacht de gebruikte technologie zal bij het vervangen van de inhoud de scrollbar naar boven verspringen, naar de beginpositie. Dit is niet gebruiksvriendelijk.

Oplossingsrichting

Dit verspringen van de scrollbar is eenvoudig te verhelpen. Functioneel werkt het als volgt. Sla de positie van de balk op zodra deze wijzigt. Wanneer je de inhoud ververst kun je de positie weer terugzetten. De technische werking van deze oplossingsrichting bevat tevens een aantal ontwerpbeslissingen. Wanneer de pagina laadt zul je het scroll event moeten koppelen aan de logica die de positie van de scrollbar opslaat. Het opslaan van de posities moet op een manier gebeuren die tussen pagina requests niet verloren gaat. Dit kan door middel van hidden input values die met het formulier meegestuurd worden. Nog beter is om cookies te gebruiken als opslagmechanisme. Ook als elementen met een scrollbar zich buiten een formulier bevinden, wordt zo de waarde opgeslagen. Om de functionaliteit herbruikbaar te maken voor gebruik in de toekomst, kun je specificeren van welke elementen de scrollbarpositie opgeslagen moet worden. Dit los je op door de class ‘RememberScrollPosition’ aan de betreffende HTML DOM-elementen toe te kennen.

Technische oplossing

In dit voorbeeld kiezen we voor een client side oplossing in JavaScript en gaan we uit van een ASP.NET oplossing die requests/postbacks uitvoert bij iedere selectie van een item. De HTML-code en ASPX-code ziet er als volgt uit:

<div id="scrolbaarElement1" class="RememberScrollPosition"
style="width: 100px; height: 150px; overflow: auto; border: 1px solid #000;">
    <asp:CheckBoxList ID="CheckBoxList1" runat="server" AutoPostBack="True">
        <asp:ListItem>Item 1</asp:ListItem>
        <asp:ListItem>Item 2</asp:ListItem>
        <asp:ListItem>Item n</asp:ListItem>
        …
    </asp:CheckBoxList>
</div>

Allereerst is er logica nodig. Met de class ‘RememberScrollPosition’ kun je die op het scroll event van DOM-elementen uitvoeren. Wanneer jQuery beschikbaar is, kun je dit heel eenvoudig oplossen:

$(document).ready(function () {
    scrollpositionRestoreAll();
    $(".RememberScrollPosition").each(function () {
        $(this).scroll(function () {
            scrollpositionSave(this);
        });
    });
});

Bovenstaande code komt in de <head> sectie van de pagina en wordt uitgevoerd bij het laden van de pagina. Eerst roep je scrollpositionRestoreAll() aan om eerder opgeslagen scrollbalkposities te herstellen. Vervolgens selecteer je met behulp van jQuery alle DOM-elementen met de class ‘RememberScrollPosition’. Op het scroll event van ieder element roep je vervolgens scrollpositionSave() aan. Vanzelfsprekend bevat dit de logica om de positie op te slaan in een cookie. Dat gaat als volgt:

function scrollpositionSave(element) {
    if (elementCanBeIdentified(element) && elementHasScrolled(element)) {
        setCookie(element.id, element.scrollTop);
    }
}

function elementCanBeIdentified(element) {
    return document.getElementById(element.id) && element.id.length > 0;
}

function elementHasScrolled(element) {
    return element.scrollTop > 0;
}

De DOM-elementen waarvan je de scrollpositie opslaat, moeten een ID-attribuut hebben zodat het element uniek is en herkend kan worden. Anders is niet duidelijk om welk element op de pagina het gaat. De eigenschap ‘scrollTop’ kun je in JavaScript gebruiken om de positie van de schuifbalk op te halen. De positie wordt alleen opgeslagen wanneer deze niet in de beginpositie staat. Zo beperk je de opslag van de posities tot wat strikt noodzakelijk is.

Nu duidelijk is hoe het opslagmechanisme werkt, kun je de posities van de schuifbalk implementeren. Dit gebeurt door middel van het uitlezen van het cookie. Voor iedere waarde die in het cookie staat, wordt het element en de positie uitgelezen én toegepast wanneer het element op de pagina is gevonden.

function scrollpositionRestoreAll() {
    var cookies = getCookiesAsArray();
    for (var cookieKey in cookies) {
        if (elementExists(cookieKey)) {
            var elementId = cookieKey;
            var elementScrollPosition = cookies[elementId];
            elementSetScrollPosition(elementId, elementScrollPosition);
        }
    }
}

In bovenstaande code worden hulpfuncties gebruikt. Die zijn in aparte functies gezet om ze in andere delen van de programmatuur opnieuw te kunnen gebruiken.

function getCookiesAsArray() {
    var result = { };
    var cookieContent = document.cookie;
    if (cookieContent.length > 0) {
        var cookies = cookieContent.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var keyValuePair = cookies[i].split("=");
            try {
                var key = keyValuePair[0].replace(" ", "");
                var value = keyValuePair[1];
                result[key] = value;
            }
            catch (e) {
            }
        }
    }
    return result;
}

function elementExists(elementId) {
    return document.getElementById(elementId);
}

function elementSetScrollPosition(elementId, position) {
    document.getElementById(elementId).scrollTop = position;
}

In sommige situaties is het nodig om de eerder opgeslagen schuifbalkposities te verwijderen. Dit gaat op dezelfde manier als scrollpositionsRestoreAll(). De actie echter is niet het herstellen van de schuifbalkpositie, maar het verlopen van de cookie. De browser verwijdert in dat geval de waarde.

function scrollpositionsClearAll() {
    var cookies = getCookiesAsArray();
    for (var cookieKey in cookies) {
        if (elementExists(cookieKey)) {
            clearCookie(cookieKey);
        }
    }
}

Bovenstaande JavaScript-methodes kun je opslaan in een apart .js bestand. De functionaliteit is daarmee herbruikbaar op andere pagina’s.

Eventueel kun je scrollpositionsClearAll() gebruiken wanneer de pagina voor het eerst wordt aangeroepen. De gebruiker start dan iedere keer met een herkenbare beginsituatie. Dit kan in de codebehind van de ASPX-1pagina:

C#:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        Page.ClientScript.RegisterClientScriptBlock(
            this.GetType(), "Body_Load_ClearScrollPositionsScript",
             "scrollpositionsClearAll()", true);
    }
}

VB:

Protected Overrides Sub OnLoad(ByVal e As EventArgs)
    MyBase.OnLoad(e)
    If Not Me.IsPostBack() Then
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "Body_Load_ClearScrollPositionsScript", "scrollpositionsClearAll()", True)
    End If
End Sub

Conclusies

Met enkele eenvoudige JavaScript-methodes heb je zo een oplossing gerealiseerd waarbij de scrollposities van elementen worden onthouden tussen de postbacks en het verversen van de pagina. De functionaliteit kan hergebruikt worden. Het zou echter handig zijn als we dit in een jQuery plugin kunnen wrappen. Dat zorgt er niet alleen voor dat het eenvoudiger wordt om deze functionaliteit opnieuw te gebruiken, maar onderhoudt ook de programmatuur beter. In een volgende blogpost zal ik dit verder uitwerken.

» Download hier het demo project (Visual Studio 2010)

  • Visual Studio 2010
  • ASP.NET 4.0 Web Application
  • jQuery 1.4.1 (standaard beschikbaar in ASP.NET 4.0 Web Application)
Schrijven voor het web

Schrijven voor het web

0

Online wil ik meteen zien of de inhoud van een site of een webpagina de moeite waard is. Ook vind ik het belangrijk dat teksten aantrekkelijk en kort zijn en dat de inhoud scanbaar is. Lezen van een scherm is tenslotte anders dan van papier. Het is lastiger, het kost meer tijd (gemiddeld 25% volgens Jakob Nielsen, 1997) en bovendien ben ik vaak ongeduldig en heb ik weinig tijd. Daarom in deze blogpost een aantal praktische tips die kunnen helpen bij het schrijven van direct scanbare en goed vindbare webteksten.

Tekst is belangrijk

Waarom is tekst op een website eigenlijk belangrijk? Mensen kijken toch liever naar plaatjes en filmpjes? Dat klopt maar gedeeltelijk. Online geldt dat mensen hun informatie vooral zoeken in teksten, grafieken, tabellen, opsommingen enz.. Ook Google doet dat en beloont websites met heldere en kwalitatieve content graag met een hogere ranking. Daarmee is natuurlijk niet gezegd dat filmpjes en plaatjes helemaal geen waarde hebben. Maar als het om informatie gaat zijn teksten nu eenmaal het belangrijkst.
Jakob Nielsen (http://www.useit.com) ontdekte bovendien dat webpagina’s gescand worden in de vorm van een F. Hij zei ook: ‘People rarely read webpages word by word; instead they scan the page, picking out individual words and sentences.’

To the point

Ik heb er een hekel aan als ik eerst door een webpagina moet scrollen en pas onderaan de informatie vind waar het om gaat. Ik vind het handig als ik in één oogopslag zie wat ik van de betreffende pagina kan verwachten. Denk daarom aan Nielsen: zet de belangrijkste inhoud van je tekst altijd bovenaan de pagina en kom meteen ‘to the point’. Begin niet met prietpraat, welkomstwoorden, grapjes, sfeerimpressies, historische achtergronden of met een inleiding waarin je van alles uitlegt. Vertel liever meteen waar het om gaat, val direct met de deur in huis.

De bezoeker centraal

Bezoekers van websites zoeken bijna altijd antwoorden op vragen. Het is daarom belangrijk je te verplaatsen in de doelgroep die een website bezoekt. Je kunt dat doen door zoveel mogelijk vragen van bezoekers te bedenken. Vraag je iedere keer af: is dit waar hij naar op zoek is, vindt hij deze informatie relevant, geeft het een antwoord op de vragen die hij heeft? Stel jezelf dus niet de vraag ‘welke informatie wil ik aanbieden?’, maar vraag je af ‘welke informatie zoekt de doelgroep?’.

Scanbare tekst

Omdat je webteksten niet op dezelfde manier leest als teksten van papier is het belangrijk om er structuur in aan te brengen. Bezoekers scannen een pagina eerst op informatieve trefwoorden voordat ze ‘echt’ gaan lezen. Structuur aanbrengen kan op verschillende manieren, bijvoorbeeld zo:

  • Vermeld de belangrijkste informatie aan het begin van je tekst.
  • Verdeel de tekst in alinea’s die je een duidelijke en informatieve korte titel meegeeft (max. 5 woorden). Aan de titel moet je kunnen zien waar de tekst over gaat.
  • Houd de titel kort en gebruik zelfstandige naamwoorden i.p.v. werkwoorden.
  • Maak per alinea gebruik van tussenkopjes die de inhoud vermelden.
  • Geef sleutelwoorden in de tekst een kleur of maak ze vet.
  • Gebruik opsomminglijsten en bullets: die zorgen voor orde en overzicht.
  • Werk met informatieve hyperlinks die je inhoud meegeeft. Kies nooit voor oplossingen als ‘klik hier’ of ‘download hier’.
  • Onderstreep liever geen woorden of delen van zinnen. De bezoeker associeert die met links.

Beknopte en heldere schrijfstijl

Niemand leest graag saaie, wollige, stroperige, te lange of ingewikkelde zinnen. Online al helemaal niet. Schrijf je webteksten daarom in een vlotte en goed leesbare stijl. De volgende tips kunnen daarbij helpen:

  • Schrijf helder en beknopt in korte zinnen (vuistregel: maximaal 15-20 woorden). Kom meteen ter zake, vermijd lange lappen tekst en gebruik geen betekenisloze woorden en zinnen. Laat jargon en ambtelijke of ouderwetse taal achterwege.
  • Als je wil verwijzen naar uitgebreidere informatie (rapporten, notities, verslagen, brochures, regelingen e.d.) doe dat dan met bijv. een extra pdf die de volledige inhoud bevat en die de lezer kan printen. Plaats als smaakmaker een compacte samenvatting.
  • Spreek in je tekst de bezoeker rechtstreeks en actief aan. Dus niet ‘Hier kun je meer lezen over …’ maar ‘Lees meer over …’ Schrijf actief en begin met onderwerp en gezegde. Liever ‘EU verscherpt maatregelen tegen banken’ dan ‘De maatregelen tegen de banken worden door de EU verscherpt’.
  • Schrijf bij voorkeur in de tegenwoordige of de verleden tijd en vermijd combinaties met een teveel aan hulpwerkwoorden en deelwoorden. Ook de toekomende tijd, onvoltooid of voltooid, is minder geschikt voor teksten op het web.
  • Laat tangconstructies als deze achterwege. ‘Digitale nieuwsbrieven kunnen, mits zij op de juiste wijze worden ingezet door een organisatie, waardevol zijn.’ Beter is ‘Digitale nieuwsbrieven kunnen waardevol zijn. Wel dient een organisatie ze op de juiste wijze in te zetten.’

Informatieve links

Een link geeft beknopt weer wat de inhoud is van de pagina, het document of de website erachter. Gebruik in je tekst bij voorkeur betekenisvolle links die de lezer extra informatie geven. Schrijf ook nooit ‘Klik hier voor meer informatie over Mediaan automatisering (http://www.mediaan.nl)’. Beter is ‘Meer informatie http://www.mediaan.nl’. Mensen weten heus wel dat ze op een link moeten klikken, dat hoef je er niet nog eens apart bij te vermelden!

Opmaak

Als je een goede tekst hebt geschreven is het zonde als die niet prettig leesbaar is. Het is verstandig om daarom ook aandacht te besteden aan de opmaak van je tekst. Hier zijn enkele tips.

  • Onderscheid alinea’s van elkaar door witregels.
  • Benadruk kern- en sleutelwoorden met kleur of maak ze vet.
  • Gebruik bij voorkeur een schreefloze letter zoals bijvoorbeeld Arial, Verdana, Univers of Tahoma.
  • Vermijd cursieve letters: die zijn minder goed leesbaar op een scherm.
  • Gebruik één hooguit twee lettertypes: dat is rustiger en leest fijner.
  • Stem de kleur van tekst en achtergrond op een website op elkaar af. Een goed contrast tussen beide is belangrijk, zonder dat te overdrijven. Een witte tekst tegen een gele achtergrond of donkerblauw op zwart is niet aan te raden (slecht leesbaar). Maar ook een gele tekst tegen een zwarte achtergrond niet (doet pijn aan je ogen).

Samenvatting

Informatie op websites staat vooral in tekst. Ook Google houdt van tekst met waardevolle informatie. Als die bovendien uitstekend leesbaar is en makkelijk te scannen valt, is Google helemaal in zijn nopjes. Het betekent bijna altijd dat je tekst en daarmee ook je website prima vindbaar is. Wil je meer weten? Neem dan vrijblijvend contact op via ons contactformulier, via Twitter (@Mediaan) of Facebook.

Literatuur en bronnen

Schrijven voor het web, Geert Poort, Schouten & Nelissen, Zaltbommel
Schrijfwijzer, Jan Renkema, Sdu Uitgevers, Den Haag
www.frankwatching.com
www.marketingfacts.nl
www.veldmerk.nl
www.onzetaal.nl
www.vandale.nl
www.taaladvies.net

Sociale media wereld

Waarom moeten bedrijven sociale media serieus nemen?

1

Social media is een begrip waar we tegenwoordig niet meer omheen kunnen. In de afgelopen jaren heeft het de samenleving en de bedrijfsvoering aanzienlijk veranderd, en zal dit de komende periode ook nog blijven doen. Sommigen beweren dat sociale media slechts een hype is, maar kunnen we tegenwoordig nog wel spreken over een hype? Wat is sociale media, waarom is het zo populair en wat kunnen we er eigenlijk allemaal mee?

Wat zijn sociale media?

Allereerst is het belangrijk om uit te leggen wat sociale media precies is. Wanneer men het over sociale media heeft wordt er vaak, onterecht, alleen gedacht aan diensten zoals Facebook en Twitter. Wikipedia, wat overigens hét voorbeeld van een populaire sociale media dienst is, omschrijft sociale media als volgt:

“Sociale media is een verzamelbegrip voor online platformen waar de gebruikers, zonder of met minimale tussenkomst van een professionele redactie, de inhoud verzorgen. Er is sprake van interactie en dialoog tussen de gebruikers onderling.”

Facebook en Twitter, maar ook Youtube, LinkedIn en Hyves zijn voorbeelden van populaire online platformen die ook wel sociale netwerken genoemd worden. Ze brengen gebruikers op verschillende manieren samen en laten ze met elkaar communiceren. Daarnaast zijn er ook recentere diensten die sterk op sociale media leunen om hun producten en diensten aan te bieden. Groupon, een website die producten of diensten tegen een gereduceerde prijs aanbiedt als er genoeg kopers zijn, is hier een erg mooi voorbeeld van. Zo zijn er nog talloze voorbeelden op te noemen van diensten die sociale media inzetten, ieder op een eigen manier. Iets wat al deze diensten gemeen hebben is het woord “social”. Dit woord loopt als een rode draad door hun bedrijfsstrategie heen. Waarom is “social” toch opeens zo succesvol en belangrijk?

Sociaal zijn: een hype?

Sociale media diensten brengen gebruikers samen en laten ze verhalen en/of ervaringen op een laagdrempelige manier met elkaar delen. Dat hier behoefte aan is bleek wel toen Facebook de 100 miljoenste gebruiker registreerde 9 maanden nadat de dienst gelanceerd was! Een aardig contrast ten opzichte van de televisie, die er 13 jaar over deed om 50 miljoen gebruikers te krijgen. Het succes achter Facebook wordt gezocht in de eenvoud waarmee mensen informatie kunnen uitwisselen. Die eenvoud heeft ervoor gezorgd dat Facebook vaker bezocht wordt dan Google, en inmiddels meer dan 800 miljoen actieve leden heeft. Dat de diensten populair zijn, staat buiten kijf. Maar is er hier nog sprake van een hype? Tijdens de Mediaan kennisdag Sociale Media in Chateau St. Gerlach (Valkenburg) was de conclusie dat sociale media diensten aanwezig zijn: dwingend en definitief. Hoe komt het toch dat deze diensten zo populair zijn en blijven?

(R)evolutie?

Er zijn twee redenen waarom sociale media zo populair zijn en we eigenlijk niet meer van een hype kunnen spreken. Voor een groot gedeelte heeft dit te maken met de verandering van de samenleving. Generatie Y is een groep van mensen jonger dan 30 jaar die tegenwoordig meer dan 50% van de wereldbevolking vertegenwoordigt. Deze mensen zijn vrijwel allemaal opgegroeid in een digitaal tijdperk, en zijn gewend met veel informatie om zich heen te leven, welke altijd binnen handbereik is. Dit heeft bijvoorbeeld als gevolg dat het nieuwe werken eigenlijk helemaal niet meer zo nieuw is voor deze groep, en dat fysieke communicatie steeds minder belangrijk wordt. Het is dan ook niet geheel toevallig dat 96% van deze mensen zich aangemeld hebben bij een sociaal netwerk. Deze manier van communiceren sluit volledig aan bij de wereld waarin zij zijn opgegroeid en voor deze groep mensen is deze manier van communiceren de standaard geworden. Dit heeft als gevolg dat binnen 10 jaar, wanneer generatie Y is doorgedrongen tot de management lagen van de meeste organisaties, sociale media een grote rol gaat spelen in de bedrijfsvoering.
Naast de veranderingen van de samenleving, zijn er ook vele veranderingen gaande op technologisch vlak. Cloud computing bijvoorbeeld, maar de explosieve toename van het gebruik van sociale netwerken komt voornamelijk door de opmars van mobile devices die verbonden zijn met het internet. Of het hier om een mobiele revolutie of evolutie gaat laten wij in het midden, maar het verandert onze levensstijl aanzienlijk. Alles moet sneller, directer en overal, wat weer precies aansluit op de levensbehoeften van generatie Y.

Strategisch belang

De verschillen tussen de generaties zullen in de komende jaren alleen nog maar toenemen, en daar zullen sociale media een belangrijke rol in spelen. Sociale media is een niet meer weg te denken manier van communiceren met klanten. Het is grenzeloos, snel en open. Het biedt tal van mogelijkheden, maar bevat ook risico’s. Daarom is het voor bedrijven zeer belangrijk om hier goed op in te spelen en dit onderdeel mee te nemen in hun bedrijfsvoering. Met opnemen in de bedrijfsvoering wordt niet alleen bedoeld dat er richtlijnen moeten komen voor het gebruik van sociale media diensten, maar ook hoe je als bedrijf gebruik kan maken van de informatie die nu beschikbaar is. Dit is tegenwoordig mogelijk omdat de conversatie zich verplaatst heeft. De mond-tot-mond “reclame” die vaker tijdens verjaardagspartijtjes verspreid wordt, gaat tegenwoordig steeds vaker via de eerder genoemde sociale netwerken. Dit biedt mogelijkheden voor bedrijven. Sociale media is een nieuw marketing- & communicatiekanaal dat gebruikt kan worden om klanten te benaderen, of ze op een persoonlijke en directe manier verder te helpen. Door als bedrijf actief te zijn op diverse sociale media platformen, leert een bedrijf wat er zoal speelt bij de klanten en heeft het de mogelijkheid om te reageren. Dit is een van de grote krachten van sociale media. Iedereen, dus ook bedrijven, heeft de mogelijkheid om te reageren.

Sociaal zijn moet je leren

Besef wel dat het actief zijn op sociale netwerken voor bedrijven pas interessant wordt als er focus is en er (meetbare) doelen vastgelegd worden. Dit soort afspraken moeten in een strategie opgenomen worden die integraal door de bedrijfsvoering loopt. De uitstraling van een bedrijf via sociale media moet kloppen. Besef ook dat het gebruik van sociale media niet zwart-wit is. Draaiboeken en richtlijnen kunnen helpen, maar leer van je ervaringen en evalueer regelmatig. Ben sociaal, en leer van anderen: vraag om feedback. Alleen op die manier kan sociale media je helpen met het sociaal maken van je bedrijfsvoering.

Deze blogpost richt zich met name op de sterke ontwikkeling en de mogelijkheden van sociale media. Natuurlijk zijn er ook gevaren en richtlijnen waar (voornamelijk) bedrijven goed over moeten nadenken. Mediaan heeft naast een eigen strategie voor diverse klanten frameworks ontwikkeld die omschrijven hoe je het beste als bedrijf sociale media kunt gebruiken (bijv. geschikte kanalen), handhaven (bijv. do’s en dont’s) en beheren (bijv. monitoring). Deze frameworks zijn geschikt voor o.a. webcare, marketing & sales, en social branding activiteiten. Wil je hier meer over weten? Neem dan vrijblijvend contact met ons op. Dit kan via ons contactformulier, of natuurlijk via Twitter (@Mediaan) of Facebook.

project estimation

Een huis bouwen of software ontwikkelen. Een wereld van verschil?

In de IT branche blijkt het schatten van software projecten een hele uitdaging. Veel projecten worden niet binnen afgesproken tijd, budget en tegen afgesproken kwaliteit opgeleverd. Dit kan een groot aantal redenen hebben die niet altijd even gemakkelijk zijn toe te lichten. Er is ook geen eenduidig antwoord op te geven, maar het kan wel anders.

In dit artikel worden een aantal vergelijkingen getrokken tussen het bouwen (en inrichten) van een huis en het ontwikkelen van software. Hierbij worden een aantal problemen duidelijk die in andere soorten projecten minder of niet van toepassing zijn. Er zijn echter wel oplossingen welke in de praktijk nog altijd niet, of niet met de juist reden, worden gebruikt.

Software projecten zijn complex

Er zijn veel soorten en maten projecten en er komen veel aspecten bij kijken om een project in te schatten. De schattingen van kosten, hoeveelheid werk en kwaliteit van de op te leveren producten zijn meestal de definitie voor het afronden van een succesvol project. Niet alleen ziet ieder project en de daarbij betrokken organisatiestructuren en procesinrichting er anders uit, het inschatten van de omvang van de te bouwen applicatie zelf is vaak al een hele uitdaging.

Waarom is het schatten van software projecten zo lastig?

Bij het bouwen van een huis kunnen de kosten toch ook goed ingeschat worden?

Schatten met materialen en producten

Het verschil zit in een aantal dingen. Kostenschattingen van bouwprojecten zijn grotendeels gebaseerd op materialen en producten. Als duidelijk is hoe een gebouw ongeveer uit moet zien op welke bouwgrond, dan kunnen de te gebruiken materialen, de hoeveelheid, en de kwaliteit ervan bepaald worden. Het aantal vierkante meters en de inhoud van ruimtes is makkelijk te berekenen. Voeg hierbij een aantal redelijk goed in te schatten activiteiten aan toe, zoals het assembleren en installeren van de materialen, en het totale kostenplaatje is grotendeels af. Veel risico’s, zoals wegzakkende grond, kunnen van tevoren geanalyseerd worden waardoor ook hier maatregelen tegen getroffen kunnen worden. Enkel de afhankelijkheden van verschillende aannemers en volgorde van activiteiten kan nog een onzekerheid in de doorlooptijd van het bouwproject introduceren. Over het algemeen kunnen nauwkeurige schattingen gemaakt worden van de kosten en doorlooptijden.

Schatten met taken en activiteiten

Software projecten worden in de praktijk vaak anders geschat. Schattingen en planningen zijn vaak gebaseerd op werkpakketten en daarbij horende taken en activiteiten, in plaats van materialen en wat opgeleverd gaat worden. Kosten worden vaak gebaseerd op de nodige inspanning welke ingeschat wordt op deze activiteiten, uitgedrukt in aantal mandagen. Er wordt ingeschat hoeveel uren werk het ontwerpen, realiseren en testen in beslag nemen. Daarbij worden vaak nog schattingen gemaakt van de uren die nodig zijn voor documentatie, rapportages, projectmanagement, installatie etc. Dit schatten gebeurt in meer dan 90% van de projecten op basis van ervaring en gevoel. Omdat niet duidelijk is wat de echte omvang is van de te realiseren software kunnen er geen eenduidige antwoorden gegeven worden op de kosten en doorlooptijden hiervan. Er is geen eenheid die aangeeft hoeveel vierkante meter een softwareapplicatie is, toch?

Een eenduidige maat voor de omvang van software

Als sinds de eerste regels programmeercode worden geschreven zijn er manieren bedacht om iets te zeggen over de orde en grootte van software. Er werd toen bijvoorbeeld gerekend met het aantal regels code (Source Lines of Code), maar dit bleek al snel zijn beperkingen te hebben door de grote variëteit aan programmeertalen en doordat er een slecht verband is tussen het aantal regels code en de functionele werking ervan. Later werden er Functional Size Measurement (FSM) methodes bedacht. In plaats van te kijken naar technische eigenschappen van de programmatuur worden met deze methodes enkel functionaliteiten bekeken. De omvang van functionaliteiten, zoals de oppervlakte van een kavel of inhoud van een gebouw, wordt dan uitgedrukt in Functiepunten (FP). Dit zijn de producten of materialen die daadwerkelijk gebouwd of gemaakt worden bij het bouwen van een huis. Maar wat zijn de functionaliteiten dan van een softwareapplicatie?

Afspraken over resultaten

Functionaliteiten van een softwareapplicatie zijn vaak abstract en niet tastbaar, ook voor de opdrachtgever zelf. Er is behoefte aan een applicatie die een bepaald probleem moet oplossen of een bedrijfsproces moet ondersteunen. Hoe dit precies uitziet is vaak niet helemaal duidelijk. Het volledig uitwerken van de functionaliteiten die met de software mogelijk moet zijn is een langdurig proces. Waar je bij een gebouw relatief eenvoudig kunt zeggen welke muren, ramen en deuren er gezet moeten worden en via welke gangen je ergens terecht kunt komen, weet je bij software meestal niet welke schermen, knoppen en navigatie je wilt hebben. Vaak kan dit met software ook op 100en verschillende manieren opgelost worden, waar je bij een gebouw een stuk minder mogelijkheden hebt. Ook is de impact van het plaatsen van een deur of muur op het gebruik daarvan veel duidelijker dan de impact van keuzes in softwareoplossingen op de bedrijfsprocessen en gebruikers van de systemen. Toch moeten de functionaliteiten van een softwareapplicatie in zekere mate duidelijk zijn bij de start van een project, want waarover maak je anders afspraken?

Overeenkomsten op basis van nacalculatie geven vaak, wanneer het erop aan komt, geen garantie op de invulling daarvan. Hierdoor hangt de samenwerking nauw samen met het vertrouwen in de andere partij. Controle op uitgaven en budgetten is er vaak niet, er kan enkel afgeknepen worden als de limieten zijn bereikt. Liefst wil je de leverancier een meetbare resultaatverplichting aan laten gaan. Pas als er een huis is met woonkamer, slaapkamer, keuken en alle daarbij horende aansluiting voor gas, water, elektriciteit etc. is het project opgeleverd en wilt de opdrachtgever betalen voor hetgeen dat is opgeleverd.

Wanneer vanuit het gebruikersperspectief wordt gekeken naar een softwareapplicatie is het mogelijk om functionaliteiten te benoemen op een vaste en te controleren manier. FSM methodes zijn ISO gecertificeerd en er zijn richtlijnen opgesteld, zoals de Nesma Functiepunt telrichtlijnen. Door unieke functionaliteiten te benoemen en te tellen wordt het mogelijk om iets te zeggen over de omvang van een applicatie. Zoals een architect of aannemer al een idee krijgt bij de omvang en kosten van een huis zodra de volumes en oppervlaktes bekend zijn, zo kan een IT projectmanager of software ontwikkelaar een idee krijgen van de omvang, kosten en doorlooptijd zodra deze functionele omvang in FP bekend is.

Omvang bepalen is geen moeite

Traditioneel werden IT projecten op een watervalmethode aangepakt, en zo worden projecten nog steeds vaak uitgevoerd. Pas als de ontwerpfase 100% gereed is wordt aan de realisatiefase begonnen. De ontwerpfase, waarin de functionele omvang bekend wordt in uitgebreide ontwerpen, is hierbij vaak een langdurig proces. Bedrijven en processen veranderen en vaak wijzigen de wensen en eisen aan het ontwerp van de software dan ook tijdens het opstellen van het ontwerp. Een groot gebouw waarbij de ontwerpfase een jaar duurt hoeft geen probleem te zijn want de wensen en eisen hiervan zijn statischer. Er moet in softwareprojecten dus een balans gevonden worden tussen het detailniveau van de ontwerpen en de doorlooptijd van het opstellen van de ontwerpen. Er zijn verschillende detailleringen mogelijk van de functiepunttellingen welke ieder een bepaalde nauwkeurigheid hebben. Het is mogelijk om in een fractie van de ontwerptijd, in enkele dagen of zelfs uren, al een indruk te krijgen van de functionele omvang van grote applicaties. De verdere detaillering die nodig is voor de realisatie van de functionaliteiten kan later plaatsvinden.

Andere aspecten zoals kwaliteit en afwerking

Net zoals er met het aantal vierkante meters gerekend kan worden bij het bouwen van een huis, kan er gerekend worden met het aantal functiepunten van software. Er kunnen in een woonkamer van 45m2 nog altijd mooie marmeren vloertegels gelegd worden, of een praktisch klik-laminaat. Op dezelfde manier kan van een rapportagefunctionaliteit van 20FP de gebruikersinterface en rapporten er grafisch mooi en afgewerkt uitzien, of voldoende om te functioneren en enkel de data weer te geven. Ook kan de garage van het huis een plat dak hebben zodat er nog een verdieping op kan komen, net zoals software gebouwd kan worden met uitbreidbaarheid in het achterhoofd. De omvang is in beide gevallen duidelijk, de hoeveelheid werk en de kosten kunnen nog variëren op basis van de keuzes die gemaakt worden. Als opdrachtgever weet je in ieder geval dat je ermee kunt wat nodig is. De afwerkopties in softwareprojecten zijn nog altijd lastiger te communiceren dan in bouwprojecten, mede doordat software veel abstracter en minder tastbaar is, maar door de omvang inzichtelijk en meetbaar te maken kunnen veel problemen met projectschattingen en daaruit volgende afspraken en overeenkomsten, aangepakt worden.

Afspraken over resultaat, kosten, kwaliteit en productiviteit transparant en bespreekbaar

Wanneer de functionele omvang van softwareapplicaties bekend is kunnen op basis hiervan afspraken gemaakt worden over de andere aspecten. Het is voor alle betrokkenen duidelijk welk resultaat verwacht wordt. Hoe snel en productief een leverancier is, maakt in principe niet meer uit voor de opdrachtgever, dat is iets waar de leverancier zich mee bezig mag gaan houden. De kwaliteit van de leverancier zijn werk en de snelheid waarmee hij dit doet wordt ineens een stuk transparanter. De oorzaken van grote (prijs)verschillen tussen leveranciers kunnen verklaard worden. Het is zichtbaar wanneer een leverancier minder, of andere, functionaliteiten zal realiseren. Ook zijn afspraken over de kwaliteit en afwerking van de producten apart bespreekbaar gemaakt.

Schatten blijft lastig

Met deze aanpak, waarbij de omvang van een softwareproject duidelijk vast te stellen is, zijn de verschillen met het bouwen van een huis een stuk kleiner. Feit blijft echter dat het schatten van softwareprojecten nog altijd een lastige opdracht is door de andere dynamiek in softwareprojecten. Ook is de in dit artikel voorgestelde functiepuntmethode geen oplossing voor alle problemen die gerelateerd zijn aan projectschattingen. Het (beginnen) introduceren van functiepunten heeft in onze ervaring echter wel een groot aantal voordelen waar alle betrokken partijen iets aan hebben.

Mediaan heeft al meer dan 25 jaar ervaring met projectschattingen op basis van functiepunten. We maken de op te leveren producten transparant waardoor we projecten fixed-price en fixed-date uit kunnen voeren. Ook bieden we onze opdrachtgevers de mogelijkheid tot het volgen van cursussen om de functiepuntmethode binnen enkele uren te leren begrijpen en toe te passen in projecten. Mediaan voert als onafhankelijke partij ook controle-tellingen uit in andere projecten van opdrachtgevers. Neem contact met ons op voor meer informatie.

Blog

Mediaan gaat bloggen!

Hallo! Wij zijn Mediaan.
Omdat wij trots zijn op wat wij doen, gaan we een weblog bijhouden. Op deze blog zullen we toelichting geven op allerlei onderwerpen waar wij, maar jullie waarschijnlijk ook, dagelijks mee te maken hebben. Dat zijn bijvoorbeeld deze onderwerpen:

Web development State of the art webtechnieken zoals HTML5 en jQuery plugins zullen de revue passeren. Gebruikersvriendelijkheid is voor jullie erg belangrijk, dus ook voor ons!
Mobile development Ook benieuwd naar hoe wij onze Apps voor Android, iOS en Windows Phone ontwikkelen? Blijf ons dan vooral volgen.
.NET development Moderne programmeertalen waar de afgelopen tijd veel ontwikkelingen hebben plaatsgevonden. Hoe kijken onze ontwikkelaars hier tegenaan, en wat zijn de praktische voordelen?
Java en Oracle development Wij hebben meer dan 25 jaar ervaring met de producten van Oracle, met medewerkers die deze ontwikkelingen nog steeds op de voet volgen.
Business Intelligence Meer informatie en controle over je organisatie of systemen betekent meer data die verwerkt en georganiseerd moet worden. Met Business Intelligence tools gaat dit op een ontzettend krachtige manier.
Cloud development Wat voor een impact heeft het als je een applicatie voor de cloud wil ontwikkelen? Waarom en wanneer wel, of juist niet naar de cloud?
Social Media Benieuwd hoe wij als bedrijf tegen het gebruik van social media aankijken? Deze blog is hier een voorbeeld van. Strategieën, webcare, marketing & sales zijn voor ons geen nieuwe begrippen.
Marketing Mediaan doet meer dan alleen automatisering. We zijn ook een communicatiebedrijf dat zich al 40 jaar bezig houdt met o.a. het adviseren, ontwerpen, schrijven en produceren van flyers, teksten en (jaar)verslagen van bedrijven.
IT Projecten Benieuwd hoe wij (mega) projecten aanpakken en transparant maken? Hoe wij de slogan ‘fixed-price en fixed-date’ waar kunnen maken?
Om de twee weken zullen we een bericht plaatsen over een van deze onderwerpen, zodat jullie goed op de hoogte zijn van wie wij zijn en wat we doen. Als jullie vragen hebben, kunnen jullie die natuurlijk gewoon stellen! Dit kan via deze blog in de reacties, via het contactformulier, via twitter (@mediaan) of zelfs via Facebook.

Wat we precies doen zal de komende tijd duidelijk worden uit de blog posts, maar hieronder staat nog eens een korte samenvatting van onze hoofdactiviteiten:

We zijn internationaal actief in (mega) ICT projecten, voeren de regie in projecten en programma’s, geven advies over het veranderen bedrijfsvoering, ontwikkelen software, beheren applicaties en verzorgen (data) migraties. Onze specialiteiten liggen in de Telecom, Onderwijs en Pensioenen en Verzekeringen sectoren.

Wij maken IT projecten transparant en beheersbaar en durven dat fixed-price en fixed-date te doen. Wij weten dat het kan, want wij doen dit al meer dan 25 jaar.

Mediaan bestaat uit Mediaan/abs (Nederland), Mediaan Communicatie (Nederland) en MediaanABS (Duitsland). Informatie over onze producten, diensten en activiteiten zijn o.a. te vinden op LinkedIntwitter (@mediaan)Facebook en onze website.

Naar boven