views:

35

answers:

1

Hello,

This is my code in my managed bean :-

<?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"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"&gt;
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <center>
            <h:form>
                <h2> <u>Select Fruit(s). </u> </h2>

                <!-- Value Change Listener is entirely superflous. You can make a full blown project without requiring the need to ever use this...This is
                just for demo purpose..-->

                <h:selectManyMenu onchange="document.forms[0].submit();" style="height: 200px;font-size: 1.5em;width: 200px;"   >
                    <f:selectItems value="#{actionValueLisBean.fruitsList}" var="fruit" itemLabel="#{fruit}" itemValue="#{fruit}"/>

                    <f:valueChangeListener type="beans.ActionValueLisBean"/>
                </h:selectManyMenu>

                <h3> Your previous selection is :<h:outputText value="#{actionValueLisBean.prevSel}"/></h3>
                <h3>Your current selection is :<h:outputText value="#{actionValueLisBean.currSel}"/></h3>

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

This is my bean :-

package beans;

import com.sun.jmx.remote.internal.ArrayQueue;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;

@ManagedBean
@RequestScoped
public class ActionValueLisBean implements ValueChangeListener {


    private List<String> fruitsList;
    private String currSel;
    private String prevSel;

    public String getCurrSel() {
        return currSel;
    }

    public void setCurrSel(String currSel) {
        this.currSel = currSel;
    }

    public String getPrevSel() {
        return prevSel;
    }

    public void setPrevSel(String prevSel) {
        this.prevSel = prevSel;
    }



    public List<String> getFruitsList() {
        return fruitsList;
    }

    public void setFruitsList(List<String> fruitsList) {
        this.fruitsList = fruitsList;
    }



    public ActionValueLisBean() {
        fruitsList = new ArrayQueue<String>(5);

        fruitsList.add("Apple");
        fruitsList.add("Mango");
        fruitsList.add("Banana");
        fruitsList.add("Peach");
        fruitsList.add("Plum");

    }

    @Override
    public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {

            if(event.getOldValue() != null)
                prevSel = event.getOldValue().toString();
            if(event.getNewValue() != null)
                currSel  = "abc";

    }


}

And then i have prevSel and currSel is bound to h:outputText. But the value is not getting even though the processValueChange is fired correctly and System.out.println(event.getNewValue()); is also working fine. I tried setting different scopes of bean too but no use. I know ValueChangeListener is entirely useless. Still i want to know how it works.

Thanks in advance :)

+2  A: 

I am not sure what you mean with "the value is not getting". You should clarify that bit more.

At least, its sole purpose is to listen on a value change so that you can do some business stuff based on the change such as logging or preloading some stuff related to the new value. When the initial value equals to the submitted value, then this method won't be invoked.

Here's a code snippet to play around with it yourself:

<h:form>
    <p>Input value: <h:inputText value="#{bean.value}" valueChangeListener="#{bean.change}"/></p>
    <p>Old value: <h:outputText value="#{bean.oldValue}" /></p>
    <p>New value: <h:outputText value="#{bean.newValue}" /></p>
    <p><h:commandButton value="submit" action="#{bean.submit}" /></p>
</h:form>

Bean:

package com.example;

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

@ManagedBean
@ViewScoped
public class Bean {

    private String value;
    private String oldValue;
    private String newValue;

    public void submit() {
        System.out.println("Submit: " + value);
    }

    public void change(ValueChangeEvent event) {
        oldValue = (String) event.getOldValue();
        newValue = (String) event.getNewValue();
        System.out.println("Change: " + oldValue + " to " + newValue);
    }

    public String getValue() {
        return value;
    }

    public String getOldValue() {
        return oldValue;
    }

    public String getNewValue() {
        return newValue;
    }

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

}

Update: as per your update: you're using two different instances of the bean. You're actually displaying the values of the managed bean, not of the bean which is newly created by f:valueChangeListener.

BalusC
Hi BalusC, please read my edited post. I am not using valuelistener of component. I am using `f:valueListener`. Can you find bug in my code? I am reading this article :-http://java-server-faces.blogspot.com/2006/04/valuechangelisteners-what-you-need-to.htmlBut it is not working :(
Ankit Rathod
See the update. To fix this problem, go ahead with my proposed approach.
BalusC
Hi BalusC, I didn't quiet understand. So what do i have to do next?
Ankit Rathod
The `f:valueChangeListener` creates a **new** instance of the bean. It is not using the same instance as the input/output components are displaying. You've now two beans and you're displaying values from the "wrong" bean. Use my approach to achieve the requirement you initially had in mind. Use your approach to completely detach listening on change events from the managed bean (and you're not interested in accessing the value change listener bean in the view).
BalusC
Great! Thanks BalusC. Btw, your points have enormously grown! Last time when i used JSF 2.0 in June they were 54.4k. Now they are 82.8k. This way you will even break Jon Skeet's record.
Ankit Rathod