2012-11-25 33 views
0

在这个页面中,我将让用户通过单击复选框来使密码可见。实际上,应该隐藏两个输入(passwordconPassword)并显示另一个输入(密码V)。所有这3个输入具有相同的价值和需求为用户这两个状态之间进行切换,以保持它们的值:(有两个秘密领域可见或具有一个纯文本字段)更新和进程在JSF 2.0 Primefaces中无法正常工作3.4

我把网页和豆代码在这里:

JSF页面:

<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" 
       template="./templates/main_template.xhtml" 
       xmlns:p="http://primefaces.org/ui" 
       xmlns:h="http://java.sun.com/jsf/html" 
       xmlns:f="http://java.sun.com/jsf/core" 
       xmlns="http://www.w3.org/1999/xhtml"> 

    <ui:define name="subTitle"> 
    :: #{lbls.newEntry} </ui:define> 

    <ui:define name="content"> 
    <p:panel rendered="#{current.loggedIn}" header="#{lbls.newEntry}" > 
     <h:form id="frmEntry"> 
     <h:panelGrid columns="3"> 

      <h:panelGroup> 
      <h:outputLabel for="title" value="#{lbls.title}:"/> 
      <p:focus for="title"/> 
      </h:panelGroup> 
      <p:inputText id="title" value="#{entry.passwordEntry.title}" maxlength="100" label="#{lbls.title}" required="true"/> 
      <p:message for="title"/> 

      <h:outputLabel for="description" value="#{lbls.description}:"/> 
      <p:inputTextarea id="description" value="#{entry.passwordEntry.description}" maxlength="500" rows="3" cols="40" label="#{lbls.description}"/> 
      <p:message for="description"/> 

      <p:spacer height="10"/> 
      <p:spacer height="10"/> 
      <p:spacer height="10"/> 

      <h:outputLabel for="username" value="#{lbls.username}:"/> 
      <p:inputText id="username" value="#{entry.passwordEntry.username}" maxlength="100" label="#{lbls.username}"/> 
      <p:message for="username"/>   

      <h:outputLabel for="password" id="lblPassword" value="#{lbls.password}:" styleClass="#{entry.showPasswords ? 'none' : ''}" /> 
      <p:password id="password" feedback="true" value="#{entry.passwordEntry.password}" match="conPassword" maxlength="100" 
         label="#{lbls.password}" promptLabel="#{lbls.strengthPromp}" weakLabel="#{lbls.weakPassword}" 
         goodLabel="#{lbls.goodPassword}" strongLabel="#{lbls.strongPassword}" styleClass="#{entry.showPasswords ? 'none' : ''}" 
         /> 
      <p:message id="msgPassword" for="password" class="#{entry.showPasswords ? 'none' : ''}"/> 

      <h:outputLabel id="lblConPassword" for="conPassword" value="#{lbls.conPassword}:" 
         styleClass="#{entry.showPasswords ? 'none' : ''}"/> 
      <p:password id="conPassword" value="#{entry.passwordEntry.password}" label="#{lbls.conPassword}" maxlength="100" 
         styleClass="#{entry.showPasswords ? 'none' : ''}"/> 
      <p:message id="msgConPassword" for="conPassword" class="display: #{!entry.showPasswords ? 'none' : ''}"/> 

      <h:outputLabel id="lblPasswordV" for="passwordV" value="#{lbls.password}:" 
         styleClass="#{!entry.showPasswords ? 'none' : ''}"/> 
      <p:inputText id="passwordV" value="#{entry.passwordEntry.password}" maxlength="100" 
         label="#{lbls.password}" 
         styleClass="#{!entry.showPasswords ? 'none' : ''}"/> 
      <p:message id="msgPasswordV" for="passwordV" 
        class="#{!entry.showPasswords ? 'none' : ''}"/> 

      <h:outputLabel for="showPasswords" value="#{lbls.showPasswords}:"/> 
      <p:selectBooleanCheckbox id="showPasswords" label="#{lbls.showPasswords}" value="#{entry.showPasswords}"> 
      <p:ajax process="password passwordV conPassword" update="password passwordV conPassword lblPassword lblPasswordV lblConPassword msgPassword msgConPassword msgPasswordV"/> 
      </p:selectBooleanCheckbox> 
      <h:outputText/> 

      <p:spacer height="10"/> 
      <p:spacer height="10"/> 
      <p:spacer height="10"/> 

      <h:outputLabel for="url" value="#{lbls.url}:"/> 
      <p:inputText id="url" value="#{entry.passwordEntry.url}" maxlength="255" label="#{lbls.url}"/> 
      <p:message for="url"/> 

      <h:outputLabel for="ip" value="#{lbls.ip}:"/> 
      <p:inputText id="ip" value="#{entry.passwordEntry.ip}" maxlength="255" label="#{lbls.ip}"/> 
      <p:message for="ip"/> 

      <p:spacer height="10"/> 
      <p:spacer height="10"/> 
      <p:spacer height="10"/> 

      <h:outputLabel for="tags" value="#{lbls.tags}:"/> 
      <p:autoComplete id="tags" value="#{entry.selectedTags}" 
          completeMethod="#{entry.selectTag}" converter="PasswordEntry" multiple="true" 
          var="tag" itemLabel="#{tag.title}" itemValue="#{tag}" /> 
      <p:message for="tags"/> 

      <p:spacer height="10"/> 
      <p:spacer height="10"/> 
      <p:spacer height="10"/> 

      <h:outputText/> 
      <h:panelGroup layout="block" styleClass="right-align"> 
      <p:commandButton value="#{lbls.save}" actionListener="#{entry.save(event)}" 
          update=":growl messages"/> 
      </h:panelGroup> 


      <f:facet name="footer"> 
      <p:messages id="messages"/> 
      </f:facet> 
     </h:panelGrid> 
     </h:form> 
    </p:panel> 

    <ui:include src="/templates/not_logged_in.xhtml" rendered="!#{current.loggedIn}"/> </ui:define> 

