2011-12-30 17 views
14

<p:inputText>の検証とその内容の更新に問題があります。検証が失敗した後のPrimefaces JSFの更新が機能しない

基本的にinputTextの検証に失敗した場合、それは決して再び更新されません。

ここで明確にする簡単な例です:あなたは "エレメント" の入力以下commandLinksをクリックすると

package com.easydevel.test; 

public class Test { 

    private String currentElement; 
    private String element; 

    public String getCurrentElement() { 
     return currentElement; 
    } 

    public void setCurrentElement(String currentElement) { 
     this.currentElement = currentElement; 
    } 

    public String getElement() { 
     return element; 
    } 

    public void setElement(String element) { 
     this.element = element; 
    } 

    public String assignElement(){ 
     setElement(getCurrentElement()); 
     return ""; 
    } 

} 

:テスト豆

!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:f="http://java.sun.com/jsf/core" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.org/ui"> 
    <h:head> 
    </h:head> 
    <body> 
    <h1>Test</h1> 

     <h:form id="list" prependId="false"> 
      <ul> 
       <li>Element 1&#160; 
        <p:commandLink action="#{Test.assignElement}" update="detail_value"> 
         <f:setPropertyActionListener target="#{Test.currentElement}" value="1" /> 
         Assign 
        </p:commandLink> 
       </li> 
       <li>Element 2&#160; 
        <p:commandLink action="#{Test.assignElement}" update="detail_value"> 
         <f:setPropertyActionListener target="#{Test.currentElement}" value="2" /> 
         Assign 
        </p:commandLink> 
       </li> 
      </ul> 
     </h:form> 

     <h:form id="detail" prependId="false"> 
      <p:inputText value="#{Test.element}" id="detail_value" required="true" styleClass="#{Faces.messagesFor['detail_value'] ? 'border:1px solid red' : ''}"> 
       <p:ajax event="blur" update="detail_value"></p:ajax> 
      </p:inputText> 
     </h:form> 
    </body> 
</html> 

にfaceletフィールドは更新されますが、検証が失敗した場合(単に入力テキストを空白のままにし、ページの他の部分をクリックすると)、入力の境界線が赤くなります。その後、上記のコマンドリンクをクリックすると再び更新されることはありません。

アイデア?

答えて

9

Arjan tijmsは答えは作品が、しかし、私が見つけた最良の解決策があります:

  1. 使用Omnifaces Solution リスナーを実装する代わりに、あなた自身あなたが必要とするのは、単純なコードの1行だけです。あなたがPrimefacesを使用している場合

    <h:commandButton value="Update" action="#{bean.updateOtherInputs}"> 
    <f:ajax execute="currentInputs" render="otherInputs" /> 
    <f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener" /> 
    </h:commandButton> 
    
  2. あなたはresetInput component使用することができます。

    <p:commandButton value="Reset Non-Ajax" actionListener="#{resetInputView.reset}" 
    immediate="true" ajax="false" style="margin-right:20px;"> 
    <p:resetInput target="panel" /> 
    </p:commandButton> 
    
5

「入力要素」(実際にはEditableValueHolder)は、AJAXの再レンダリングを使用して検証が失敗した場合、再び更新することはできません。

参照:

  1. JSF AJAX validation: execute="@this" render="@form" inconsistent depending on prior requests
  2. How can I populate a text field using PrimeFaces AJAX after validation errors occur?
  3. http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1060

ワークアラウンド再レンダリングされるコンポーネントをリセットするアクションリスナーを作成することです。 http://community.jboss.org/message/620000

この動作が気になる場合は、JAVASERVERFACES_SPEC_PUBLIC-1060に投票するのをためらってください。もし可能であれば、あなたが期待していた理由を示すコメントを残してください。

3

私は自分自身に答えるでしょう。

Arjanが提供するリンクに基づいて、フォーム要素を消去するためのactionListenerを開発しました。そしてそれは働く。

にfacelet:

<p:commandLink action="#{Test.assignElement}" update="detail_value"> 
         <f:actionListener type="com.easydevel.utils.CleanForms" /> 
         <f:setPropertyActionListener target="#{Test.currentElement}" value="1" /> 
         Assign 
</p:commandLink>  

とリスナー....

package com.easydevel.utils; 

import java.util.Collection; 
import java.util.Iterator; 
import javax.faces.component.EditableValueHolder; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.context.PartialViewContext; 
import javax.faces.event.AbortProcessingException; 
import javax.faces.event.ActionEvent; 
import javax.faces.event.ActionListener; 


public class CleanForms implements ActionListener { 

public void processAction(ActionEvent event) throws AbortProcessingException {     
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    PartialViewContext ajaxContext = facesContext.getPartialViewContext(); 
    UIComponent root = facesContext.getViewRoot();   
    Collection<String> renderIds = ajaxContext.getRenderIds(); 
    for (String renderId : renderIds) { 
     UIComponent form = findComponent(root,renderId); 
     if (form != null) { 
      clearComponentHierarchy(form); 
     } 
    } 
} 

private void clearComponentHierarchy(UIComponent pComponent) { 

     if (pComponent.isRendered()) { 

      if (pComponent instanceof EditableValueHolder) { 
       EditableValueHolder editableValueHolder = (EditableValueHolder) pComponent; 
       editableValueHolder.setSubmittedValue(null); 
       editableValueHolder.setValue(null); 
       editableValueHolder.setLocalValueSet(false); 
       editableValueHolder.setValid(true); 
      }   

      for (Iterator<UIComponent> iterator = pComponent.getFacetsAndChildren(); iterator.hasNext();) { 
       clearComponentHierarchy(iterator.next()); 
      }   

     } 
} 

private static UIComponent findComponent(UIComponent base, String id) { 
     if (id.equals(base.getId())) 
     return base; 
     UIComponent kid = null; 
     UIComponent result = null; 
     Iterator kids = base.getFacetsAndChildren(); 
     while (kids.hasNext() && (result == null)) { 
     kid = (UIComponent) kids.next(); 
     if (id.equals(kid.getId())) { 
      result = kid; 
      break; 
     } 
     result = findComponent(kid, id); 
     if (result != null) { 
      break; 
     } 
     } 
     return result; 
    } 

} 
関連する問題