JSF cursus deel 1 oefeningen JSF Basics en Facelets in samenwerking met HowITsDone
Oefening 1 bestudeer de applicatie facelet template & /pages01/person/ Java code: handler01: PersonHandler domeinobject: Persoon service: PersonService + MockImpl web.xml faces config
Domein bean Drie benaderingen: gebruik de bean direct in je pagina injecteer de bean in je handler manage de bean zelf in je handler
Oefening 2 voeg zoekfunctie op bsn toe Tips: gebruik de juiste finder methode in de personService realiseer je dat het bestaande sessie Persoon object niet wordt vervangen door het gevonden Persoon object
Oplossing oefening 2 probleem: pagina moet gevonden Persoon object gaan gebruiken oplossing 1: gebruik #{handler.bean.property} in plaats van #{bean.property} oplossing 2 (niet uitgewerkt): plaats de bean zelf in sessie: FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(“persoon”, mijnGevondenPersoon);
Oplossing oefening 2 (2) probleem: Persoon object dat bewaard wordt is dezelfde instance als zoek object oplossing 1: verwijder injectie Persoon object en maak elke keer een nieuwe aan oplossing 2 (niet uitgewerkt): gebruik een apart zoekveld in de handler oplossing 3 (niet uitgewerkt): injecteer een request Persoon object
Bean oefening 2
dataTable
dataTable data binding value attribute Object (niet zo zinvol) array java.util.List java.sql.ResultSet javax.servlet.jsp.jstl.sql.Result javax.faces.model.DataModel var attribute hiermee kun je huidige row aanspreken
dataTable styling columnClasses rowClasses comma separated style classes per kolom rowClasses comma separated style classes per rij headerClass, geldt voor alle headers footerClass, geldt voor alle footers <h:column> specifiek headerClass footerClass
Oefening 3 voeg zoekfunctie op achternaam toe Tips: hoofdletter onafhankelijk ‘starting with’ (suggest) Tips: gebruik <h:dataTable> om de zoekresultaten te tonen gebruik de juiste finder methode in de personService
Pagina oefening 3
Bean oefening 3
DataTable select row gebruik DataModel in plaats van List model.setWrappedData( list data ) row object = model.getRowData() plaats handler in sessie scope om dit te laten werken
Oefening 4 selecteer een persoon uit de dataTable Tips: gebruik ListDataModel in plaats van List maak de cellen clickable met <h:commandLink> houd een selected persoon bij let op de scope van de handler (request is een probleem)
Bean oefening 4
Pagina oefening 4
DataTable sorteren geen support out of the box niet moeilijk zelf te schrijven Tomahawk heeft support RichFaces ook
Oefening 5 sorteer op kolom Tips: keep it simple: commandLink in kolom header besteed sortering uit aan service die dan kan besluiten de DB in te schakelen maar houd de service stateless dus geef sorteerrichting (ascending, descending) mee
Bean oefening 5
Pagina oefening 5
Verwijder row geen support out of the box niet moeilijk zelf te schrijven meeste oplossingen vervuilen domein object met boolean veld extend ListDataModel is een nette oplossing
Oefening 6 verwijder een persoon uit de dataTable Tips: gebruik h:selectBooleanCheckbox gebruik ListDataModelExt
Pagina oefening 6
Bean oefening 6
ListDataModelExt
ListDataModelExt (2)
ListDataModelExt (3)
Dropdown list list data door middel van: <f:selectItem itemValue=.. itemLabel=../> child tags of: array/ List van SelectItem objecten er is ook een itemDisabled attribute/property Belast de database niet onnodig: cache de statische lijstjes, bijvoorbeeld met static Let dan wel op de getter: geen static methode!
Oefening 7 introduceer dropdown list bij man/vrouw keuze (alleen bij het invulscherm) Tips: gebruik h:selectOneListbox
Bean oefening 7
Pagina oefening 7
Internationalization (i18n) aantal aandachtspunten: zet locale in faces config gebruik alleen tekst uit properties file of een ander schakelmechanisme voorkom zomertijd/ wintertijd problemen door het zetten van timeZone: <f:convertDateTime type="date" pattern="dd-MM-yyyy" timeZone="GMT+1"/> gebruik altijd itemValue en itemLabel bij SelectItem waarbij value taalneutraal is
Oefening 8 I18n: zorg dat de man/vrouw keuze rekening houdt met de taal (current locale) Tips: gebruik WebUtil.getMessage( key)
Bean oefening 8
Facelet functions wrapper om een static methode aan te roepen met #{ns-prefix:functienaam ( argument1, argument2) } argumenten kunnen literals zijn maar ook variabelen: #{howitsdone:showMessage( ‘hallo’) } #{howitsdone:showObject( persoon) }
Oefening 9 I18n: zorg dat de man/vrouw keuze in de dataTable ook rekening houdt met de taal (current locale) Tips: gebruik facelet functie #{howitsdone:getMessage( key)}
Pagina oefening 9
Taglib facelet function
Facelet tags normale tag syntax: aparte file, bijvoorbeeld date.xhtml: <ns-prefix:tagnaam/> attributen zijn mogelijk maar impliciet <howitsdone:date days=…/> aparte file, bijvoorbeeld date.xhtml: <ui:composition> <… #{days} …/> </ui:composition>
Facelet tags (2) action bindings kun je NIET overdragen truc: bean en action apart overdragen: <howitsdone:link bean=… action=… label=…/> <ui:composition> <h:commandLink action=“#{bean[action]}” value=“#{label}”/> … </ui:composition>
Oefening 10 Zorg dat het invoeren van de geboortedatum via drie dropdown lijstjes gebeurt: dag, maand, jaar Tips: gebruik facelet tag <howitsdone:date>
Pagina oefening 10
Tag date
Taglib facelet tag
Bean oefening 10
Bean oefening 10 (2)
Bean oefening 10 (3)
Bean oefening 10 (4)
Bean oefening 10 (5)
Validatie pagina attributen op <h:inputXXX en <h:selectXXX required=“true” requiredMessage=“#{…}” validator=“#{method expression}” child tags in <h:inputXXX en <h:selectXXX <f:validateLength> <f:validateLongRange>,<f:validateDoubleRange> schrijf je eigen validator <f:validator validatorId=“ gebruik een validator van bijv. Tomahawk <t:validateRegExpr pattern="[1-9]{1}[0-9]{3}\s?[a-zA-Z]{2}"/>
Validatie (2) JSF validatie fase (fase 3) zogauw er een veld invalide is bevonden gaat lifecycle door naar fase 6 m.a.w. je komt nooit bij je action methodes in onze oefeningen werkt daardoor de zoekfunctionaliteit niet meer oplossing 1: immediate=true op commandButton, maar… zoekwaarde is niet overgezet (fase 4) dus werkt niet oplossing 2: validatie in code
Validatie (3) code zelf schrijven in action/actionListener methode zie ook WebUtil.java voor helpers
Meldingen tonen javax.faces.application.FacesMessage severity: fatal, error, warn, info summary & detail global of gebonden aan component facesContext.addMessage(null, facesMessage) facesContext.addMessage(“mainform:lastname”, facesMessage) alle meldingen: <h:messages> alleen de summary (default) ook de detail meldingen: showDetail=“true” melding per component: <h:message for=
Oefening 11 Zorg dat voornaam, achternaam en geslacht verplichte velden worden Zorg dat bsn groter dan 0 is Tips: gebruik required en validateLongRange bekijk de meldingen die het template via <h:messages> toont zorg dat de meldingen gebruikersvriendelijker worden
Oefening 12 Zorg dat geboortedatum gevuld is Tips: check de drie waardes in de handler: save() extra: check ook of de datum echt klopt, bijvoorbeeld accepteer geen 30 feb eventueel: plaats validatie in het domein object en roep het aan vanuit de service in plaats van de handler; voordeel is dat validatie ook plaatsvindt als je niet via JSF binnenkomt (tip: JValidate framework)
Oefening 13 Maak een eigen validator om te testen of het bsn nummer een geldig sofinummer is