2011-12-30 37 views
14

Tôi gặp sự cố khi xác thực số <p:inputText> và cập nhật nội dung của nó.Bản cập nhật JSF của Primefaces sau khi xác nhận không thành công, không hoạt động

Về cơ bản khi xác thực inputText thất bại, nó không bao giờ được cập nhật lại.

Dưới đây là một ví dụ đơn giản để làm rõ:

Các Facelet:

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

Các thử nghiệm đậu:

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 ""; 
    } 

} 

Nếu bạn click vào commandLinks dưới "Element" s đầu vào trường được cập nhật, nhưng khi xác nhận không thành công (chỉ cần để trống văn bản đầu vào và nhấp vào bất kỳ phần nào khác của trang), đường viền của đầu vào chuyển sang màu đỏ. Sau đó nó không bao giờ được cập nhật một lần nữa khi nhấp vào commandLinks đã đề cập ở trên.

Bất kỳ ý tưởng nào?

Trả lời

9

Arjan tijms Câu trả lời sẽ công trình, tuy nhiên những giải pháp tốt nhất mà tôi tìm thấy là:

  1. Sử dụng Omnifaces Solution Vì vậy, thay vì thực hiện trình nghe của chính bạn tất cả những gì bạn cần chỉ là một dòng mã đơn giản.

    <h:commandButton value="Update" action="#{bean.updateOtherInputs}"> 
    <f:ajax execute="currentInputs" render="otherInputs" /> 
    <f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener" /> 
    </h:commandButton> 
    
  2. Nếu bạn đang sử dụng Primefaces bạn có thể sử dụng 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

Đây là trường hợp khét tiếng của 'yếu tố đầu vào' (thực tế là EditableValueHolder) khi xác thực không thành công cho chúng không bao giờ có thể được cập nhật lại thông qua hiển thị lại AJAX.

Xem:

  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

Một công việc xung quanh là tạo ra một người biết lắng nghe hành động mà reset các thành phần đó sẽ được tái tạo hình. Xem trang cuối cùng của điều này: http://community.jboss.org/message/620000

Nếu hành vi này làm phiền bạn (tôi đoán vậy), vui lòng bỏ phiếu cho JAVASERVERFACES_SPEC_PUBLIC-1060 và nếu có thể để lại nhận xét cho biết bạn mong đợi và lý do gì.

3

Tôi sẽ tự trả lời.

Dựa trên các liên kết được cung cấp bởi Arjan, tôi phát triển actionListener để làm sạch các phần tử biểu mẫu. Và nó hoạt động.

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

và người nghe ....

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

} 
Các vấn đề liên quan