You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by katre <ka...@henchmonkey.org> on 2005/10/11 20:16:55 UTC

DynaActionForm, Boolean checkboxes, and Initial

Hello all.

In my app, I use the DynaActionForm, because it makes it much easier to
declare all the forms I need.  However, it is giving me a problem with
Boolean type variables used in checkboxes.

Specifically, I have the following form-bean:

<form-bean
        name="test_form"
        type="org.apache.struts.action.DynaActionForm">
    <form-property
        name="Download"
        type="java.lang.Boolean"
        initial="true"/>
</form-bean>

In my JSP, I have:

<html:checkbox property="Download"/>

This is properly checked by default.

The problem is that when a user unchecks the checkbox, this is not
noticed in the form, due to the infamous
HTTP-doesn't-send-empty-parameters problem.  The canonical advice I have
seen is 'set the property to false in the form's reset() method'.

This has two problems:
a) DynaActionForm's reset does nothing by default.  Is there really no
support for this common thing in DynaActionForm?
b) I created a subclass on DynaActionForm, which had a reset() method
that only sets that property to false.  However, the ActionForm.reset()
method is apparently called via the <html:form> tag, (the doStartTag()
method calls initFormBean(), which calls the form bean's reset()
method).  This means that the checkbox is initially unchecked, and seems
to be a problem regardless of using DynaActionForm or not.

So, my question is: how can I have a Boolean checkbox that defaults to
true, and yet can tell when it is unchecked, and still use
DynaActionForm?

Thanks,
katre


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by katre <ka...@henchmonkey.org>.
Dave Newton wrote:
> katre wrote:
> 
> >Right, and this does work, but it requires having a separate action
> >leading to every form.
> > 
> >
> Why _wouldn't_ forms have separate actions?

A lot of my forms (for example, search forms) don't need any special
prepopulation (or just get prepopulation from the initial attributes in
my dynaforms).  These just have a forward leading to the JSP, and don't
currently have actual actions leading to them.  They do, of course,
submit to an action that processes the results.

katre


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by Dave Newton <ne...@pingsite.com>.
katre wrote:

>Right, and this does work, but it requires having a separate action
>leading to every form.
>  
>
Why _wouldn't_ forms have separate actions?

Dave



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by Michael Jouravlev <jm...@gmail.com>.
On 10/12/05, katre <ka...@henchmonkey.org> wrote:
> Michael Jouravlev wrote:
> > > More importantly (and getting back to my original question), it means
> > > that when using a dyna form, you can't use the initial attribute for
> > > properties.  You have to write code to set them to the default value in
> > > that separate action (and thus separating the form from the logic).
> >
> > Um, right, you have to clear values associated with checkboxes in
> > reset method, right before the form fields are populated by Struts. I
> > guess, this means that you cannot use session-scoped dynaforms for
> > pages with checkboxes. I don't use dynaforms anyway but I see that
> > this is a shortcoming. You can still use request-scoped dynaforms.
>
> The problem is with both request and session-scoped dynaforms, when
> using the initial attribute if the form-property to pre-populate the
> form.  In this case, the form gets pre-populated with the "initial"
> value even when it is being populated from the request, which causes the
> problem.

Ah, I see, here is what seems to happen:

  * Dynaform is populated with "checked" value
  * JSP is displayed with checked checkbox
  * You uncheck the checkbox and submit form
  * When request comes:
    ** Struts creates dynaform with default "checked" value
    ** Struts populates form, unchecked value is not populated

Right, now there *is* a problem for request-scoped forms too. In my
forms I clear checkbox in reset() when POST comes. Dynaforms do not
allow that.

You can file a request in Bugzilla, or maybe even a patch ;-)

Michael.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by katre <ka...@henchmonkey.org>.
Michael Jouravlev wrote:
> > More importantly (and getting back to my original question), it means
> > that when using a dyna form, you can't use the initial attribute for
> > properties.  You have to write code to set them to the default value in
> > that separate action (and thus separating the form from the logic).
> 
> Um, right, you have to clear values associated with checkboxes in
> reset method, right before the form fields are populated by Struts. I
> guess, this means that you cannot use session-scoped dynaforms for
> pages with checkboxes. I don't use dynaforms anyway but I see that
> this is a shortcoming. You can still use request-scoped dynaforms.

The problem is with both request and session-scoped dynaforms, when
using the initial attribute if the form-property to pre-populate the
form.  In this case, the form gets pre-populated with the "initial"
value even when it is being populated from the request, which causes the
problem.

katre


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by Michael Jouravlev <jm...@gmail.com>.
On 10/12/05, katre <ka...@henchmonkey.org> wrote:
> > Um, well, what _I've_ been doing is setting the appropriate ActionForm
> > value before I display the form, not in reset but in the Action's
> > execute method (reset works too, but because I've never used
> > validate="true" I'm doing setup stuff in the Action anyway). After form
> > submision I look at the form value of the checkbox (I usually use
> > Boolean, but I almost always use DynaValidatorActionForms, so YMMV on
> > that one).
>
> Right, and this does work, but it requires having a separate action
> leading to every form.  Which isn't such a huge inconvenience, really,
> just more code.

In Struts JSP page is regarded as data-aware HTML and is used for
output only. All input should pass through an action.

> More importantly (and getting back to my original question), it means
> that when using a dyna form, you can't use the initial attribute for
> properties.  You have to write code to set them to the default value in
> that separate action (and thus separating the form from the logic).

Um, right, you have to clear values associated with checkboxes in
reset method, right before the form fields are populated by Struts. I
guess, this means that you cannot use session-scoped dynaforms for
pages with checkboxes. I don't use dynaforms anyway but I see that
this is a shortcoming. You can still use request-scoped dynaforms.

Michael.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by katre <ka...@henchmonkey.org>.
Dave Newton wrote:
> katre wrote:
> 
> >The basic problem, as before, is that it is totally impossible in struts
> >to default a checkbox to true, and still be able to detect when it is
> >uncheked by a user.
> > 
> >
> Wow. All those apps of mine, ruined ;)

