2010-06-30 10 views
5

Dla mojej aplikacji chcę mieć użytkowników z różnymi uprawnieniami. Jedno pozwolenie pozwoliłoby użytkownikowi na przeglądanie danych z mojej bazy danych, podczas gdy inne pozwoliłoby im edytować dane. Po zalogowaniu sprawdzam ich zgodę na określenie, czy mogą edytować dane. Szukam sposobu na wyłączenie całej mojej strony, jeśli użytkownik ma uprawnienie tylko do odczytu. Czy istnieje prosty sposób wyłączenia wszystkiego w obrębie znacznika <h:form>? Musiałbym mieć możliwość wyłączenia wielu stron, mam nadzieję, że wystarczy spojrzeć na jedną wartość logiczną przez backingbean. Każda pomoc będzie bardzo ceniona.Jak wyłączyć stronę/formularz w JSF

-EDIT-
Czy są jakieś pojemniki lub coś w tym rodzaju, które mógłbym owinąć wokół moich wejść, które mogłyby zostać wyłączone? W ten sposób musiałem tylko odwołać się do diable w jednym miejscu i mogłem zostawić każde pole, aby ustawić własną własność wyłączenia, jeśli jest to potrzebne w innej logice, którą mam?

Odpowiedz

6

Można wyłączyć przyciski, łącza, pola wprowadzania danych (wszystko, co umożliwia edycję) itp ... wskazując je wszystkie na taką samą wartość w komponencie bean.

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

ja nie znam żadnego sposobu, aby wyłączyć wszystko zawarte w formularzu, ale może nie chcesz tego zrobić, ponieważ może chcesz, aby użytkownik złożyć zapytań (czyli pola wyszukiwania) withing formularza.

Aktualizacja: odpowiedź na komentarz Alexa Larzelere'a.

IMHO w tym przypadku lepiej jest użyć disabled zamiast rendered ponieważ może chcesz wyświetlić wartość pola do użytkownika w polu inputText, ale nie pozwól, żeby to zmienić. Jeśli go nie wyrenderujesz, nie będzie mógł tego zobaczyć. Można również użyć parametru outputText, aby go wyświetlić, ale musisz zachować dwa elementy zamiast jednego.

Aktualizacja zgłoszeniowy do edycji w pytaniu: Można owinąć komponenty wewnątrz h:panelGroup dla przykładu i uczynić go lub nie w zależności od swojej logice, ale nie można wyłączyć pól wejściowych, które są od wewnątrz h:panelGroup, musisz to zrobić indywidualnie.

+0

+1 Pokonaj mnie. Alternatywą jest użycie "renderowanego" i po prostu ukryć wszystko, co daje możliwość edycji od użytkowników, którzy nie są do tego uprawnieni. –

+0

To może być opcja, ale to będzie dużo pracy. Miałem nadzieję, że będzie coś bardziej eleganckiego (co, jak wiem, nie jest możliwe) '' – SomeFatMan

+0

to nie jest dużo pracy, kiedy dodajesz element, po prostu dodaj parametr wyłączenia. Nawet w przyszłości możesz grupować uprawnienia według ról lub grup, na przykład :) – pakore

0

Większość komponentów Tomahawk ma atrybuty displayValueOnly, visibleOnUserRole i enabledOnUserRole do kontrolowania widoczności elementów.

Nadzieja poniższe linki będą przydatne dla Ciebie:

5

Ten prosty zwyczaj składnik może być użyty do zawijania innych składników i wyłącza je, jeśli są używane z atrybutem disabled = "true" lub wyrażeniem EL, które jest prawdziwe. Sposób, w jaki ma działać, polega na tym, że jeśli uszkodzony komponent jest już wyłączony, nie zostanie włączony, jeśli zostanie użyty disablePanel (lub ponownie renderowany) z wyłączoną = "true". Komponent próbuje jedynie wyłączyć składniki UICInput & UICommand, co moim zdaniem jest w porządku, ale można je zmienić.

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

używają tego kodu i wszystko działało aż do teraz. Znalazłem, że kiedy mam komponent w moim disablePanel, który jest włączony na początku z warunkiem takim jak '' a ty zmień ten warunek i zaktualizuj cały disablePanel, który ma być włączony, nie powoduje poprawnego wyłączenia inputText, ale wykorzystuje początkowy stan wyłączony od momentu, gdy widok został wyrenderowany za pierwszym razem. Jakieś pomysły? – odaa

0

Jest to rozwiązanie umożliwiające wyłączenie wszystkich składników ze strony. Nota że z tym, można również wyłączyć tylko grupę składników na raz

Włożyłem metodę disableUIComponent wewnątrz klasie użytkowej beacuse chciałem użyć go w kilku 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()); 
    } 
} 

A następnie można użyć w ziarnach. To jest przykład dla strony, która miała 3 scrollPanels i chciałem wyłączyć tylko Panel1 i panel3:

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

To działa na mnie :) PS używałem primefaces 2,2

+1

Dzięki. W przypadku nowszych wersji każdego jsf sprawdź http://showcase.omnifaces.org/taghandlers/massAttribute Czy to właśnie, ale bardziej elastyczne i bez własnego kodu ... – Kukeltje

0

Omnifaces ma massAttribute taghandler do tego z kilkoma opcjami. Ten, który przychodzi zamknięte do czego potrzebne jest

<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> 

Wyłącza wszystkie komponenty, które rozciągają się od javax.faces.component.UIInput.