</ui:composition> 

和豆制品:

package package; 


@ManagedBean(name = "entry") 
@ViewScoped 
public class PasswordEntryBean implements Serializable { 

    //<editor-fold defaultstate="collapsed" desc="FIELDS"> 
    private static final Logger logger = LogUtil.getLogger(PasswordEntryBean.class); 
    private PasswordEntry passwordEntry; 
    @ManagedProperty(value = "#{current}") 
    private CurrentSessionBean current; 
    private Database database; 
    private List<PasswordTag> selectedTags = new ArrayList<PasswordTag>(); 
    private Set<PasswordTag> tags; 
    private boolean showPasswords; 
    //</editor-fold> 

    //<editor-fold defaultstate="collapsed" desc="CONSTRUCTORS">  
    public PasswordEntryBean() { 
    passwordEntry = new PasswordEntry(); 
    } 

    @PostConstruct 
    public void init() { 
    } 
    //</editor-fold> 

    //<editor-fold defaultstate="collapsed" desc="PROPERTIES">  
    public PasswordEntry getPasswordEntry() { 
    return passwordEntry; 
    } 

    public Database getDatabase() { 
    return database; 
    } 

    public boolean getShowPasswords() { 
    return showPasswords; 
    } 

    public void setShowPasswords(boolean showPasswords) { 
    this.showPasswords = showPasswords; 
    } 

    public void setDatabase(Database database) { 
    this.database = database; 
    } 

    public Set<PasswordTag> getTags() { 
    return tags; 
    } 

    public void setTags(Set<PasswordTag> tags) { 
    this.tags = tags; 
    } 

    public List<PasswordTag> getSelectedTags() { 
    return selectedTags; 
    } 

    public void setSelectedTags(List<PasswordTag> selectedTags) { 
    this.selectedTags = selectedTags; 
    } 

    public void setPasswordEntry(PasswordEntry passwordEntry) { 
    this.passwordEntry = passwordEntry; 
    } 

    public CurrentSessionBean getCurrent() { 
    return current; 
    } 

    public void setCurrent(CurrentSessionBean current) { 
    this.current = current; 
    } 
    //</editor-fold> 
} 

更新的代码


我只是写了一个简单的代码,以使其更容易让你了解我的问题:

