Primefaces JSF update after validation failed doesn't work

前端 未结 3 1195
小蘑菇
小蘑菇 2021-02-12 20:42

I have a problem with the validation of a and updating its content.

Basically when the inputText validation fails, it never gets updated

相关标签:
3条回答
  • 2021-02-12 20:59

    I will answer myself.

    Based on the links provided by Arjan, i develop the actionListener to clean the form elements. and It works.

    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>    
    

    And the LISTENER....

    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;
       }
    
    }
    
    0 讨论(0)
  • 2021-02-12 21:06

    This is the notorious case of 'input elements' (EditableValueHolders actually) that once validation has failed for them can never be updated again via AJAX re-rendering.

    See:

    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

    A work-around is to create an action listener that resets the components that are to be re-rendered. See the last page of this: http://community.jboss.org/message/620000

    If this behavior bothers you (I guess it does), then please don't hesitate to vote for JAVASERVERFACES_SPEC_PUBLIC-1060 and if possible leave a comment telling what you expected and why.

    0 讨论(0)
  • 2021-02-12 21:08

    Arjan tijms answer will works, however the best solutions I found are:

    1. Use Omnifaces Solution So, instead of implementing the listener your self all what you need is just one line of simple code.

      <h:commandButton value="Update" action="#{bean.updateOtherInputs}">
      <f:ajax execute="currentInputs" render="otherInputs" />
      <f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener" />
      </h:commandButton>
      
    2. If you are using Primefaces you can use 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>  
      
    0 讨论(0)
提交回复
热议问题