0
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">

    <f:view>

        <h:head>
        </h:head>

        <h:body>

            <div style="margin-left: auto; margin-right: auto; width: 300px;">

                <h1>User Manager</h1>

                <h:form id="user-input-form">

                    <p:panelGrid id="input"
                                 layout="grid"
                                 columns="2">

                        <p:outputLabel for="user-name" value="User name" />
                        <p:inputText id="user-name"
                                     value="#{debugUserManager.selectedEntity.name}"
                                     required="true"
                                     style="width: 125px;">
                        </p:inputText>
                        <p:outputLabel for="password" value="Password" />
                        <p:password id="password"
                                    value="#{debugUserManager.selectedEntity.password}"
                                    required="true"
                                    redisplay="true"
                                    style="width: 125px;">
                        </p:password>

                    </p:panelGrid>

                    <p:messages severity="error" />

                </h:form>

                <h:form id="user-button-form">

                    <p:commandButton id="save-button"
                                     icon="fa fa-save"
                                     value="Save"
                                     action="#{debugUserManager.save()}"
                                     process="@form :user-input-form"
                                     update="@form :user-input-form"
                                     style="margin-top: 10px;" />

                    <p:growl id="growl"
                             showSummary="true"
                             showDetail="false"
                             sticky="false"
                             life="10000" />

                </h:form>

            </div>            

        </h:body>

    </f:view>

</html>

Here's the manager bean:

@Named
@ViewScoped
public class DebugUserManager implements Serializable
{
    private static final long serialVersionUID = 1L;

    private SimpleUser selectedEntity;

    @PostConstruct
    public void init()
    {
        this.selectedEntity = new SimpleUser();
    }

    public SimpleUser getSelectedEntity()
    {
        return selectedEntity;
    }

    public void setSelectedEntity( SimpleUser selectedEntity )
    {
        this.selectedEntity = selectedEntity;
    }

    public void save()
    {
        System.out.println( "Saving simple user: " + selectedEntity.getName() + "//" + selectedEntity.getPassword() );

        FacesContext.getCurrentInstance().addMessage( "user-button-form:growl", new FacesMessage( "User successfully saved. User name = " + selectedEntity.getName() + ", password = " + selectedEntity.getPassword() ) );
    }

    public class SimpleUser implements Serializable
    {
        private static final long serialVersionUID = 1L;

        private String name;
        private String password;

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }

        public String getPassword()
        {
            return password;
        }

        public void setPassword(String password)
        {
            this.password = password;
        }
    }
}

Have a look at the structure. I use two forms, one for the inputs and one for the button(s). This example stems from a bigger context.

In the save button, I use process="@form :user-input-form" to submit both forms.

I'd expect the validation to kick in on the first form to block the action from being called, but this isn't happening. Instead the action is called and because the first form isn't submitted, any value entered into the inputs will end up as null on the entity:

enter image description here

QUESTION:

Is this expected behavior??

If Y: Is this specified anywhere? What's the logical explanation?

If N: Is it a bug in Mojarra? Is this a bug in PrimeFaces? Anything else that could be wrong? ‍♂️

I've tried PrimeFaces versions 6.2, 7.0 and 8.0-SNAPSHOT, but all of them expose the described problem.

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
Kawu
  • 13,647
  • 34
  • 123
  • 195
  • See point 2 of dupe. It's in HTML specification. – BalusC Jan 17 '20 at 19:29
  • 1
    @BalusC: I dare to disagree. This is not a nested form. I've seen a similar case working in PrimeFaces but am pretty sure it was by accident due to the way the ajax submission fields were 'gathered' in the client when using a process attribute and not on purpose. It might also have been related to the jsf version for the server side processing. So my answer to this question would be not 'y' and not 'n' but rather: behaviour is undefined, don't use a construct like this. – Kukeltje Jan 17 '20 at 19:56
  • 1
    Compliments for the [mcve] btw. We see this waaaaay to little. – Kukeltje Jan 17 '20 at 19:58
  • Small addition (correction): there is some info in the link refered to in #2 but way down. And if you are sure you don't have nested form (the core of #2) everybody would have stopped reading before reaching tge paragraph (I initially did) so @BalusC is right, but it might get a more prominent place since other statements about the process attribute suggests it might work. (You cover the fields in your process attribute and maybe referring to them by id explicitly might make it work (since I've seen something like this working) – Kukeltje Jan 17 '20 at 20:05
  • I knew I posted something somehere and remembered it was related to partial submission and found post see almost at the end in https://forum.primefaces.org/viewtopic.php?t=50603 – Kukeltje Jan 17 '20 at 20:15
  • Yes, this is **not** a nested form. I'm aware of that problem, see my own answer there... – Kawu Jan 17 '20 at 22:36
  • 2
    From point 2: *"You can use UIForm components in parallel, but they won't process each other during submit."*. Just put the button in same form as inputs. That's also how HTML requires it. – BalusC Jan 17 '20 at 22:41
  • I would never have found and understood that sentence, given that right before, the issue is about nested forms. Parallel forms, hmmm, very interesting. As usual, thanks a lot, BalusC. – Kawu Jan 17 '20 at 22:45
  • But when using partial submit, primefaces **does** process the other form at least from the client side if the other form is referenced in the process attribute. I'll try to create an example. Plain html does/http soespt but using ajax it is not just that anymore but also javascript. But in the end, don't rely on it. It is never actually needed – Kukeltje Jan 18 '20 at 07:36

0 Answers0