You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Colin Sampaleanu <co...@Bspark.com> on 2000/08/25 21:55:21 UTC

Handling checkboxes with struts

There is currently a limitation on using Struts with checkboxes and a form
bean. The problem is than a form containing a checkbox will not send up
_any_ parameter if the checkbox is not checked. If the checkbox is mapped to
a boolean value on a formbean, this means an unchecked checkbox will never
override an already set boolean true property in the corresponding form
bean. This is quite problematic if the default value of the property is
true, or if the form bean is session scope and is already set.

What is needed is a way for the action form processor to know what
checkboxes are on the submitted page. If it knows this, a missing parameter
value of that name means a false value. What I have done is within the form
on the JSP page, used a hidden field such as:
	<input type="hidden" name="falseIfMissing"
value="checkbox1,checkbox2"/>
to send up names of fields that should be considered false if missing, and
added the corresponding override of the Action servlet processActionForm
method:
----
  /**
   * extension to normal processActionForm that handles a special parameter
   * "falseIfMissing" which signifies names (separated by ',') of form
fields
   * which should be treated as false if not sent up as a parameter.
   * This mechanism is needed since normally a checkbox that is not checked
does
   * not send up a value at all, and so no 'setXXXXXX(false)' methods would
ever
   * be called for that checkbox on the form bean. A form can send up a list
   * of checkbox fields which should be checked, as a hidden field
   */
  protected ActionForm processActionForm(ActionMapping mapping,
                                         HttpServletRequest request)
      throws ServletException {

    ActionForm af = super.processActionForm(mapping, request);
    if (af != null) {
      String falseIfMissing = request.getParameter("falseIfMissing");
      if (falseIfMissing != null) {
        // build a list of boolean properties that must be set false
        String prefix = mapping.getFormPrefix();
        String suffix = mapping.getFormSuffix();
        Hashtable props = new Hashtable();
        StringTokenizer st = new StringTokenizer(falseIfMissing, ", ");
        while (st.hasMoreElements()) {
          String name = (String) st.nextElement();
          if (prefix != null) {
            if (!name.startsWith(prefix))
              continue;
            name = name.substring(0, prefix.length());
          }
          if (suffix != null) {
            if (!name.endsWith(suffix))
              continue;
            name = name.substring(0, name.length() - suffix.length());
          }
          if (name.length() > 0 && request.getParameter(name) == null) {
            props.put(name, "false");
            //System.out.println("processActionForm: setting unchecked
field: " + name);
          }
        }
        if (!props.isEmpty())
          try {
            BeanUtils.populate(af, props);
          }
          catch (Exception e) {
            throw new ServletException("BeanUtils.populate", e);
          }
      }
    }

    return af;
  }
----


Is this something that should be included in the base ActionServlet? The
name could be a little more specialized to not interfere with any existing
parameters, or the form processor could look for the mapping to implement a
specialized interface (e.g. UncheckedFieldAware) before looking for this
special parameter...