jsfprimefacesfocusbootsfacesajax-update

Bootsfaces inputText loses focus caused by using ajax and updating value in bean


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


Solution

  • 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:

    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.