JSF:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:f="http://java.sun.com/jsf/core"> 
    <h:head> 
    <title>Facelet Title</title> 
    <style type="text/css"> 
     .none { 
     display: none; 
     } 
    </style> 
    </h:head> 
    <h:body> 
    <h1>Register</h1> 
    <h:form id="frmRegistration"> 
     <h:panelGrid columns="3"> 
     <h:outputLabel value="Username:" for="username"/> 
     <p:inputText label="username" id="username" value="#{testBean.username}" required="true"/> 
     <p:message for="username"/> 

     <h:outputLabel value="Password:" id="lblPassword" for="password" styleClass="#{!testBean.visiblePassword ? '' : 'none'}"/> 
     <p:password label="password" id="password" value="#{testBean.password}" 
         styleClass="#{!testBean.visiblePassword ? '' : 'none'}"/> 
     <p:message for="password" id="msgPassword" class="#{!testBean.visiblePassword ? '' : 'none'}"/> 

     <h:outputLabel value="Confirm Password:" id="lblCpassword" for="cpassword" styleClass="#{!testBean.visiblePassword ? '' : 'none'}"/> 
     <p:password label="confirm password" id="cpassword" value="#{testBean.password}" 
         styleClass="#{!testBean.visiblePassword ? '' : 'none'}"/> 
     <p:message for="cpassword" id="msgCpassword" class="#{!testBean.visiblePassword ? '' : 'none'}"/> 

     <h:outputLabel value="Password:" id="lblVpassword" for="vpassword" styleClass="#{testBean.visiblePassword ? '' : 'none'}"/> 
     <p:inputText label="password" id="vpassword" value="#{testBean.password}" 
         styleClass="#{testBean.visiblePassword ? '' : 'none'}"/> 
     <p:message for="vpassword" id="msgVpassword" class="#{testBean.visiblePassword ? '' : 'none'}"/> 

     <h:outputLabel value="Show password"/> 
     <p:selectBooleanButton value="#{testBean.visiblePassword}" 
           onLabel="Yes" offLabel="No"> 
      <p:ajax update="messages password cpassword vpassword lblPassword lblCpassword lblVpassword msgPassword msgCpassword msgVpassword" 
        process="messages password cpassword vpassword" listener="#{testBean.addMessage}" /> 
     </p:selectBooleanButton> 


     <f:facet name="footer"> 
      <p:commandButton actionListener="#{testBean.save(event)}" value="Save" update="messages"/> 
      <p:messages id="messages"/> 
     </f:facet> 
     </h:panelGrid> 
    </h:form> 
    </h:body> 
</html> 

和豆制品:

import javax.faces.application.FacesMessage; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.context.FacesContext; 
import javax.faces.event.ActionEvent; 

@ManagedBean 
@ViewScoped 
public class TestBean { 

    private String username; 
    private String password; 
    private boolean visiblePassword; 

    public void addMessage() { 
    String summary = visiblePassword ? "Checked" : "Unchecked"; 

    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(summary)); 
    } 

    public TestBean() { 
    } 

    public void save(ActionEvent event) { 
    } 

    public String getUsername() { 
    return username; 
    } 

    public void setUsername(String username) { 
    this.username = username; 
    } 

    public String getPassword() { 
    return password; 
    } 

    public void setPassword(String password) { 
    this.password = password; 
    } 

    public boolean isVisiblePassword() { 
    return visiblePassword; 
    } 

    public void setVisiblePassword(boolean visiblePassword) { 
    this.visiblePassword = visiblePassword; 
    } 
} 

此代码可以隐藏两个字段并显示第三个字段的道具好吧,如果我不添加进程属性到<p:ajax标记。但是这个属性是为了使这些字段在两种模式(2个秘密字段/ 1个纯文本字段)之间切换时保持它们的值。

但它失败!

============================================= =============

第二次更新

我用重新显示并解决了空值的问题,但仍然投入不隐藏/显示,除非我设置了updateprocess@form这不适合我的情况。

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:f="http://java.sun.com/jsf/core"> 
    <h:head> 
    <title>Facelet Title</title> 
    <style type="text/css"> 
     .none { 
     display: none; 
     } 
    </style> 
    </h:head> 
    <h:body> 
    <h1>Register</h1> 
    <h:form id="frmRegistration"> 
     <h:panelGrid columns="3"> 
     <h:outputLabel value="Username:" for="username"/> 
     <p:inputText label="username" id="username" value="#{testBean.username}" required="true"/> 
     <p:message for="username"/> 

     <h:outputLabel value="Password:" id="lblPassword" for="password" rendered="#{!testBean.visiblePassword}"/> 
     <p:password redisplay="true" label="password" id="password" value="#{testBean.password}" 
         rendered="#{!testBean.visiblePassword}"/> 
     <p:message for="password" id="msgPassword" rendered="#{!testBean.visiblePassword}"/> 

     <h:outputLabel value="Confirm Password:" id="lblCpassword" for="cpassword" rendered="#{!testBean.visiblePassword}"/> 
     <p:password redisplay="true" label="confirm password" id="cpassword" value="#{testBean.password}" 
         rendered="#{!testBean.visiblePassword}"/> 
     <p:message for="cpassword" id="msgCpassword" rendered="#{!testBean.visiblePassword}"/> 

     <h:outputLabel value="Password:" id="lblVpassword" for="vpassword" rendered="#{testBean.visiblePassword}"/> 
     <p:inputText label="password" id="vpassword" value="#{testBean.password}" 
         rendered="#{testBean.visiblePassword}"/> 
     <p:message for="vpassword" id="msgVpassword" rendered="#{testBean.visiblePassword}"/> 

     <h:outputLabel value="Show password"/> 
     <p:selectBooleanButton value="#{testBean.visiblePassword}" 
           onLabel="Yes" offLabel="No"> 
      <p:ajax update="messages password cpassword vpassword lblPassword lblCpassword lblVpassword msgPassword msgCpassword msgVpassword" 
        process="password cpassword vpassword" listener="#{testBean.addMessage}" /> 
     </p:selectBooleanButton> 


     <f:facet name="footer"> 
      <p:commandButton actionListener="#{testBean.save(event)}" value="Save" update="messages"/> 
      <p:messages id="messages"/> 
     </f:facet> 
     </h:panelGrid> 
    </h:form> 
    </h:body> 
