Пересмотреть требуемое выражение после сбоя проверки - PullRequest
2 голосов
/ 08 июля 2019

У меня есть форма с некоторыми обязательными полями в зависимости от selectOneMenu, например:

<p:selectOneMenu id="myList" value="#{myBean.selectedItem}">
    <p:selectItems value="#{myBean.myItems}" />
    <p:ajax listener="#{myBean.myList_change}"
            process="myList field1 field2 field3"
            update="field1 field2 field3" />
</p:selectOneMenu>

<p:inputNumber id="field1" required="true" />
<p:inputNumber id="field2" required="#{myBean.selectedItem gt 1}" />
<p:inputNumber id="field3" required="#{myBean.selectedItem gt 2}" />

При первом нажатии кнопки отправки без заполнения обязательных полей:

<p:commandButton id="mySubmit" action="#{myBean.myAction}" />

Я получаю ошибки проверки, тогда, если я изменю значение selectOneMenu, требуемое выражение больше не будет оцениваться.

Например, если я отправлю форму с selectedItem equals to 3, я получу всеошибки проверки, затем я отправляю форму с selectedItem equals to 1, и для простых символов все еще требуются все три поля как обязательные.

Я попытался добавить resetInput к кнопке:

<p:resetInput target=":myForm" />

Скореечем immediate="true" до selectOneMenu, без какого-либо успеха.

Любая идея, пожалуйста?

Примечание: версия PrimeFaces - 6.2

PS: На изображении требуется только первое поле, но должны быть обязательны все элементы.

example

После полной минимальной воспроизводимостипример:

Файл xhtml (test.xhtml):

<?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:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Example</title>
</h:head>
<h:body bgcolor="white">
    <h:form>
        <p:messages showDetail="true" />
        <p:selectOneMenu id="myList" value="#{myBean.selectedItem}">
            <f:selectItem itemLabel="1" itemValue="1" />
            <f:selectItem itemLabel="2" itemValue="2" />
            <f:selectItem itemLabel="3" itemValue="3" />
            <p:ajax listener="#{myBean.myList_change}"
                process="myList field1 field2 field3" update="field1 field2 field3" />
        </p:selectOneMenu>

        <p:inputNumber id="field1" required="true" decimalPlaces="0"
            value="#{myBean.field1}" />
        <p:inputNumber id="field2" required="#{myBean.selectedItem gt 1}"
            decimalPlaces="0" value="#{myBean.field2}" />
        <p:inputNumber id="field3" required="#{myBean.selectedItem gt 2}"
            decimalPlaces="0" value="#{myBean.field3}" />

        <p:commandButton actionListener="#{myBean.submit}" update="@form" />
    </h:form>
</h:body>
</html>

Боб (MyBean.java):

    package com.mkyong.common;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "myBean")
@SessionScoped
public class MyBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final String STRING_EMPTY = "";

    private Long selectedItem;

    private String field1, field2, field3;

    public Long getSelectedItem() {
        return selectedItem;
    }

    public void setSelectedItem(final Long selectedItem) {
        this.selectedItem = selectedItem;
    }

    public String getField1() {
        return field1;
    }

    public void setField1(final String field1) {
        this.field1 = field1;
    }

    public String getField2() {
        return field2;
    }

    public void setField2(final String field2) {
        this.field2 = field2;
    }

    public String getField3() {
        return field3;
    }

    public void setField3(final String field3) {
        this.field3 = field3;
    }

    public void myList_change() {
        final long value = selectedItem.longValue();
        if (value < 1) {
            setField1(STRING_EMPTY);
        }
        if (value < 2) {
            setField2(STRING_EMPTY);
        }
        if (value < 3) {
            setField3(STRING_EMPTY);
        }
    }

    public void submit() {
    }

}

В файле web.xml вы должны установить страницу приветствия:

<welcome-file-list>
    <welcome-file>faces/test.xhtml</welcome-file>
</welcome-file-list>

1 Ответ

3 голосов
/ 09 июля 2019

Этот вопрос изначально был странным, странным, поскольку в нем содержалось какое-то нелогичное поведение, которое, как указывалось в OP, нельзя было решить с помощью атрибута p:resetInput или resetValues="true" в p:ajax.

Дополняет @Alessandro отзывчивостью на комментарии, создавая сначала [mcve], а затем в чате. Спасибо за это, вознаграждение по сравнению с некоторыми другими людьми, которые не видят значение [mcve] и активно отвечают.