Well, I figured, since no one replied to my first email, why not get
dramatic and see what happens? :)

> Um, well, what _I've_ been doing is setting the appropriate ActionForm 
> value before I display the form, not in reset but in the Action's 
> execute method (reset works too, but because I've never used 
> validate="true" I'm doing setup stuff in the Action anyway). After form 
> submision I look at the form value of the checkbox (I usually use 
> Boolean, but I almost always use DynaValidatorActionForms, so YMMV on 
> that one).

Right, and this does work, but it requires having a separate action
leading to every form.  Which isn't such a huge inconvenience, really,
just more code.

More importantly (and getting back to my original question), it means
that when using a dyna form, you can't use the initial attribute for
properties.  You have to write code to set them to the default value in
that separate action (and thus separating the form from the logic).

Thanks very much for your help,
katre


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by Dave Newton <ne...@pingsite.com>.
katre wrote:

>The basic problem, as before, is that it is totally impossible in struts
>to default a checkbox to true, and still be able to detect when it is
>uncheked by a user.
>  
>
Wow. All those apps of mine, ruined ;)

>Someone, please prove me wrong! Tell me struts isn't this limited!  Tell
>me how to fix this!  Otherwise, I'll have to go add javascript hackery
>and extra hidden fields to every JSP that uses a checkbox, and that's a
>lot.
>  
>
That's crazy.

Um, well, what _I've_ been doing is setting the appropriate ActionForm 
value before I display the form, not in reset but in the Action's 
execute method (reset works too, but because I've never used 
validate="true" I'm doing setup stuff in the Action anyway). After form 
submision I look at the form value of the checkbox (I usually use 
Boolean, but I almost always use DynaValidatorActionForms, so YMMV on 
that one).

Somehow I can create and edit records with checkboxes despite the "total 
impossibility" :D Sometimes I have to marshall the checkbox value into 
an integer if that's what I'm using as a flag in the DB.

I've appended some old code that shows (more or less) one way of 
approaching this (and I eagerly await the code style comments ;)

Dave

// Code edited to protect the not-so-innocent and hide framework details
// Loads the required OM on an edit; before showing the form, i.e. GET 
request
        AnnouncementType anntype = 
AnnouncementTypePeer.retrieveByEventAndType(event_.getEventId(), typeId_);
        if (anntype == null) {
            request_.setAttribute("dontShowForm", Boolean.TRUE); // <-- 
Go ahead, mock me!
            return errorResourceToInput(request_, mapping_, 
"anntypebean.error.editRetrieval");
        }

        DynaActionForm form = (DynaActionForm) form_;
        BeanUtils.copyProperties(form, anntype);

        // Mock me some more!
        Boolean clientP = anntype.getClientAnnouncement() > 0 ? 
Boolean.TRUE : Boolean.FALSE;
        Boolean cbModeP = anntype.getCbMode() > 0 ? Boolean.TRUE : 
Boolean.FALSE;
        Boolean epcModeP = anntype.getEpcMode() > 0 ? Boolean.TRUE : 
Boolean.FALSE;
       
        form.set("clientAnnouncementP", clientP);
        form.set("cbModeP", cbModeP);
        form.set("epcModeP", epcModeP);

// Put form values back into OM and update after POST
            AnnouncementType announcementType = 
AnnouncementTypePeer.retrieveByEventAndType(event_.getEventId(), id_);
            if (announcementType == null) {
                request_.setAttribute("dontShowForm", Boolean.TRUE);
                return errorResourceToInput(request_, mapping_, 
"anntypebean.error.editRetrieval");
            }
            BeanUtils.copyProperties(announcementType, form_);
            announcementType.setAnnouncementPrice(safeMoney((String) 
form_.get("announcementPrice")));
            announcementType.setClientAnnouncement((Boolean) 
form_.get("clientAnnouncementP")); // <-- Yes, I'm a lisp programmer
            announcementType.setCbMode((Boolean) form_.get("cbModeP"));
            announcementType.setEpcMode((Boolean) form_.get("epcModeP"));
            AnnouncementTypePeer.doUpdate(announcementType);



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: DynaActionForm, Boolean checkboxes, and Initial

Posted by katre <ka...@henchmonkey.org>.
Okay, I went back and created the smallest app that shows this problem.
It can be downloaded from http://www.henchmonkey.org/struts-test.zip .

The basic problem, as before, is that it is totally impossible in struts
to default a checkbox to true, and still be able to detect when it is
uncheked by a user.

Either one of two things will happen: either your reset() method does
not do anything to the value, so you get the default-checked value
because there is no parameter set to change that value, or your reset()
sets the checkbox to false, in which case it cannot be set by default,
as the form is reset right before it is displayed in the JSP (by
<html:form>.

This is true with dyna forms and with regular ActionForm subclasses.

Someone, please prove me wrong! Tell me struts isn't this limited!  Tell
me how to fix this!  Otherwise, I'll have to go add javascript hackery
and extra hidden fields to every JSP that uses a checkbox, and that's a
lot.

katre


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org