Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling listener in bean when pressing enter in JSF 2 h:inputText

Tags:

ajax

jsf-2

I am currently writing my first JSF 2 page and I would like to implement the following: When the user writes something in a h:inputText element and presses the enter button another h:inputText should get updated with some data out of a database.

My testpage contains 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:f="http://java.sun.com/jsf/core"      
      xmlns:h="http://java.sun.com/jsf/html">

    <h:body>
        <h3>JSF 2.0 Example</h3>

        <h:form>

           <h:inputText id="inputField" value="#{helloBean.name}">
              <f:ajax render="output" execute="inputField" event="keypress" listener="#{bean.myChangeListener}" /> 
           </h:inputText>
           <h2><h:outputText id="output" value="#{helloBean.name}" /></h2>  

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

The Bean contains all neccessary getters and setters and this function:

public void myChangeEvent( AjaxBehaviorEvent event) {

        System.out.println( "VALUE CHANGED" );

}

UPDATE 2013-12-16:

After hours of troubleshooting I found the problem why nothing was submitted when leaving the textfield or pressing enter in the textfield. My web application was created with templates and in the template for my page header was an 'a4j:status' tag and this was in conflict with JSF 2. After removing the 'a4j:status'-line the myChangeEvent method gets called when I click somewhere else on the web page after editing the textfield value.

But there is stil the problem, that the whole page gets submitted when clicking on enter after changing the textfield value. This is because I have a button at the bottom of the page thats saves the user input and therefore submits the whole page, which is OK. But this button should not be called when pressing enter in the textfield. What do I have to add to my existing code?

UPDATE 2013-12-17: After some trouble with JS I finally got it working with the help of L-Ray (thanks again). Here I will show the final and working version with JQuery:

<h:inputText id="inputField" value="#{helloBean.name}" >
    <f:ajax render="output" execute="inputField" event="change"  listener="#{helloBean.myChangeEvent}" />
</h:inputText>
<h2><h:outputText id="output" value="#{helloBean.name}" /></h2>  

<script type="text/javascript">
    $(document).ready(function() {

        $( "#mainForm\\:inputField" ).bind('keypress', function(e) {

            var keyCcode = e.keyCode || e.which;

            // Enter was pressed
            if(keyCcode == 13) { 
                e.target.blur();
                e.stopPropagation();
                return false;
            } else {
                return true;
            }
        });
    });
</script>
like image 737
Metalhead89 Avatar asked Dec 13 '13 11:12

Metalhead89


1 Answers

I would suggest not using the listener="#{bean.myChangeEvent}" attribute in the inputText (it expects the ValueChangeEvent), but a listener call from the f:ajax, which expects either no parameter or a AjaxBehaviorEvent.

Also I would suggest not to listen to a keypressed-event inside the f:ajax but for a change-event, together with an javascript - keypress - event.

So as a solution, maybe the following code might work for you...

<h:form>
   <h:inputText id="inputField" value="#{helloBean.name}" 
        onkeypress="if (event.keyCode == 13) {event.target.blur();event.stopPropagation();return false;} else {return true;};">
        <f:ajax render="output" execute="inputField" event="change" 
             listener="#{helloBean.myChangeEvent}"/> 
       </h:inputText>
       <h2><h:outputText id="output" value="#{helloBean.name}" /></h2>  
</h:form>

an the managed bean

public void myChangeEvent( AjaxBehaviorEvent e ) {
    System.out.println( "VALUE CHANGED" );
}

The event object will be given into our javascript part by the browser himself - So running this outside a on* - attribute won't work.

The javascript method event.stopPropagation() is an jQuery method or seamingly also a javascript method (see W3C school), preventing other events to be called bubbling down the DOM-tree.

like image 162
L-Ray Avatar answered Oct 19 '22 07:10

L-Ray