You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Bruno Grossi <br...@powerlogic.com.br> on 2007/05/04 19:58:04 UTC

[Trinidad] Problem with dynamic rendered in checkbox

Hi,

I detected a problem with checkbox/radios with dynamic rendered 
attribute, that I don't know if it's a JSF or Trinidad bug:

If I have a checkbox with a 
rendered="${requestScope.someBooleanAttribute}", and a button that 
simple alter that attribute in request, to not render it again. If, at 
first step, the component is rendered and I check it, my target value is 
setted to true.. But, if I click the button again, the component exists, 
and checks if it's value is changed.

For that, we have:

1- wasSubmitted value returns true:
  protected boolean wasSubmitted(
    FacesContext context,
    UIComponent  component)
  {
    FacesBean bean = getFacesBean(component);
    return !getDisabled(bean) && !getReadOnly(context, bean);
  }

2- getSubmittedValue returns FALSE!
  public Object getSubmittedValue(
    FacesContext context,
    UIComponent  component)
  {
    if (super.getSubmittedValue(context, component) == null)
      return Boolean.FALSE;

    return Boolean.TRUE;
  }

3- The value was changed to FALSE...

It occurs to radio and combos too..

The getSubmittedValue is correctly implemented, because if the checkbox 
is unmarked the browser don't send the parameter, and 
super.getSubmittedValue(context, component) returns null.



My suggestion is, in that cases, render a hidden field that indicates 
that the component was rendered, to check it in wasSubmitted... 
Something like:

<input type="hidden" name="form:j_id_jsp_1240287335_0i7_rendered" 
value="true">

where form:j_id_jsp_1240287335_0i7 is the component's client id. And:


  protected boolean wasSubmitted(
    FacesContext context,
    UIComponent  component)
  {
    if (!wasRendered(context)) {
       return false;
    }
    FacesBean bean = getFacesBean(component);
    return !getDisabled(bean) && !getReadOnly(context, bean);
  }

  protected boolean wasRendered(...) {
    String clientId = component.getClientId(context);
    return context.getExternalContext().
                                
getRequestParameterMap().get(clientId+"_rendered")!=null;

  }



There are other solution?


Thanks,
Bruno E. Grossi

Re: [Trinidad] Problem with dynamic rendered in checkbox

Posted by Scott O'Bryan <da...@gmail.com>.
Bruno,

Your correct in the fact that rendered=false is useless.  However, that 
is not how it's typically used.  Typically this will be bound to a 
backing bean which will allow you to turn the component on/off.  You 
should use a hidden input field and a switcher if you need to keep the 
value in the form submission.  Adam is totally correct in that it will 
break a bunch of stuff if we all of a sudden just "turned it on" because 
people have come to expect the current behavior.

Scott

