You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Ralph Schaer <sc...@ess.ch> on 2000/06/13 16:53:15 UTC

Checkbox

Suggestion for a new CheckBox <-> Beans Mapping

Hi
I found a few drawbacks in the current checkbox tag  <-> Bean mapping
implementation

- the value attribute is optional. if you don't specifie an value and the
user checks
  the checkbox, the browser sends the default value "on" (for example:
...&checkbox=on&...)
  But the class CheckboxTag.java only checks the value against "true" or
"yes"

- Every checkbox needs an set and get method. No problem
  with one checkbox but not very handy with 5 or 10 checkboxes.


The standard approach in JSP is to map a checkbox to an method with a string
array parameter
(void setCheckbox(String[] args) ). I changed the source for
CheckboxTag.java and BeanUtils.java, that
it works this way. The value is now mandatory. (see attachment)

  <tag>
    <name>checkbox</name>
    <tagclass>org.apache.struts.taglib.CheckboxTag</tagclass>
    <attribute>
      <name>name</name>
      <required>true</required>
      <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
      <name>value</name>
      <required>true</required>                  <----------------
      <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>




Ralph


Re: Checkbox

Posted by Ralph Schaer <sc...@ess.ch>.
Nightly Build 2000/06/13

>The initial thinking was that a <struts:checkbox> would represent the value
of a
>single boolean property in your bean.

OK. Now I understand. But there are still a few problems.


example 1
---------

JSP:  <struts:checkbox name="administrator">administrator</struts:checkbox>

Source: TestForm implements ActionForm

  private boolean admin = false;

  public boolean getAdministrator() {
    return admin;
  }

  public void setAdministrator(boolean admin) {
    this.admin = admin;
  }

The user select the checkbox and press the submit button
The browser sends the following request to the server:
http://localhost:8080/test.do?submit=OK&administrator=on

The admin property in TestForm is still false because "on" is not mapped to
true

This is easy to fix. After line 125 in BeanUtils.java add the follwing code:
     else if (value.equalsIgnoreCase("on"))
        return (new Boolean(true));


With this fix example 1 is working


example 2
---------

JSP: same as example 1
Source: private boolean admin = true;

The checkbox is now selected. The user DESELECT the checkbox and press the
submit button
The browser sends the follwing request to the server:
http://localhost:8080/test.do?submit=OK

The admin property is still true because there is no "administrator" in the
query string.
Thats very annoying that the browser doesn't send something like
"administrator=off"

I have no idea how to handle this case.



example 3a
----------

more than one checkbox.
with existing tag

JSP: <struts:checkbox name="blue">blue</struts:checkbox>
     <struts:checkbox name="red">red</struts:checkbox>
     <struts:checkbox name="green">green</struts:checkbox>
     <struts:checkbox name="yellow">yellow</struts:checkbox>
     <struts:checkbox name="black">black</struts:checkbox>

Source:
  private boolean blue = false;

  public boolean getBlue() {
    return blue;
  }

  public void setBlue(boolean blue) {
    this.admin = blue;
  }

  //Same for red, green, yellow, black

Disadvantag: Every checkbox needs a property and a get/set method. Adding a
new checkbox to the jsp page
             needs a code change in the Form


example 3b
----------

My suggestion: mapping checkbox to String[]

JSP: <struts:checkbox name="colour">blue</struts:checkbox>
     <struts:checkbox name="colour">red</struts:checkbox>
     <struts:checkbox name="colour">green</struts:checkbox>
     <struts:checkbox name="colour">yellow</struts:checkbox>
     <struts:checkbox name="colour">black</struts:checkbox>

Source:
  private String[] colour = null;

  public String[] getColour() {
    return colour;
  }

  public void setColour(String[] colour) {
    this.colour = colour;
  }

This is the way JSP maps checkboxes to java with the
setProperty tag (<jsp:setProperty name="test" property="*"/>)


!!Also this approach has the problem mentioned in example 2!!!


>It might end up making the most sense to create a new tag for this purpose,
and
>leave the existing one as suitable for boolean properties.
I agree with you. (for example <struts:checkboxgroup>


Ralph



Re: Checkbox

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Ralph Schaer wrote:

> Suggestion for a new CheckBox <-> Beans Mapping
>
> Hi
> I found a few drawbacks in the current checkbox tag  <-> Bean mapping
> implementation
>
> - the value attribute is optional. if you don't specifie an value and the
> user checks
>   the checkbox, the browser sends the default value "on" (for example:
> ...&checkbox=on&...)
>   But the class CheckboxTag.java only checks the value against "true" or
> "yes"
>

The initial thinking was that a <struts:checkbox> would represent the value of a
single boolean property in your bean.

>
> - Every checkbox needs an set and get method. No problem
>   with one checkbox but not very handy with 5 or 10 checkboxes.
>
> The standard approach in JSP is to map a checkbox to an method with a string
> array parameter
> (void setCheckbox(String[] args) ). I changed the source for
> CheckboxTag.java and BeanUtils.java, that
> it works this way. The value is now mandatory. (see attachment)
>

I'm not sure I completely understand what you are after here.  Do you want to
end up rendering one checkbox or many?  The modified CheckboxTag code you
submitted appears to render only one checkbox, which is initialized to "checked"
if the value matches any one of the Strings in an array.  Could you describe a
typical use case for this?

It might end up making the most sense to create a new tag for this purpose, and
leave the existing one as suitable for boolean properties.

>
>   <tag>
>     <name>checkbox</name>
>     <tagclass>org.apache.struts.taglib.CheckboxTag</tagclass>
>     <attribute>
>       <name>name</name>
>       <required>true</required>
>       <rtexprvalue>false</rtexprvalue>
>     </attribute>
>     <attribute>
>       <name>value</name>
>       <required>true</required>                  <----------------
>       <rtexprvalue>false</rtexprvalue>
>     </attribute>
>   </tag>
>
> Ralph
>
>   ------------------------------------------------------------------------
>                      Name: BeanUtils.java
>    BeanUtils.java    Type: java/*
>                  Encoding: quoted-printable
>
>                        Name: CheckboxTag.java
>    CheckboxTag.java    Type: java/*
>                    Encoding: quoted-printable

Would it be possible for you to send context diffs, or otherwise highlight the
code that has changed?  It is not always obvious when comparing two fairly long
source files.

Thanks,
Craig