FAM 4.0 - Validació
1. Validació de formularis
Recordatori del cicle de vida o fases d'una pàgina JSF:
- Restore View
- Apply Request Values
- Process Validations. Si detecta errors es passa directament a la fase 6
- Update Model Values
- Invoke Application
- Render response
Les tasques de validació (fase 3) es fan abans que l'execució del codi de negoci (fases 4 i 5). En aquelles situacions que no es supera la validació s'obté un millora del rendiment. La validació de formularis es farà aprofitant l'estàndar JSR-303.
La llibreria OmniFaces ofereix eines per estalviar tasques repetitives:
- <o:highlight styleClass="has-error" focus="true" /> per aplicar la classe CSS d'error als camps que no superen la validació
- <o:outputLabel> per facilitar la composició dels missatges d'error amb el valor de la etiqueta que apareix a la vista/formulari
- <o:validateMultiple> per validar grups de camps relacionats entre ells
Els missatges d'error es troben a l'arxiu cat.diba.jee.core.faces.Messages_ca.properties
Un factor important és l'actualització de les parts del DOM que ens interessa, ja que la gran majoria seran peticions Ajax. Això s'aconsegueix mitjançant l'atribut update
d'alguns components. Com a norma general sempre s'actualitzarà el component amb l'id messages
que permet la visualització d'avisos (info, error, perill, ...). D'altres exemples d'update
- Crida per obrir un dialeg de PrimeFaces i actualitzar els elements del DOM corresponents al tancar-lo:
<p:ajax event="dialogReturn" listener="#{ubicacioBB.onAreaChosen}" update="messages areaId areaId_hidden" />
- Acció d'enviar el formulari i actualitzar parcialment el DOM:
<p:commandLink action="#{ubicacioBB.saveOrUpdate}" id="save" ajax="true" styleClass="btn btn-default" type="submit" update="@form messages">
<i class="fa fa-save" aria-hidden="true" />
#{literalsCore['Helper.Save']}
</p:commandLink>
2. Escenari 1: validació de camps obligatoris
És el cas més senzill. S'utilitza <o:outputLabel> i l'atribut required="true"
al camp d'entrada. L'avantatge d'aquesta etiqueta és que aprofita el valor del camp referenciat com a valor pels missatges d'error.
Exemple: per defecte, el missatge d'error és form_id:field_i és un camp obligatori
, però amb aquest component l'error queda com (segons l'exemple que apareix desprès) Nom és un camp obligatori.
<form> <o:outputLabel for="nomUbicacio" value="#{literalsAplicacio['Ubicacio.Nom']}" styleClass="control-label col-sm-1 text-left" /> <div class="col-sm-3"> <h:inputText value="#{ubicacioBB.detailEntity.famUbiNom}" id="nomUbicacio" styleClass="form-control" required="true" /> </div> </form> <o:highlight styleClass="has-error" focus="true" />
3. Escenari 2: validació de camps obligatoris amb disabled='true'
Aquest cas es presenta quan el camp s'informa a partir d'un dialeg o depen d'un altre camp.
<div class="form-group #{ areaNom.valid ? '' : 'has-error'}"> <o:outputLabel for="areaId_hidden" value="#{literalsAplicacio['Ubicacio.Area']}" styleClass="control-label col-sm-1 text-left" /> <div class="col-sm-3"> <div class="input-group"> <h:inputText id="areaId" styleClass="form-control" value="#{ubicacioBB.detailEntity.famArea != null ? ubicacioBB.detailEntity.famArea.famAreNom : ''}" disabled="true" /> <!-- http://stackoverflow.com/questions/29490141/validation-disabled-pinputte... --> <h:inputHidden id="areaId_hidden" required="true" binding="#{areaNom}" value="#{ubicacioBB.detailEntity.famArea != null ? ubicacioBB.detailEntity.famArea.famAreNom : ''}" /> <div class="input-group-addon"> <p:commandLink actionListener="#{areaBB.chooseArea}" immediate="true" ajax="true"> <i class="fa fa-search" aria-hidden="true" /> <p:ajax event="dialogReturn" listener="#{ubicacioBB.onAreaChosen}" update="messages areaId areaId_hidden" /> </p:commandLink> </div> </div> </div> </div>