Bruno Grossi wrote:
> Adam,
>
> if "rendered" is always false, there are any reason to include the 
> component/tag on my page?
>
> In my example, I have an web wizard, that shows, step-by-step, some 
> fields in my page. I have a tr:tableLayout and the rendered attribute 
> is on <tr:rowLayout>, to show/hide the whole line, according to the 
> actual "line number"...
>
> Thanks,
> Bruno
>
> Adam Winer wrote:
>> No, it's your responsibility to make sure that "rendered"
>> is the same on postback as it was when the page was
>> rendered.  It is an explicit rule of JSF that when
>> rendered is false, *nothing* renders and nothing
>> happens on postback.  We cannot start rendering
>> extra fields for everything that doesn't render -
>> besides being extremely inefficent, it wouldn't help
>> you at all when a parent component has rendered="false".
>>
>> The simplest way to do this is to stop using
>> EL expressions on "rendered".  Instead, just
>> call setRendered(true/false) on the component
>> to toggle visibility.  JSF state saving will handle
>> everything for you.
>>
>> -- Adam
>>
>>
>> On 5/4/07, Bruno Grossi <br...@powerlogic.com.br> wrote:
>>> Hi,
>>>
>>> I detected a problem with checkbox/radios with dynamic rendered
>>> attribute, that I don't know if it's a JSF or Trinidad bug:
>>>
>>> If I have a checkbox with a
>>> rendered="${requestScope.someBooleanAttribute}", and a button that
>>> simple alter that attribute in request, to not render it again. If, at
>>> first step, the component is rendered and I check it, my target 
>>> value is
>>> setted to true.. But, if I click the button again, the component 
>>> exists,
>>> and checks if it's value is changed.
>>>
>>> For that, we have:
>>>
>>> 1- wasSubmitted value returns true:
>>>   protected boolean wasSubmitted(
>>>     FacesContext context,
>>>     UIComponent  component)
>>>   {
>>>     FacesBean bean = getFacesBean(component);
>>>     return !getDisabled(bean) && !getReadOnly(context, bean);
>>>   }
>>>
>>> 2- getSubmittedValue returns FALSE!
>>>   public Object getSubmittedValue(
>>>     FacesContext context,
>>>     UIComponent  component)
>>>   {
>>>     if (super.getSubmittedValue(context, component) == null)
>>>       return Boolean.FALSE;
>>>
>>>     return Boolean.TRUE;
>>>   }
>>>
>>> 3- The value was changed to FALSE...
>>>
>>> It occurs to radio and combos too..
>>>
>>> The getSubmittedValue is correctly implemented, because if the checkbox
>>> is unmarked the browser don't send the parameter, and
>>> super.getSubmittedValue(context, component) returns null.
>>>
>>>
>>>
>>> My suggestion is, in that cases, render a hidden field that indicates
>>> that the component was rendered, to check it in wasSubmitted...
>>> Something like:
>>>
>>> <input type="hidden" name="form:j_id_jsp_1240287335_0i7_rendered"
>>> value="true">
>>>
>>> where form:j_id_jsp_1240287335_0i7 is the component's client id. And:
>>>
>>>
>>>   protected boolean wasSubmitted(
>>>     FacesContext context,
>>>     UIComponent  component)
>>>   {
>>>     if (!wasRendered(context)) {
>>>        return false;
>>>     }
>>>     FacesBean bean = getFacesBean(component);
>>>     return !getDisabled(bean) && !getReadOnly(context, bean);
>>>   }
>>>
>>>   protected boolean wasRendered(...) {
>>>     String clientId = component.getClientId(context);
>>>     return context.getExternalContext().
>>>
>>> getRequestParameterMap().get(clientId+"_rendered")!=null;
>>>
>>>   }
>>>
>>>
>>>
>>> There are other solution?
>>>
>>>
>>> Thanks,
>>> Bruno E. Grossi
>>>
>>
>
>


Re: [Trinidad] Problem with dynamic rendered in checkbox

Posted by Bruno Grossi <br...@powerlogic.com.br>.
Adam,

if "rendered" is always false, there are any reason to include the 
component/tag on my page?

In my example, I have an web wizard, that shows, step-by-step, some 
fields in my page. I have a tr:tableLayout and the rendered attribute is 
on <tr:rowLayout>, to show/hide the whole line, according to the actual 
"line number"...

Thanks,
Bruno

Adam Winer wrote:
> No, it's your responsibility to make sure that "rendered"
> is the same on postback as it was when the page was
> rendered.  It is an explicit rule of JSF that when
> rendered is false, *nothing* renders and nothing
> happens on postback.  We cannot start rendering
> extra fields for everything that doesn't render -
> besides being extremely inefficent, it wouldn't help
> you at all when a parent component has rendered="false".
>
> The simplest way to do this is to stop using
> EL expressions on "rendered".  Instead, just
> call setRendered(true/false) on the component
> to toggle visibility.  JSF state saving will handle
> everything for you.
>
> -- Adam
>
>
> On 5/4/07, Bruno Grossi <br...@powerlogic.com.br> wrote:
>> Hi,
>>
>> I detected a problem with checkbox/radios with dynamic rendered
>> attribute, that I don't know if it's a JSF or Trinidad bug:
>>
>> If I have a checkbox with a
>> rendered="${requestScope.someBooleanAttribute}", and a button that
>> simple alter that attribute in request, to not render it again. If, at
>> first step, the component is rendered and I check it, my target value is
>> setted to true.. But, if I click the button again, the component exists,
>> and checks if it's value is changed.
>>
>> For that, we have:
>>
>> 1- wasSubmitted value returns true:
>>   protected boolean wasSubmitted(
>>     FacesContext context,
>>     UIComponent  component)
>>   {
>>     FacesBean bean = getFacesBean(component);
>>     return !getDisabled(bean) && !getReadOnly(context, bean);
>>   }
>>
>> 2- getSubmittedValue returns FALSE!
>>   public Object getSubmittedValue(
>>     FacesContext context,
>>     UIComponent  component)
>>   {
>>     if (super.getSubmittedValue(context, component) == null)
>>       return Boolean.FALSE;
>>
>>     return Boolean.TRUE;
>>   }
>>
>> 3- The value was changed to FALSE...
>>
>> It occurs to radio and combos too..
>>
>> The getSubmittedValue is correctly implemented, because if the checkbox
>> is unmarked the browser don't send the parameter, and
>> super.getSubmittedValue(context, component) returns null.
>>
>>
>>
>> My suggestion is, in that cases, render a hidden field that indicates
>> that the component was rendered, to check it in wasSubmitted...
>> Something like:
>>
>> <input type="hidden" name="form:j_id_jsp_1240287335_0i7_rendered"
>> value="true">
>>
>> where form:j_id_jsp_1240287335_0i7 is the component's client id. And:
>>
>>
>>   protected boolean wasSubmitted(
>>     FacesContext context,
>>     UIComponent  component)
>>   {
>>     if (!wasRendered(context)) {
>>        return false;
>>     }
>>     FacesBean bean = getFacesBean(component);
>>     return !getDisabled(bean) && !getReadOnly(context, bean);
>>   }
>>
>>   protected boolean wasRendered(...) {
>>     String clientId = component.getClientId(context);
>>     return context.getExternalContext().
>>
>> getRequestParameterMap().get(clientId+"_rendered")!=null;
>>
>>   }
>>
>>
>>
>> There are other solution?
>>
>>
>> Thanks,
>> Bruno E. Grossi
>>
>


