2010-06-30 9 views
5

Per la mia applicazione voglio avere utenti con permessi diversi. Un permesso consentirebbe a un utente di visualizzare i dati dal mio database, mentre un altro permesso consentirebbe loro di modificare i dati. Al momento dell'accesso controllerei la loro autorizzazione per determinare se possono modificare i dati. Sto cercando un modo per disabilitare la totalità della mia pagina se l'utente ha il permesso di sola lettura. C'è un modo semplice per disabilitare tutto all'interno del tag <h:form>? Avrei bisogno di essere in grado di disabilitare più pagine, si spera solo guardando un booleano in backingbean. Qualsiasi aiuto sarebbe molto apprezzato.Come disabilitare pagina/modulo in JSF

-EDIT-
Sono presenti contenitori o simili che potrei avvolgere attorno ai miei ingressi che potrebbero essere impostati su disabilitato? In questo modo avrei solo bisogno di fare riferimento al diable in un posto e lasciare anche ogni campo per impostare la sua proprietà disable se è necessario in un'altra logica che ho?

risposta

6

È possibile disabilitare i pulsanti, i collegamenti, i campi di input (tutto ciò che consente la modifica) ecc ... puntandoli tutti allo stesso valore nel backing bean.

<h:inputText disabled="#{!bean.permissionToWrite}"> 

non so alcun modo per disattivare tutto contenuto in una forma, ma non si può decidere di farlo perché si consiglia all'utente di inviare query di ricerca (vale a dire una casella di ricerca) withing la forma.

Aggiornamento: risposta al commento di Alex Larzelere.

IMHO in questo caso è meglio usare disabled piuttosto che rendered perché si può decidere di visualizzare il valore di un campo per l'utente in una scatola inputText, ma non lasciarlo a modificarlo. Se non lo rendi, non può vederlo. È possibile utilizzare anche outputText per visualizzarlo, ma è necessario mantenere due elementi anziché uno.

Aggiornamento risposta alla modifica nella domanda: Puoi avvolgere i componenti all'interno di un h:panelGroup per esempio e renderlo o meno a seconda della logica, ma non è possibile disattivare i campi di input che si trovano all'interno della h:panelGroup, devi farlo individualmente.

+0

+1 Picchiami. Un'alternativa è usare 'rendered' e nascondere semplicemente tutto ciò che dà la possibilità di editare da utenti che non sono autorizzati a farlo. –

+0

Questa potrebbe essere un'opzione, anche se questo richiederà molto lavoro. Speravo che ci fosse qualcosa di più elegante (che so non è possibile) '' – SomeFatMan

+0

non è un granché, quando aggiungi un elemento, aggiungi il parametro disable. Anche in futuro potresti raggruppare le autorizzazioni in base a ruoli o gruppi, ad esempio :) – pakore

0

La maggior parte dei componenti di Tomahawk ha gli attributi DisplayValueOnly, visibleOnUserRole e enabledOnUserRole per controllare la visibilità degli elementi.

Speranza seguenti link sarà utile a voi:

5

Questo semplice componente personalizzato può essere utilizzato per avvolgere gli altri componenti e li disabiliterà se usato con l'attributo disabilitato = "true" o un espressione EL che sta valutando true. Il modo in cui è previsto che funzioni è che se un componente wrappped è già disabilitato, non verrà abilitato se disablePanel viene usato (o ajax ri-renderizzato) con disabled = "true". Il componente tenta solo di disabilitare UIInput & componenti UICommand, che penso sia ok ma potrebbe essere modificato.

xmlns:fnc="http://myco.co.uk/fnc" 
... 
<fnc:disablePanel disabled="#{bean.isItDisabled}"> 
    <h:inputText/> 
    ... 
</fnc:disablePanel> 
... 

UIDisablePanel.java

package uk.co.myco.component; 

import java.io.IOException; 
import javax.faces.component.*; 
import javax.faces.context.FacesContext; 

/* 
* @author Brendan Healey (Oversteer) 
*/ 

@FacesComponent("uk.co.myco.component.UIDisablePanel") 
public class UIDisablePanel extends UIComponentBase { 

    private enum PropertyKeys { 
     disabled; 
    } 

    public UIDisablePanel() { 
     setRendererType(null); 
    } 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 

