Convert an empty string in your converter to null. That way if the
Date is null in the bean, the converter will convert the empty string
to null, and since both will be null, you will get no change event.

-Andrew

On 7/6/07, Vladimir Isakovich <[EMAIL PROTECTED]> wrote:
Andrew,
thanks for pointing to the source. Aparently this is the exact place.

Now I guess (sorry for guessing, I should take more time and learn the code)
getSubmittedValue() never returns null, the request parameter values
submitted from a page are never nulls; empty strings at the most.
So, should not this method convert them into nulls?

Also, I clearly see here the call to getConvertedValue(context,
submittedValue), and just wonder why I am getting valueChangeEvent fired for
every date on my screen, when they are not changed. ( java.util.Date in
pojo)
I'm displaying oldValue/newValue from the event (toString of cause) and they
look different


vlad

On 7/6/07, Andrew Robinson <[EMAIL PROTECTED]> wrote:
> Best way to answer this is to point you to the UIInput code:
>
> public void validate(FacesContext context) {
> ...
> Object submittedValue = getSubmittedValue();
> if (submittedValue == null) return;
> Object convertedValue = getConvertedValue(context, submittedValue);
> ...
> Object previousValue = getValue();
> setValue(convertedValue);
> setSubmittedValue(null);
> if (compareValues(previousValue, convertedValue))
> {
>    queueEvent(new ValueChangeEvent(this, previousValue, convertedValue));
> }
> ...
> protected boolean compareValues(Object previous,
> Object value)
> {
> return
previous==null?(value!=null):(!previous.equals(value));
> }
>
> So, as you can see the value change event is generated if the
> component's "getValue()" returns an object that is not equal to the
> converted submitted value.
>
>
>
> On 7/6/07, Vladimir Isakovich <[EMAIL PROTECTED]> wrote:
> > Andrew,
> > Are you saying that if in the method called by valueChangeListener I
take:
> > event.getOldValue() - it's not the same as my 'original value' in my
pojo?
> > It's alredy has been converted from say Integer to String?
> >
> > The poin I'm trying to make is why I should add another layer of
protection
> > against valueChangeEvent, when it could be done in JSF.
> >
> > Also in your example: String str = converter.getAsString(value);
> > JSF API want
> > converter.getAsString(FacesContext,UIComponent,value).
> > Do you know why it needs two additional args, is it gonna plug this
value
> > into the component and then attach this component to the tree?
> >
> > I've just wrote this code for bloking the unwanted valueChangeEvent, but
> > have not tested it yet. I was the above mentioned getAsString(), but
with
> > the only purpose of getting converted value - not updating the tree.
> >
> >
> >
> >     public static boolean isValueChanged(ValueChangeEvent event) {
> >         if (event.getOldValue() == null) {
> >             if (StringUtils.isEmpty(event.getNewValue().toString()))
> >                 return false;
> >             else
> >                 return true;
> >         }
> >
> >         UIInput comp = (UIInput)event.getComponent();
> >         Converter conv = comp.getConverter();
> >         if (conv == null) {
> >             if
> > (event.getOldValue ().toString().equals(event.getNewValue().toString()))
> >                 return false;
> >             else
> >                 return true;
> >         } else {
> >             Object oldVal =
> >                 conv.getAsString(FacesContext.getCurrentInstance(),
comp,
> >                                  event.getOldValue());
> >             if (oldVal.equals(event.getNewValue()))
> >                 return false;
> >             else
> >                 return true;
> >         }
> >     }
> >
> > vlad
> >
> >
> > On 7/6/07, Andrew Robinson <[EMAIL PROTECTED] > wrote:
> > > The original value is already converted by specification. The purpose
> > > of a converter is to take an object from the back-end and change it to
> > > a view (HTML typically) compatible value and then change the view
> > > value back to a back-end value on submit.
> > >
> > > It is the back-end developer's job to ensure the back-end value is
> > > "converted". If you want the original value to be converted using a
> > > JSF converter, then use the Application object to create a converter
> > > from you backing bean when you load the data, and convert the value as
> > > you wish.
> > >
> > > The purpose of the value change event is to tell you if the user
> > > changed something. The user changed something if the value they submit
> > > after conversion is not the same as the value from the back-end.
> > >
> > > You keep saying "converted original value", but that is an oxymoron by
> > > JSF definition. If my component is a number input field, the converted
> > > value is type Integer and the client value is type String. So the
> > > converter converts between string and integer, not integer and
> > > integer.
> > >
> > > To be even more precise, for a converter to work properly the
> > > following must be true:
> > >
> > > Converter converter = ...
> > > Object value = component.getValue();
> > > String str = converter.getAsString(value);
> > > Object value2 = converter.getAsObject(str);
> > > if (value2.equals(value)) {
> > > // converter is valid
> > > }
> > >
> > > On 7/6/07, Vladimir Isakovich <[EMAIL PROTECTED]> wrote:
> > > > Null vs empty string is not the only one case, the point I'm trying
to
> > make
> > > > here:
> > > > whenever the JSF framework is applying some data conversion (either
the
> > > > converter was explicitly declared or not), it may (should) remember
that
> > > > conversion rule, so that when that same page is submitted, the
framework
> > (I
> > > > mean JSF) will compare ( for the purpose of firing changeValueEvent)
not
> > the
> > > > original value with the new value but the converted original value
with
> > the
> > > > new value.
> > > >
> > > > Yes this is an old issue with all previous frameworks, but I thought
JSF
> > > > could be better. And thinking of the declared converters, cann't I
find
> > all
> > > > converters for a given UIComponent using JSF API. I did not try but
I
> > > > thought it's doable.
> > > >
> > > > vlad
> > > >
> > > >
> > > > On 7/6/07, Bryan Basham <[EMAIL PROTECTED]> wrote:
> > > > > The problem you are experiencing is true for any Java/Web
> > > > > framework.  An HTTP request parameter does not understand
> > > > > what a Java null is but always uses the empty string "".  So
> > > > > somewhere in your application (or framework) you have to
> > > > > handle the conversion from "" to null.
> > > > >
> > > > > When it comes to String values, null is not the same as ""
> > > > > so I would recommend that your backing beans be populated
> > > > > with "" instead of null when dealing with JSF.  Alternatively,
> > > > > you could create a NullStringConverter which converts from
> > > > > "" to null.
> > > > >
> > > > > When it comes to non-String values, then your converter should
> > > > > return null from the getAsObject method when an "" is the
> > > > > request parameter.
> > > > >
> > > > > -Bryan
> > > > >
> > > > > vlad10 wrote:
> > > > > > I'm fresh with JSF,
> > > > > > just started building some prototypes with facelets 1.1.11 ,
myfaces
> > > > > > 1.1.3/tomahawk 1.1.3.
> > > > > >
> > > > > > I'm getting this general feeling that the framework is missing
some
> > > > > > important feature.
> > > > > > I may create an inputText and populate it with a null value, the
> > > > framework
> > > > > > conviniently will convert it into an empty string and populate
my
> > page.
> > > > > > However, on submit the valueChangeListener will fire with the
reason
> > > > that
> > > > > > null is not the same as an empty string.
> > > > > > I have another example. This the initial value is not null. I
may
> > > > explicitly
> > > > > > add a converter to that field, so the value stored in POJO as
> > > > jva.util.Date
> > > > > > or as a BigDecimal or anything else will be nicely displayed on
the
> > > > screen,
> > > > > > but I'll face again the unwanted behavior of my
valueChangeListener.
> > > > > > For the time being, I'm trying to compensate this deficiency in
my
> > app
> > > > by
> > > > > > adding some filtering in a utility class. At the moment it's in
the
> > > > > > beginning, just checking null/empty string case:
> > > > > >
> > > > > >     /**
> > > > > >      * UIInput value is never null when submitted, but the POJO
is
> > > > always
> > > > > >      * initialized with nulls. This creates a false alarm by
> > > > > > valueChangeListeners.
> > > > > >      * This method tries to compensate this deficiency.
> > > > > >      * @param input
> > > > > >      * @param rec
> > > > > >      * @return
> > > > > >      */
> > > > > >     public static boolean isValueChanged(UIInput input, Object
pojo)
> > {
> > > > > >         String name = input.getId();
> > > > > >         Object val = BeanUtil.getBeanValue (pojo,name);
> > > > > >         if (val == null)
> > > > > >             if(
StringUtils.isEmpty(input.getValue().toString()))
> > > > > >                 return false;
> > > > > >             else
> > > > > >                 return true;
> > > > > >         return (
> > input.getValue().toString().compareTo(val.toString())
> > > > != 0);
> > > > > >     }
> > > > > >
> > > > > > My question: am I missing something????
> > > > > > Do I really need to add another layer in my app, I may call it
> > something
> > > > > > like JSF Frendly POJOs. I may perform all necessary conversions
> > right
> > > > there
> > > > > > when moving data from DB to the screen, and then on submit
perform
> > the
> > > > > > opposit conversion when moving data back. I hope I can avoid
that.
> > > > > > Is not it possible for a framework to 'remember' not just an
> > oldValue,
> > > > but
> > > > > > also the conversion performed, so prior to comparing old/new
values
> > it
> > > > would
> > > > > > apply that same converter to the old value???
> > > > > > I think, this part has been missed.
> > > > > >
> > > > > > thanks
> > > > > > vlad
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>


Reply via email to