Первым делом я изменил некоторые нелогичные вещи в коде, которые могут быть не связаны

  • Тип в бэк-бине для selectedItem от String до int, поскольку именно так оно и было.
  • Измените поля с String на int, поскольку они имеют p:inputNumber
  • Установите поля для null вместо пустой строки при изменении выбора.

Java-код:

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "myBean")
@SessionScoped
public class MyBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private int selectedItem;

    private Integer field1, field2, field3;

    public int getSelectedItem() {
        return selectedItem;
    }

    public void setSelectedItem(final int selectedItem) {
        this.selectedItem = selectedItem;
    }

    public Integer getField1() {
        return field1;
    }

    public void setField1(final Integer field1) {
        this.field1 = field1;
    }

    public Integer getField2() {
        return field2;
    }

    public void setField2(final Integer field2) {
        this.field2 = field2;
    }

    public Integer getField3() {
        return field3;
    }

    public void setField3(final Integer field3) {
        this.field3 = field3;
    }

    public void myList_change() {

        if (selectedItem < 1) {
            setField1(null);
        }
        if (selectedItem < 2) {
            setField2(null);
        }
        if (selectedItem < 3) {
            setField3(null);
        }
    }

    public void submit() {
    }
}

В xhtml I

  • Удалил field1 field2 field3 из атрибута process, так как он показался бесполезным (отправка происходит в 'submit', ajax submit не требуется).
  • Также удалил их из атрибута update (изменение поля становится обязательным после того, как изменение не требует обновления)
  • Изменен actionListener на p:commandButton на `action

XHTML-код

<?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:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Example</title>
</h:head>
<h:body bgcolor="white">
    <h:form id="myForm">
        <p:messages showDetail="true" />
        <p:selectOneMenu id="myList" value="#{myBean.selectedItem}">
            <f:selectItem itemLabel="1" itemValue="1" />
            <f:selectItem itemLabel="2" itemValue="2" />
            <f:selectItem itemLabel="3" itemValue="3" />
            <p:ajax listener="#{myBean.myList_change}"
                process="myList"/>
        </p:selectOneMenu> <br/> 

        <p:inputNumber id="field1" value="#{myBean.field1}" required="true" decimalPlaces="0" />
        <p:inputNumber id="field2" value="#{myBean.field2}" required="#{myBean.selectedItem gt 1}" decimalPlaces="0" />
        <p:inputNumber id="field3" value="#{myBean.field3}" required="#{myBean.selectedItem gt 2}" decimalPlaces="0" />

        <p:commandButton value="submit" action="#{myBean.submit}" update="@form"/>

    </h:form>
</h:body>
</html>

А потом для меня это начало «работать». В чате стало очевидно, что у OP есть фиксированный список полей в процессе и атрибуты обновления по определенной причине.

  • В атрибуте update, например, когда выбор был изменен, например, с. 3–2, 3-е поле может быть очищено (установлено в бине), требуя «upate», чтобы сделать его пустым.
  • В атрибуте процесса, например, когда выбор был изменен на, например, 3, 2-е поле (не установлено / не очищено в компоненте) будет отправлено и обновлено. Если бы его не было в атрибуте процесса, исходное значение из bean-компонента было бы возвращено обратно, фактически перекрывая значение, которое мог ввести пользователь.

Но эта комбинация была причиной странного поведения, поскольку, если что-то обрабатывается, оно тоже проверяется (в данном случае это связано с тем, что требуется или нет). Имея три пустых поля, установка выбора 3 и отправка всех трех полей не удастся, так как 2 пустые, но «3» также не будет помещено в модель. Я бы заподозрил, что resetValues поможет и здесь, но это не помогло (не для меня). Но что эффективно хотел OP - это условно обновить поле ввода. Условие для этого уже находится в компоненте, и вы можете просто добавить обновление определенного поля, которое тоже там меняется

public void myList_change() {

    if (selectedItem < 1) {
        setField1(null);
    }
    if (selectedItem < 2) {
        setField2(null);
        PrimeFaces.current().ajax().update("myForm:field2");
    }
    if (selectedItem < 3) {
        setField3(null);
        PrimeFaces.current().ajax().update("myForm:field3");
    }
}

Абсолютно не нужно, чтобы поля 1, 2 и 3 были в атрибуте процесса или обновления, и все работает как требуется (каламбур предназначен)

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