4

I have a JSF page with a few fields. I followed this tutorial from BalusC and all is good. I then added RichFaces support to it, which is working fine. I can see popups etc working.

Now what I am trying to do is that once a person has been registered, I want to show the name in the popup (this is also fine I can see that in the popup). Then I want to be able to change that name inside the popup and have that reflected in the parent, but I have no clue how to do that. Please have a look.

XHTML Page

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">
<h:head>
    <title>Registration</title>
</h:head>
<h:body>
    <h:form>
        <h:panelGrid columns="3">
            <h:outputLabel for="username">Username</h:outputLabel>
            <h:inputText id="username" value="#{register.user.username}"
                required="true">
                <f:ajax event="blur" render="usernameMessage" />
            </h:inputText>
            <h:message id="usernameMessage" for="username" />

            <h:outputLabel for="password">Password</h:outputLabel>
            <h:inputSecret id="password" value="#{register.user.password}"
                required="true" redisplay="true">
                <f:ajax event="blur" render="passwordMessage" />
            </h:inputSecret>
            <h:message id="passwordMessage" for="password" />

            <h:outputLabel for="email">Email</h:outputLabel>
            <h:inputText id="email" value="#{register.user.email}"
                required="true">
                <f:ajax event="blur" render="emailMessage" />
            </h:inputText>
            <h:message id="emailMessage" for="email" />

            <h:outputLabel for="birthdate">Birthdate (yyyy-MM-dd)</h:outputLabel>
            <h:inputText id="birthdate" value="#{register.user.birthdate}">
                <f:convertDateTime pattern="yyyy-MM-dd" />
                <f:ajax event="blur" render="birthdateMessage" />
            </h:inputText>
            <h:message id="birthdateMessage" for="birthdate" />

            <h:panelGroup />
            <h:commandButton value="Register" action="#{register.submit}">
                <f:ajax execute="@form" render="@form" />
            </h:commandButton>
            <h:commandButton value="Edit Name in Popup">
                <rich:componentControl target="popup" operation="show" />
            </h:commandButton>
            <h:messages globalOnly="true" layout="table" />
        </h:panelGrid>
        <rich:popupPanel id="popup" modal="true" resizeable="true"
            onmaskclick="#{rich:component('popup')}.hide()">
            <f:facet name="header">
                <h:outputText value="Simple popup panel" />
            </f:facet>
            <f:facet name="controls">
                <h:outputLink value="#"
                    onclick="#{rich:component('popup')}.hide(); return false;">
                    X
                </h:outputLink>
            </f:facet>

            <h:panelGrid columns="3">
                <h:outputLabel for="username2">Username</h:outputLabel>
                <h:inputText id="username2" value="#{register.user.username}"
                    required="true">
                </h:inputText>
                <h:commandButton value="Register" action="#{register.update}">

                </h:commandButton>
            </h:panelGrid>

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

Java class

package com.example;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class Register implements Serializable {

    private static final long serialVersionUID = 1L;

    private User user;

    public Register() {
        user = new User();
    }

    public void submit() {
        FacesMessage message = new FacesMessage("Registration succesful!");
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public void update() {
        FacesMessage message = new FacesMessage("Update succesful!");
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public User getUser() {
        return user;
    }

}

User Class

 package com.example;

    import java.io.Serializable;
    import java.util.Date;

    public class User implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long id;
        private String username;
        private String password;
        private String email;
        private Date birthdate;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        public Date getBirthdate() {
            return birthdate;
        }
        public void setBirthdate(Date birthdate) {
            this.birthdate = birthdate;
        }

    }

Updated bit after Arjan Tijms' suggestion

<h:form id="form2">
    <rich:popupPanel id="popup" modal="true" resizeable="true" onmaskclick="#{rich:component('popup')}.hide()">
        <f:facet name="header">
            <h:outputText value="Simple popup panel" />
        </f:facet>
        <f:facet name="controls">
            <h:outputLink value="#" onclick="#{rich:component('popup')}.hide(); return false;">
                X
            </h:outputLink>
        </f:facet>

        <h:panelGrid columns="3">
            <h:outputLabel for="username2">Username</h:outputLabel>
            <h:inputText id="username2" value="#{register.user.username}" required="true"></h:inputText>
            <h:commandButton value="Register" action="#{register.update}">
                <f:ajax execute="@form" render=":form" />
            </h:commandButton>
        </h:panelGrid>

    </rich:popupPanel>
</h:form>
teobais
  • 2,820
  • 1
  • 24
  • 36
Java Ka Baby
  • 4,880
  • 11
  • 39
  • 51

2 Answers2

4

Just move the rich:popupPanel out of the main form, and give it it's own form. If you then submit the form that's in the dialog, the entire page will re-render.

Since the backing bean is view scoped, the previously user data will be retained and only the user name will be updated with whatever you entered in the dialog.

Additionally, you can submit the form via AJAX, give the main form an ID and re-render that.

E.g.

<rich:popupPanel id="popup" modal="true" resizeable="true" onmaskclick="#{rich:component('popup')}.hide()">
    <f:facet name="header">Simple popup panel</f:facet>
    <h:form id="form2">
         <h:outputLabel for="username2" value="Username"/>
         <h:inputText id="username2" value="#{register.user.username}" required="true"/>
         <a4j:commandButton value="do" action="#{register.update}" render="form" oncomplete="#{rich:component('popup')}.hide()"/>                 
     </h:form>
</rich:popupPanel>

I used the A4J commandButton here which has a convenient oncomplete attribute. You can do a similar thing with the onevent attribute on the standard ajax tag, but using slightly more code.

Do note that if the main form has validation errors, it's without any counter measures impossible to update from the other form (if you run into that, you'd best open a new question for that particular situation).

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
  • Thanks for replying and I have understood what you are saying (I think :) ) but failing to get the code right . I have given the original form id named "form" and moved the panel outside in a an other form but popup is still not closing nor updating debug point shows that it is hitting the method but screen flow is not right please see my updated question towards the end. Much appreciate your response. Thanks – Java Ka Baby Aug 21 '11 at 03:19
  • The forms needs to be *in* the panel, not around it. Additionally the button should close the dialog (e.g. via script). – Arjan Tijms Aug 21 '11 at 09:15
  • Can not thank enough you are great.Do you and Blusc work togather :) – Java Ka Baby Aug 21 '11 at 11:26
0

It's already answered but I had a similar problem. My view has a <rich:dataTable> to show data and I want to filter the results with chosen items in a <rich:popupPanel>. I had the same problem: choosing an option didn't update the table (using <a4j:ajax> event).

The popups are, by default attached to the <body> tag. So, I added domElementAttachment="form" to the <rich:popupPanel> and it worked.

kauedg
  • 827
  • 8
  • 20