Archivi tag: JSF

JSF2 SelectOneRadio e DataTable

Spesso capita di dover utilizzare in una colonna di una DataTable i radiobutton. Ovviamente non appartenendo allo stesso container (essendo contenuti uno in ogni cella diversa), non sono raggruppabili, e, in html, agiscono come entità separate e svincolate.

Utilizzando le Java Server Faces, ci vengono in aiuto i valueChangeListeners.

Innanzitutto, mettiamo il selectoneradio nella datatable, impostando come listener un metodo sul nostro backingBean.

1
2
3
4
5
6
7
8
<h:dataTable value="#{bean.elementi}" var="elemento">
  <h:column>
    <f:facet name="header">Seleziona:</f:facet>
      <h:selectOneRadio id="radioSeleziona" value="#{bean.selezione}" valueChangeListener="#{bean.doSeleziona}" onclick="dataTableSelectRadio(this);">
        <f:selectItem itemValue="#{elemento.id}"></f:selectItem>
      </h:selectOneRadio>
  </h:column>
</h:dataTable>

Non essendo un radioButton multiplo (non è un insieme), per deselezionare gli altri radioButton quando si clicca su quello scelto,utilizziamo una funzione javascript agganciata nell’evento onclick.

1
2
3
4
5
6
7
8
9
10
11
12
  <h:outputScript library="js">
    function dataTableSelectRadio(radio) {
       var id = radio.name.substring(radio.name.lastIndexOf(':'));
       var element = radio.form.elements;
       for (var i = 0; i < element.length; i++) {
         if (element[i].name.substring(element[i].name.lastIndexOf(':')) == id) {
           element[i].checked = false;
         } 
       }
       radio.checked = true;
    }
  </h:outputScript>

Sul nostro backingBean poi , andiamo ad implementare il ValueChangeListener:

1
2
3
4
  public void doSeleziona(ValueChangeEvent event){
    elementoSelezionato= (String)event.getNewValue();
    internalDoQualcosa();
  }

Ovviamente potete sostituire lo script javascript con qualcosa di piu semplice utilizzando JQuery, ma la sostanza rimane questa.

Check Utente Loggato in JSF2 tramite PhaseListener

Verificare che vi siano determinate condizioni, affinche sia possibile mostrare pagine della nostra webapp realizzata tramite jsf, è relativamente facile.
Normalmente è bene verificare lo stato dell’autenticazione, tramite un servlet filter, in grado di processare tutte le risorse.
In questo esempio realizzeremo invece un listener JSF in ascolto sulla fase di RESTORE_VIEW.

Non essendo possibile effettuare operazioni di CDI sui listener prima della versione 2.2, al posto dell’injection delle classi necessarie, utilizziamo delle espressioni EL per ottenere ad esempio il controllerBean di sessione in cui è mantenuta la classe utente dopo l’autenticazione.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class UserLoggedPhaseListener implements PhaseListener{

    /**
     *
     */

    private static final long serialVersionUID = -2062847364596874153L;

    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
     */

    @Override
    public void afterPhase(PhaseEvent event) {
       
        FacesContext facesContext = event.getFacesContext();
        String currentPage = facesContext.getViewRoot().getViewId();
         
        boolean isLoginPage = currentPage.lastIndexOf("login.xhtml")>-1;
        if (isLoginPage) return;
       
        AuthController auth = facesContext.getApplication().evaluateExpressionGet(facesContext, "#{auth}", AuthController.class);
        if (auth==null || auth.getUser()==null){
            NavigationHandler nh = facesContext.getApplication().getNavigationHandler();
            nh.handleNavigation(facesContext, null, "LOGOUT");
        }
         
    }

    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
     */

    @Override
    public void beforePhase(PhaseEvent arg0) {
       
    }
   
   
    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#getPhaseId()
     */

    @Override
    public PhaseId getPhaseId() {
         return PhaseId.RESTORE_VIEW;
    }
   
}

Come prima cosa, nell’AfterPhase, andiamo a identificare la pagina richiamata. Se stiamo mostrando la pagina di login, non eseguiamo nessuna attività.
Altrimenti, tramite EL andiamo a cercare un @ManagedBean chiamato “auth”, tramite l’espressione #{auth} .
Nel caso il bean non fosse esistente e/o il suo contenuto nullo, utilizzamo il FacesContext, per accedere al NavigationHandler e richiedere la gestione dell’outcome “LOGOUT”. In questo caso, nelle navigation-rule del faces-config, dobbiamo aver definito una regola che da qualsiasi view-id (view-id=*) permette il redirect alla pagina di login.

1
2
3
4
5
6
7
<navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>LOGOUT</from-outcome>
            <to-view-id>/login.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

Fatto questo, non dimentichiamo di registrare nel faces-config.xml il nostro listener:

1
2
3
<lifecycle>
        <phase-listener>com.metalide.test.jsf.UserLoggedPhaseListener</phase-listener>
    </lifecycle>

Buon divertimento.