2

I'm not sure how to properly ask that question but I will try like that: Question is about Primefaces, JSF2 Calendar in composite.. I want to catch an event that is called after that calendar was changed (and catch its new Date value).

my composite xhtml:

    <composite:interface componentType="myComponent">            
        <composite:attribute name="value" required="true"/>            
    </composite:interface>

    <composite:implementation>
            <p:calendar 
                id="tempCalendar"
                pattern="dd.MM.yyyy" value="#{cc.attrs.value}" 
                valueChangeListener="#{cc.valueChanged}"                   
                validator="DateValidator" converter="MyDateConverter" showOn="button" showButtonPanel="true" navigator="true" >

                <p:ajax event="dateSelect"  update="@this" listener="#{cc.event1}"/>                   
            </p:calendar>
    </composite:implementation>

my composite's bean:

public void valueChanged(Object event) {

    log("valueChanged");
}

public void event1(AjaxBehaviorEvent ab) {
    log("Event1");
    if (ab != null && ab.getSource() != null && ab.getSource() instanceof Calendar) {
        //....
    }
}

page where I'm using composite:

<cc:inputdate value="#{mainBean.aDate}" />

In code above I'm trying to do catch new value in compotents bean, but log looks like that:

  1. valueChanged

  2. Event1

  3. setADate

When I'm in valueChangedListener I still have old value of calendar. New value is set at the end.

So, first of all I want to have new value in my composites bean.. but my main question is:

How to implement an event in my mainBean, that will catch new value of that calendar when changed ?


EDIT: My composite now:

<composite:interface componentType="myComponent">
    <composite:attribute name="value" required="true"/>
    <composite:attribute
            name="myListener"
            method-signature="void listener()" />

</composite:interface>

<composite:implementation>
    <h:panelGroup id="container">

        <p:calendar
            value="#{cc.attrs.value}"
            valueChangeListener="#{cc.valueChanged}"
            <p:ajax event="dateSelect"  update="@this,:buttonpanel" listener="#{cc.attrs.myListener}"/>
        </p:calendar>

    </h:panelGroup>
</composite:implementation>

And that way I call it in my main page (connected with mainBean):

<cc:inputdate 
    value="#{mainBean.item.myDate}" 
    myListener="#{mainBean.event1}"/>

I want to catch evet AFTER change in mainBean.java...

Marshall
  • 1,195
  • 6
  • 30
  • 47

2 Answers2

2

You can access it from the component's local value. i.e.,

My Test Facelet

<!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:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<f:view>
    <h:head />
    <h:body>
        <h:form>
            <p:calendar pattern="dd.MM.yyyy">
                <p:ajax event="dateSelect" process="@this"
                    listener="#{testBean.event1}" />
            </p:calendar>
        </h:form>
    </h:body>
</f:view>
</html>

My test bean

import org.primefaces.component.calendar.Calendar;

@ManagedBean(name="testBean")
@SessionScoped
public class TestBackingBean 
{
    public void event1(AjaxBehaviorEvent ab) 
    {
        if (ab != null) 
        {
            Calendar calendar =  (Calendar) ab.getSource();

            if(calendar != null)
            {
                System.out.println(String.format("Newly selected value: %s", 
                        calendar.getLocalValue()));
            }
        }
    }
}
maggu
  • 1,201
  • 9
  • 9
  • thanks for an answer but... first of all: 1) I made a mistake in my code, I pasted old version of event1.. event1 method cannot have AjaxBehaviorEvent as a parameter... is should look like event1() with no parameters. 2) And second.. maybe there is other event then dateSelect? dateSelect is before setting value to its variable. I need an event like "dateWASChanged".. – Marshall Mar 24 '13 at 09:17
  • in the above example I pasted, the new value of the calender's selected date is being retrieved (thats the local value) even before the setter method for the selection is fired. I thought that was the need you had to address. Is it not? – maggu Mar 24 '13 at 10:23
  • well, I get new value in event1 event now (kind of different way, but still). Right now I'm trinig to fire this event in my mainBean -bean which is connected with xhtml that shows my composite. Please look at my edit.. – Marshall Mar 24 '13 at 15:37
2

You've specified it as value attribute of the composite, so it should be available in any of the backing component's methods by the inherited UIComponent#getAttributes() as follows:

Object value = getAttributes().get("value");
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks, it works, I've new value in component backingbean. But it would be really helpfull to trigger that change event in mainBean (that is connected with page where my composite is called). So in my case, not in myComponent.java but in mainBean.java. In .NET I would declare event "changed", define and that's it.. Here in JSF2 I know that soultion must be close... – Marshall Mar 24 '13 at 14:38
  • But how to get there a new value? When event occurs, model is still not set. So I cannot use mainBean.getSomething().. – Marshall Mar 25 '13 at 12:57
  • Model is definitely updated at the point `` is invoked. Perhaps you're confusing it with `valueChangeListener`? See also http://stackoverflow.com/questions/11879138/when-to-use-valuechangelistener-or-fajax-listener/11883021#11883021 – BalusC Mar 25 '13 at 12:58
  • Thanks BalusC, it's hard to explain but it works what I needed to work. Thanks – Marshall Mar 28 '13 at 10:58