</html> 

回答

1

您的主要错误是,您在客户端使用CSS切换输入字段的可见性,而不是在服务器端使用JSF。所以JSF基本上不知道哪一个显示/隐藏。它只知道两个字段都显示出来。所以它会处理这两个领域。正如你已经将两个字段的值绑定到同一个属性,它总是会得到最后一个处理字段的值。

您需要在服务器端使用JSF来显示/隐藏输入字段。您可以使用为此提供的rendered属性。

rendered="#{testBean.visiblePassword}" 
+0

我也尝试过服务器端隐藏,但这种情况下的问题是,当我想第二次切换时,该值变为空。无论如何,我完全改变了我的UI设计,因为我找不到这个问题的真正解决方案。我甚至创建了3个属性并将每个输入绑定到一个单独的属性!但仍然没有工作。所以我只剩下2个outputText的2个秘密字段,并且显示/隐藏了那些outputTexts。 – ehsun7b

+1

使用''重新显示提交的值。他们出于安全原因,默认情况下不会重新显示。你不需要3个属性。只有一个就足够了。 – BalusC

+0

请看看我更新的Facelet。我用'redisplay =“true”' – ehsun7b

1

的问题是,你在同一个变量entry.passwordEntry.password结合2个或多个字段,所以提交这些字段中的值的<h:form>只有一个时将被设置为entry.passwordEntry.password,其他值都将被丢弃。

解决此问题的最佳方法是为表单上每个字段提供不同的变量。通过查看你的代码,它看起来像,可以通过在你的bean 3个PasswordEntry属性来实现:

@ManagedBean(name = "entry") 
@ViewScoped 
public class PasswordEntryBean implements Serializable { 
    //other attributes... 
    private PasswordEntry passwordEntry; 
    private PasswordEntry passwordEntryV; 
    private PasswordEntry conPasswordEntry; 

    //<editor-fold defaultstate="collapsed" desc="CONSTRUCTORS">  
    public PasswordEntryBean() { 
     passwordEntry = new PasswordEntry(); 
     passwordEntryV = new PasswordEntry(); 
     conPasswordEntry = new PasswordEntry(); 
    } 

    //getters and setters... 
} 

JSF代码:

<p:password id="password" feedback="true" value="#{entry.passwordEntry.password}" 
    match="conPassword" maxlength="100" label="#{lbls.password}" 
    promptLabel="#{lbls.strengthPromp}" weakLabel="#{lbls.weakPassword}" 
    goodLabel="#{lbls.goodPassword}" strongLabel="#{lbls.strongPassword}" 
    styleClass="#{entry.showPasswords ? 'none' : ''}" /> 

<p:password id="conPassword" value="#{entry.conPasswordEntry.password}" 
    label="#{lbls.conPassword}" maxlength="100" 
    styleClass="#{entry.showPasswords ? 'none' : ''}"/> 

<p:inputText id="passwordV" value="#{entry.passwordEntryV.password}" 
    maxlength="100" label="#{lbls.password}" 
    styleClass="#{!entry.showPasswords ? 'none' : ''}"/> 

如果你想/需要在同一价值2或3个地方,你必须考虑到绑定不应该在同一个<h:form>,否则你将有同样的问题。使用普通的JavaScript可以同步变量值(毕竟<p:password><input type="password"><p:input><input type="text">)执行如下动作,即应该在你的<p:selectBooleanCheckbox>选择一个值时,可以执行侦听器时或在服务器端。

+0

这样,如果用户填写密码字段(密码字段),然后点击复选框,3ed字段将是空的! – ehsun7b