Backward compatible AJAX ontwikkeling met Wicket

8 January 2007 11:01 Erik van Oosten AJAX, Java

Ondanks dat AJAX nu algemeen geaccepteerd lijkt is men in sommige sectoren nog terughoudend. De rijke interactie die AJAX brengt gaat namelijk voorbij aan mensen die vanwege hun handicap een browser gebruiken welke geen Javascript of CSS ondersteund. Voor een sector als de overheid is het niet acceptabel om deze mensen uit te sluiten en eigenlijk zou dit standpunt algemeen ingenomen moeten worden.

Op dit moment zijn er veel ontwikkelaars die web applicaties alleen voor Internet Explorer kunnen of willen maken. Een AJAX website bouwen welke ook werkt zonder Javascript is dan ook te veel gevraagd voor de meeste bedrijven. Om dit toch voor elkaar te krijgen zijn inmiddels een aantal technieken bekend. Een algemene aanpak is Unobtrusive Javascript, maar in dit artikel wordt een andere, iets flexibelere aanpak behandeld welke gebruik maakt van Wicket.

(Also published in English.)
(On la aussi publié a Français.)

Wicket is een van de weinige volledig component gebaseerde web frameworks. In een dergelijk web framework kun je componenten combineren tot grotere componenten en zo een web pagina samenstellen. Het voordeel van componenten is dat het gemakkelijk is om afzonderlijke componenten te ontwikkelen en wijzigingen. Met pagina gerichte frameworks moet je meestal de hele pagina tegelijk ontwikkelen. Struts schrijft bijvoorbeeld voor dat eerst alle informatie voor de gehele pagina word verzamelt voordat een JSP pagina de rendering van de (gehele) pagina voor zijn rekening neemt.

Wicket componenten samenstellen (een Wicket introductie)

In Wicket stel je een component samen door een HTML fragment (de template) te schrijven en daar aan de Java kant een component aan te koppelen. Het samenstellen van componenten en het koppelen aan HTML gebeurd tijdens de constructie fase. Tijdens de render fase kan de component de gekoppelde template aanvullen, aanpassen of zelfs compleet vervangen.

Laten we kijken naar een voorbeeld. Hier is een HTML template en de bijbehorende Java code:

_Template titel

add(new Label("titel", "De echte titel"));

Het Label component wordt hier aan een h1 element gekoppeld. Label zal tijdens de render fase de echte titel in de HTML template zetten. Het resultaat is:

De echte titel

Samenstellen van componenten is net zo eenvoudig. Stel dat we de titel samen met een subtitel op vele plaatsen willen gebruiken. We maken daarvoor een component, een Panel om precies te zijn:


    

_Template titel

_Template subtitel

class TitelPanel extends Panel {
      public TitelPanel(String id, String titel, String subtitel) {
          super(id);
          add(new Label("titel", titel));
          add(new Label("subtitel", subtitel));
     }
}

Het panel kun je nu (bijvoorbeeld in de template van een ander panel) gebruiken met:

add(new TitelPanel(
    "titelpanel", "De echte titel", "met een subtitel"));

Linken tussen pagina’s doe je met de Link component:

Boek details
add(new Link("detaillink") {
      void onClick() {
           setResponsePage(new DetailPage(boekId));
      }
});

De Link component zet tijdens de render fase een door Wicket gegenereerd href attribuut op het a element. Indien op de link wordt geklikt zal de Wicket servlet de onClick van de link uitvoeren. In dit voorbeeld wordt de response pagina gewijzigd in een ter plekke geconstrueerde pagina (pagina’s zijn uiteraard ook componenten). Hierna wordt de response pagina gerenderd en naar de browser gestuurd. Als je onClick methode leeg laat, zou de response pagina niet veranderen en wordt de huidige pagina opnieuw gerenderd.

Dynamische pagina’s in Wicket

Links zijn niet alleen handig om naar een andere pagina te springen. In Wicket is het net zo gemakkelijk om een gedeelte van de pagina aan te passen door een component te vervangen met een andere. We breiden het voorbeeld een klein beetje uit:

final BoekDetailPanel boekDetailPanel = ...;
add(boekDetailPanel);
add(new Link("detaillink") {
    void onClick() {
        boekDetailPanel.replaceWith(new BoekDetailPanel(boekId));
    }
});

Het aanklikken van de link heeft tot gevolg dat de huidige pagina wordt aangepast. Hierna wordt de huidige pagina opnieuw gerenderd en wordt een ander boek getoond. Merk op dat er bijzonder weinig code nodig is. In veel andere web frameworks zou alle informatie van de volledige pagina opnieuw moeten worden verzameld.

De oplettende lezer zal merken dat het vervangen van een stuk van een pagina een truc is waar tegenwoordig AJAX veel voor wordt ingezet. In het voorbeeld is er echter geen regel Javascript aan te pas gekomen. Het is echter wel jammer dat de gehele pagina opnieuw naar de browser gestuurd moet worden. We gaan daarom het voorbeeld verder aanpassen:

final Component boekDetailPanel = ...;
boekDetailPanel.setOutputMarkupId(true);
add(boekDetailPanel);
add(new AjaxFallbackLink("detaillink") {
    void onClick(AjaxRequestTarget target) {
        Component nieuwBoekDetailPanel = new BoekDetailPanel(boekId);
        nieuwBoekDetailPanel.setOutputMarkupId(true);
        boekDetailPanel.replaceWith(nieuwBoekDetailPanel);
        if (target != null) {
            target.addComponent(nieuwBoekDetailPanel);
        }
    }
});

Het component AjaxFallbackLink genereert tijdens de render fase zowel een href als een onclick attribuut op het gekoppelde a element. Daarnaast zorgt het ervoor dat een aantal Wicket Javascript files aan de HTML header worden toegevoegd.
Afhankelijk van of Javascript wordt ondersteund zal de browser een normale URL opvragen of een AJAX call doen. In beide gevallen roept de Wicket servlet de method onClick aan. In het eerste geval is het argument van onClick null en werkt alles precies hetzelfde als in het vorige voorbeeld. Wordt echter een AJAX call gedaan, dan zal Wicket alleen de componenten die aan de AjaxRequestTarget zijn toegevoegd renderen en naar de browser sturen. De Javascript code van Wicket zoekt het te vervangen element op met zijn id attribuut. Om te zorgen dat dit attribuut gezet wordt setOutputMarkupId(true) aangeroepen.

Met een paar regels code hebben we een AJAX applicatie gemaakt welke ook nog gewoon werkt in browsers zonder Javascript.

Conclusie

Dit artikel toont maar een klein stukje van de AJAX mogelijkheden van Wicket. Het is bijvoorbeeld eenvoudig om te laten zien dat er een AJAX call bezig is, om voor de AJAX call nog even snel wat Javascript op de client uit te voeren (bijvoorbeeld de submit knop uitzetten) en om bij het veranderen van een form invoer veld snel even een validatie uit te voeren op de server.

Wicket is niet alleen een fantastisch framework om gemakkelijk onderhoudbare en moderne web applicaties mee te maken, het is ook nog eens mogelijk om dat zo te doen dat oudere en speciale browsers er goed mee overweg kunnen.

Be Sociable, Share!

1 reactie »

  1. Leerzaam stukje, bedankt!

    ReinoutS July 31, 2008 17:04

Reageer


5 − vijf =

RSS feed for comments on this post · TrackBack URI