Обновление Primefaces JSF после неудачной проверки не работает - PullRequest
15 голосов
/ 30 декабря 2011

У меня проблема с проверкой <p:inputText> и обновлением его содержимого.

Обычно при сбое проверки inputText оно никогда не обновляется.

Вот простой примеруточнить:

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>

Тестовый компонент:

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

}

Если вы щелкнете по ссылке CommandLink под «Элементом», поле ввода обновится, но при сбое проверки (просто оставьте вводимый текст пустым и нажмите на любую другую часть страницы), граница ввода становится красной.После этого он никогда не обновляется при нажатии на упомянутые выше ссылки на команды.

Есть идеи?

Ответы [ 3 ]

10 голосов
/ 19 мая 2014

Arjan tijms ответ будет работать, однако лучшие решения, которые я нашел:

  1. Использование Omnifaces Solution Таким образом, вместо того, чтобы реализовать самого слушателя, все, что вам нужно, это всего лишь одна строка простого кода.

    <h:commandButton value="Update" action="#{bean.updateOtherInputs}">
    <f:ajax execute="currentInputs" render="otherInputs" />
    <f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener" />
    </h:commandButton>
    
  2. Если вы используете Primefaces, вы можете использовать resetInput компонент :

    <p:commandButton value="Reset Non-Ajax" actionListener="#{resetInputView.reset}"
    immediate="true" ajax="false" style="margin-right:20px;">
    <p:resetInput target="panel" />
    </p:commandButton>  
    
5 голосов
/ 30 декабря 2011

Это пресловутый случай «входных элементов» (на самом деле EditableValueHolder s), что, если проверка для них не удалась, никогда не может быть обновлена ​​снова через повторный рендеринг AJAX.

См .:

  1. Проверка JJF AJAX: execute = "@ this" render = "@ form" не согласуется в зависимости от предыдущих запросов
  2. Как заполнить текстовое поле с помощью PrimeFacesAJAX после возникновения ошибок проверки?
  3. http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1060

Обходным путем является создание прослушивателя действий, который сбрасывает компоненты, которые должны быть повторно обработаны.См. Последнюю страницу этого: http://community.jboss.org/message/620000

Если это поведение вас беспокоит (думаю, это так), тогда, пожалуйста, не стесняйтесь голосовать за JAVASERVERFACES_SPEC_PUBLIC-1060 и, если возможно, оставьтекомментарий о том, чего вы ожидали и почему.

3 голосов
/ 02 января 2012

Я отвечу сам.

На основе ссылок, предоставленных Arjan, я разрабатываю actionListener для очистки элементов формы. И это работает.

ФАСАД:

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...