0

I have the following scenario and a problem with a form submit using ajax:

<?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" xml:lang="en" lang="en"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<h:outputStylesheet library="css" name="employee.css"  />

    <title>Welcome</title>
</h:head>
<h:body>
<h:form>
    <h:panelGrid>
        <h:outputLabel for="first_name" value="First Name" />
        <h:inputText id="first_name"
            value="#{employeeController.model.firstName}" required="true" />

        <h:outputLabel for="last_name" value="Last Name" />
        <h:inputText id="last_name"
            value="#{employeeController.model.lastName}" required="true" />

        <h:outputLabel for="email" value="Email" />
        <h:inputText id="email" value="#{employeeController.model.email}"
            required="true" />

        <h:outputLabel for="phone_number" value="Phone" />
        <h:inputText id="phone_number"
            value="#{employeeController.model.phoneNumber}" required="true" />

        <h:outputLabel for="salaray" value="Salary" />
        <h:inputText id="salaray" value="#{employeeController.model.salary}"
            required="true" />

        <h:commandButton value="Save(AJAX)">
            <f:ajax execute="@form" render="modelOutput"/>
        </h:commandButton>
    </h:panelGrid>
</h:form>
    <h:panelGrid id="modelOutput">
        <h:outputText id="fName"
            value="First Name: #{employeeController.model.firstName}" />
        <h:outputText value="Last Name: #{employeeController.model.lastName}" />
        <h:outputText value="E-Mail: #{employeeController.model.email}" />
        <h:outputText
            value="Phonenumber: #{employeeController.model.phoneNumber}" />
        <h:outputText value="Salary: #{employeeController.model.salary}" />
    </h:panelGrid>
</h:body>
</html>

The model is a simple javabean with just getter and setter for the values.

When I click on the ajax Button I can see a request going to the server, holding my Form-Data. I get a partial-response back with the hard-coded values for the outputtexts - but not with the model values. I can see that also my setters are not called.

If I change the ajax execute to a specific inputText component id - than it works for that one.

What am I missing?

-- EmployeeBean

public class EmployeeBean {

    private String firstName;
    private String lastName;

    private String email;
    private String phoneNumber;
    private Float salary;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public Float getSalary() {
        return salary;
    }

    public void setSalary(Float salary) {
        this.salary = salary;
    }



}

EmployeeController:

@ManagedBean
@RequestScoped
public class EmployeeController {

    private EmployeeBean model;

    @PostConstruct
    public void init() {
        model = new EmployeeBean();
    }

    public EmployeeBean getModel() {
        return model;
    }

    public void clearAjax(AjaxBehaviorEvent ajaxBehaviorEvent) {
        clearUiAreaForm(ajaxBehaviorEvent.getComponent());
        System.out.println("Form cleared");
    }
}
Stefan
  • 2,603
  • 2
  • 33
  • 62
  • Please improve your question by editing the code. It is not complete. And sure you don't get any errors? – Kukeltje Jul 20 '17 at 14:22
  • I don't see a reason why anybody would love to see boilerplate code in questions but I will enhance it for those that seem to love that ;) Do you also want to see the mentioned Model class that works according to JavaBean spec? I feel very free to provide every line anybody wants to see. -- Yes I am sure I don't get any errors as I can see that I get an error-free partial-response and I can see that the submitted request holds the form values. There is no error in the javascript console in the browser and no error in my application server log. – Stefan Jul 20 '17 at 14:27
  • I never requested boilerplate etc... But I noticed parts of what you did post were hidden due to bad formatting. Next time please make it make it an [mcve]... Do you run the application in development mode? – Kukeltje Jul 20 '17 at 14:48
  • Read these... Good luck... https://stackoverflow.com/questions/2118656/commandbutton-commandlink-ajax-action-listener-method-not-invoked-or-input-value and https://stackoverflow.com/questions/8634156/how-to-find-out-client-id-of-component-for-ajax-update-render-cannot-find-compo – Kukeltje Jul 20 '17 at 14:53
  • So the actual problem was a failing validation - I was only able to track this by checking exactly the lifecycle - phase 4 and 5 were missing. I still don't know why they fail silently in ajax but it did. – Stefan Jul 20 '17 at 15:14

1 Answers1

0

So I found the reason and the solution.

The main problem is following:

From a lifecycle listener I saw that the processing on server side skipped phases 4 & 5. What is the reason for this? Well - phase 3 is about validation. My form had some validation restrictions, i.e. required.

I did not fill out all the input fields and therefor validation phase was not successfull. JSF then skips Phase 4 & 5 - now we also know why the setters were not called.

Here comes the kicker: It fails completely silently! You do get a good ajax request containing the form parameters. And you do get a good partial-response - but without dynamic values from the bean.

There was no error message in the application log (well, there should also be none but this leads you to knowing there was no exception). But apparently Ajax does not fill any component like it is done when you use a full page request. You do not have any information about the failing validation. If you do not use a lifecycle information output than you can't see it in any way.

Additionally, the only thing I was able to find out is adding a component that renders some information. Add a hardcoded outputText that will only be rendered on the information of facesContext.validationFailed and render it by ajax facelet.

<h:commandButton value="Save (AJAX)">
                <f:ajax execute="@form" render="modelOutput global_flag_validation_failed_render" />
            </h:commandButton>
            <h:messages />
            <h:panelGroup id="global_flag_validation_failed_render">
                <h:outputText id="global_flag_validation_failed" value="Fehler in Ajax aufgetreten!"
                    rendered="#{facesContext.validationFailed}" />
            </h:panelGroup>

I have no idea if this is the specified and wanted behaviour of Mojarra 2.2.14 - does anybody know it?

Stefan
  • 2,603
  • 2
  • 33
  • 62
  • Sorry, I know this is years later, but it may have shown on-screen if you'd had an `h:message` component for the field that was updated? – Evan Knowles Mar 26 '21 at 07:28