0

I try to AJAXify a simple commandButton in order to send AJAX request without refreshing the whole page. My xhtml file includes the following code:

<?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:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core">

<h:head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Test</title>
</h:head>

<h:body>
    <h:form id="form">
        <h:inputText id="name" value="#{test.name}"></h:inputText>
        <h:commandButton value="Welcome Me">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
        <h2>
            <h:outputText id="output" value="#{test.sayWelcome}" />
        </h2>
    </h:form>
</h:body>
</html>

My backing bean is the following:

import java.io.Serializable;
import javax.faces.bean.ViewScoped;
import javax.inject.Named;

@ViewScoped
@Named("test")
public class TestBackingBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    public String getName() {
        return name;
    }

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

    public String getSayWelcome() {
        // check if null?
        if ("".equals(name) || name == null) {
            return "";
        } else {
            return "Ajax message : Welcome " + name;
        }
    }
}

However, when I click on commandButton the form is submitted and the whole page is refreshed.

I would like to avoid using additional JSF frameworks.

Thank you in advance.

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
Puma
  • 135
  • 1
  • 12
  • **YOU** update the `@form` which is sort of the whole page (besides the body and head) so it seems as designed (by you) that the 'whole page' is updated. Not related: you use the wrong `@Viewscoped` for the `@Named`, use the `javax.faces.view.ViewScoped` one – Kukeltje Jul 28 '18 at 08:53
  • Indeed the form is sort of the whole page. But when I click on commandButton the form is submitted without using AJAX. That is, if I press F5 (for e.g. in Firefox), I get this message: "To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier." – Puma Jul 28 '18 at 09:04
  • so the behaviour (debugged network traffic?) is identical with or without the `f:ajax` – Kukeltje Jul 28 '18 at 10:27
  • Yes, the network traffic is identical with the one without f:ajax. – Puma Jul 30 '18 at 05:31

2 Answers2

0

Can you tried the execute and render properties:

 <h:form id="form">
    <h:inputText id="name" value="#{test.name}"></h:inputText>
    <h:commandButton value="Welcome Me" action=#{test.sayWelcome()}>
        <f:ajax execute="name" render="output" />
    </h:commandButton>

</h:form>
<h2> <!-- Outside the Form! -->
   <h:outputText id="output" value="#{test.message}" />
</h2>

Bean:

public class TestBackingBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;
    private String message;

    public String getName() {
        return name;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String value) {
        this.message = value;
    }

    public void sayWelcome() {
        // check if null?
        if ("".equals(name) || name == null) {
            message = "";
        } else {
            message = "Ajax message : Welcome " + name;
        }
    }
}
Vinh Can Code
  • 407
  • 3
  • 14
0

The problem here is that you're using the wrong @ViewScoped. It's a mess that's a long time in the making, so condolences I guess.

The version of @ViewScoped you have there wasn't meant to be used with CDI's @Named. As a result, you really don't have a viewscoped bean there - the bean is in the implicit CDI @Dependent scope which will behave a little like the @RequestScoped scope.

In short: use the javax.faces.view.ViewScoped annotation instead and your bean will behave properly.

kolossus
  • 20,559
  • 3
  • 52
  • 104