3
votes

I found a problem while using the bootsfaces inputText with ajax. I'm using JSF 2.2, Bootsfaces 0.8.1 and Primefaces 5.3.

I'm trying to enter a date value into the inputText field. As soon as I enter the last value for the date the inputText should trigger the change event. At this point I would like to use ajax for calling a bean method. The problem is, that my field loses focus as soon as I try to enter the last value and the method's never been invoked.

So I tried a bit with Primefaces and it almost works like I wanted. At this point I got different questions:

  1. Why does my inputText field lose the focus while entering the last value? (Bootsfaces)
  2. Why is the bean method never called after I lose the focus? (Bootsfaces)
  3. Is it possible to invoke the bean method after the bean value has been set by the field? (Primefaces)

I added the code below, so maybe you can reproduce this behaviour.

test.xhtml - sample xhtml with both primefaces and bootsfaces fields

<?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:b="http://bootsfaces.net/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <meta charset="UTF-8"/>
    </h:head>

    <h:body>
        <h:form id="form">
            <b:panel id="filterPanel" title="Filter properties" immediate="true" collapsed="false" collapsible="true">
                <b:row>
                    <b:column span="12">
                        <b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
                            <f:ajax event="change" listener="#{test.searchA()}"/>
                        </b:inputText>
                    </b:column>
                </b:row>
                <b:row>
                    <b:column span="12">
                        <p:inputText id="dateB" type="date" value="#{test.dateB}" immediate="true" class="form-control">
                            <p:ajax event="change" listener="#{test.searchB()}"/>
                        </p:inputText>
                    </b:column>
                </b:row>
            </b:panel>
        </h:form>
    </h:body>
</html>

TestBean.java - my bean for setting the values and calling methods

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name = "test")
@ViewScoped
public class TestBean {

    private String dateA;
    private String dateB;

    public void searchA() {
        System.out.println("Search A");
    }

    public void searchB() {
        System.out.println("Search B");
    }

    public String getDateA() {
        return dateA;
    }

    public void setDateA(String dateA) {
        this.dateA = dateA;
        System.out.println(dateA);
    }

    public String getDateB() {
        return dateB;
    }

    public void setDateB(String dateB) {
        this.dateB = dateB;
        System.out.println(dateB);
    }

}

Please help me finding a solution or explain me what I'm doing wrong here.

Thanks mweber

1
You can try BootsFaces 0.8.5 we released 2 days ago. It seems we solved some bugs concerning this question in there. (The listener is called properly) However, I'm currently not sure, why the backing bean method is called first sometimes and don't have the time to research yet. So sadly I cannot provide a full answer just now, but can recommend to try the new version :)Zhedar
Also I couldn't reproduce the losing of the focus at all. Which browser are you using?Zhedar
I'm using Chrome 50.0.2661.94. I already tried with Bootsfaces 0.8.5. It works fine. The problem is that I cannot use 0.8.5 because of a different problem/bug with this version. It's possible that I'll ask a new question about the problem in 0.8.5 but currently I don't have time at all. I think I'll try a workaround without ajax to call the method with a button or something like this. Or I try Primefaces again with changing the phase when the listener gets invoked.mweber
Feel free to report that bug to us at the bug tracker. We're planning to put another bug fix release out soon, so we may fix that on the way.Zhedar
I don't get your third question. When I tried the demo, searchB() was called on every keystroke as soon as the input was a valid data.Stephan Rauh

1 Answers

2
votes

You've found a subtle difference between BootsFaces and PrimeFaces. I recommend you always define the values of process and update for the sake of clarity. In your case,

    <b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
        <f:ajax event="change" listener="#{test.searchA()}" render="@none"/>
    </b:inputText>

makes the BootsFaces input field behave exactly like its PrimeFaces counterpart.

The default values of update and process are different. Since BootsFaces 0.8.5, the default values are:

  • process="@form" for <b:commandButton /> and <b:commandLink />
  • process="@this" for every other BootsFaces component
  • update="@form" for every BootsFaces component

According to Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes, the PrimeFaces default values are: enter image description here

For the sake of convenience, here's my version of the XHTML file:
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" xmlns:b="http://bootsfaces.net/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">

        <h:head>                                                                                                            
            <meta charset="UTF-8"/>                                                                                         
        </h:head>                                                                                                           

        <h:body>                                                                                                            
            <h:form id="form">                                                                                              
                <b:panel id="filterPanel" title="Filter properties" immediate="true" collapsed="false" collapsible="true">  
                    <b:row>                                                                                                 
                        <b:column span="12">                                                                                
                            <b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
                                <f:ajax event="change" listener="#{test.searchA()}" render="@none"/>                        
                            </b:inputText>                                                                                  
                        </b:column>                                                                                         
                    </b:row>                                                                                                
                    <b:row>                                                                                                 
                        <b:column span="12">                                                                                
                            <p:inputText id="dateB" type="date" value="#{test.dateB}" immediate="true" class="form-control">
                                <p:ajax event="change" listener="#{test.searchB()}"/>                                       
                            </p:inputText>                                                                                  
                        </b:column>                                                                                         
                    </b:row>                                                                                                
                </b:panel>                                                                                                  
            </h:form>                                                                                                       
        </h:body>                                                                                                           
    </html>                                                                                                                 

I've tested it with BootsFaces 0.8.5.