     boolean toDisable = isDisabled(); 
     processDisablePanel(this, toDisable); 
     //super.encodeBegin(context); 
    } 

    public void processDisablePanel(UIComponent root, boolean toDisable) { 

     /* 
     * The key point here is that a child component of <x:disablePanel> may 
     * already be disabled, in which case we don't want to enable it if the 
     * <x:disablePanel disabled= attribute is set to true. 
     */ 

     for (UIComponent c : root.getChildren()) { 
      if (c instanceof UIInput || c instanceof UICommand) { 
       if(toDisable) { // <x:disablePanel disabled="true"> 
        Boolean curState = (Boolean) c.getAttributes().get("disabled"); 
        if(curState == null || curState == false) { 
         c.getAttributes().put("UIPanelDisableFlag", true); 
         c.getAttributes().put("disabled", true); 
        } 
       } 
       else { // <x:disablePanel disabled="false"> 
        if(c.getAttributes().get("UIPanelDisableFlag") != null) { 
         c.getAttributes().remove("UIPanelDisableFlag"); 
         c.getAttributes().put("disabled", false); 
        } 
       } 
      } 

      if (c.getChildCount() > 0) { 
       processDisablePanel(c, toDisable); 
      } 
     } 

    } 

    @Override 
    public String getFamily() { 
     // Got to override it but it doesn't get called. 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    public boolean isDisabled() { 
     return (boolean) getStateHelper().eval(PropertyKeys.disabled, false); 
    } 

    public void setDisabled(boolean disabled) { 
     getStateHelper().put(PropertyKeys.disabled, disabled); 
    } 
} 

disablepanel.taglib.xml

<?xml version="1.0" encoding="UTF-8"?> 
<facelet-taglib version="2.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"> 
    <namespace>http://myco.co.uk/fnc</namespace> 
    <tag> 
     <tag-name>disablePanel</tag-name> 
     <component> 
      <component-type>uk.co.myco.component.UIDisablePanel</component-type> 
     </component> 
     <attribute> 
      <name>disabled</name> 
     </attribute> 
    </tag> 
</facelet-taglib> 
+0

Noi stanno usando questo codice e ha funzionato bene fino ad ora. Ho scoperto che quando ho un componente nel mio disablePanel che è abilitato inizialmente con una condizione come '' e tu cambia questa condizione e aggiorna l'intero disablePanel per essere abilitato, non rende correttamente l'inputText disabilitato ma usa lo stato disabilitato iniziale da quando la vista è stata sottoposta a rendering la prima volta. Qualche idea? – odaa

0

Questa è una soluzione per disabilitare tutti i componenti dalla tua pagina. Nota che, con questo, si potrebbe anche disabilitare solo un gruppo di componenti in una sola volta

ho messo il metodo disableUIComponent all'interno di una classe di utilità Allucinante ho voluto utilizzarlo in diversi JSFBeans.

public class UtilsPrimefaces { 

/** 
* Disable all the children components 
* @param uiComponentName 
*/ 
public static void disableUIComponent(String uiComponentName) { 
    UIComponent component = FacesContext.getCurrentInstance() 
      .getViewRoot().findComponent(uiComponentName); 
    if(component!=null) { 
     disableAll(component.getChildren()); 
    } 
} 

/** 
* Recursive method to disable the list 
* @param components Widget PD list 
*/ 
private static void disableAll(List<UIComponent> components) { 

    for (UIComponent component : components) { 
     logger.info(component.getClass().getTypeName());    

     if (component instanceof InputText) { 
      ((InputText) component).setDisabled(true); 

     } else if (component instanceof InputNumber) { 
      ((InputNumber) component).setDisabled(true); 

     } else if (component instanceof InputTextarea) { 
      ((InputTextarea) component).setDisabled(true); 

     } else if (component instanceof HtmlInputText) { 
      ((HtmlInputText) component).setDisabled(true); 

     } else if(component instanceof SelectOneMenu) { 
      ((SelectOneMenu) component).setDisabled(true); 

     } else if(component instanceof SelectBooleanCheckbox) { 
      ((SelectBooleanCheckbox) component).setDisabled(true); 

     } else if(component instanceof CommandButton) { 
      ((CommandButton) component).setDisabled(true);    
     } 
     disableAll(component.getChildren()); 
    } 
} 

E quindi si può usare nei propri fagioli. Questo è un esempio di una pagina che aveva 3 scrollPanels e ho voluto disattivare solo Panel1 e Panel3:

@PostConstruct 
public void init() {   
    super.init(); 
    if(userHasPermissions() || loadPageInReadOnly()) { 
     Utils.disableUIComponent(":form:panel1"); 
     Utils.disableUIComponent(":form:panel3"); 
    } 
} 

Funziona per me :) PS stavo usando primefaces 2.2

+1

Grazie. Per le versioni più recenti di ogni jsf, controlla http://showcase.omnifaces.org/taghandlers/massAttribute Fa esattamente questo, ma più flessibile e senza il tuo codice ... – Kukeltje

0

Omnifaces ha un taghandler massAttribute per questo con diverse opzioni. Quello che viene chiuso a ciò che vi serve è

<o:massAttribute name="disabbled" value="true" target="javax.faces.component.UIInput"> 
    <h:outputLabel for="input1" /> 
    <h:inputText id="input1" /> 
    <h:outputLabel for="input2" /> 
    <h:inputText id="input2" /> 
    <h:outputLabel for="input3" /> 
    <h:inputText id="input3" /> 
</o:massAttribute> 

Questo disabilita tutti i componenti che si estendono da javax.faces.component.UIInput.