Re: [Trinidad] Problem with dynamic rendered in checkbox

Posted by Adam Winer <aw...@gmail.com>.
No, it's your responsibility to make sure that "rendered"
is the same on postback as it was when the page was
rendered.  It is an explicit rule of JSF that when
rendered is false, *nothing* renders and nothing
happens on postback.  We cannot start rendering
extra fields for everything that doesn't render -
besides being extremely inefficent, it wouldn't help
you at all when a parent component has rendered="false".

The simplest way to do this is to stop using
EL expressions on "rendered".  Instead, just
call setRendered(true/false) on the component
to toggle visibility.  JSF state saving will handle
everything for you.

-- Adam


On 5/4/07, Bruno Grossi <br...@powerlogic.com.br> wrote:
> Hi,
>
> I detected a problem with checkbox/radios with dynamic rendered
> attribute, that I don't know if it's a JSF or Trinidad bug:
>
> If I have a checkbox with a
> rendered="${requestScope.someBooleanAttribute}", and a button that
> simple alter that attribute in request, to not render it again. If, at
> first step, the component is rendered and I check it, my target value is
> setted to true.. But, if I click the button again, the component exists,
> and checks if it's value is changed.
>
> For that, we have:
>
> 1- wasSubmitted value returns true:
>   protected boolean wasSubmitted(
>     FacesContext context,
>     UIComponent  component)
>   {
>     FacesBean bean = getFacesBean(component);
>     return !getDisabled(bean) && !getReadOnly(context, bean);
>   }
>
> 2- getSubmittedValue returns FALSE!
>   public Object getSubmittedValue(
>     FacesContext context,
>     UIComponent  component)
>   {
>     if (super.getSubmittedValue(context, component) == null)
>       return Boolean.FALSE;
>
>     return Boolean.TRUE;
>   }
>
> 3- The value was changed to FALSE...
>
> It occurs to radio and combos too..
>
> The getSubmittedValue is correctly implemented, because if the checkbox
> is unmarked the browser don't send the parameter, and
> super.getSubmittedValue(context, component) returns null.
>
>
>
> My suggestion is, in that cases, render a hidden field that indicates
> that the component was rendered, to check it in wasSubmitted...
> Something like:
>
> <input type="hidden" name="form:j_id_jsp_1240287335_0i7_rendered"
> value="true">
>
> where form:j_id_jsp_1240287335_0i7 is the component's client id. And:
>
>
>   protected boolean wasSubmitted(
>     FacesContext context,
>     UIComponent  component)
>   {
>     if (!wasRendered(context)) {
>        return false;
>     }
>     FacesBean bean = getFacesBean(component);
>     return !getDisabled(bean) && !getReadOnly(context, bean);
>   }
>
>   protected boolean wasRendered(...) {
>     String clientId = component.getClientId(context);
>     return context.getExternalContext().
>
> getRequestParameterMap().get(clientId+"_rendered")!=null;
>
>   }
>
>
>
> There are other solution?
>
>
> Thanks,
> Bruno E. Grossi
>