com.sun.webui.jsf.component.Checkbox Maven / Gradle / Ivy
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://woodstock.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at https://woodstock.dev.java.net/public/CDDLv1.0.html.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.webui.jsf.component;
import com.sun.faces.annotation.Component;
import com.sun.faces.annotation.Property;
import java.util.ArrayList;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
/**
* The Checkbox component is used to display a checkbox input element.
*
* The Checkbox
can be used as a single checkbox
* or one checkbox among a group of checkboxes. A group
* of checkboxes represents a multiple selection list which can have any
* number of checkboxes selected, or none selected. A checkbox can
* represent a Boolean
value, a String
value,
* or a developer defined Object
value.
*
* Detecting a selected checkbox
*
* The Checkbox
uses both the selected
* and selectedValue
properties to pass information about
* the checkbox's selection status. The selected
* property is used to indicate that the checkbox is selected.
* The selectedValue
property is used to pass a data value,
* a string by default, for the checkbox. A checkbox is considered to be
* selected when the value of the selected
property is equal
* to the value of the selectedValue
property. A checkbox can
* be initally selected by assigning the same value
* to the selectedValue
and the selected
* properties. isChecked
is called to determine
* if this Checkbox
is selected.
*
* If the selectedValue
property is not specified or its
* value is null
then the checkbox behaves like a
* boolean control. If the checkbox is selected, the value of the
* selected
property is a true Boolean
* instance. If the checkbox is not selected, the value of the
* selected
property will be a false Boolean
* instance.
*
* Note that a value binding expression that evaluates to a
* primitive boolean value can be assigned to the selected
* property. Proper type coercion from Boolean
to
* boolean
occurs.
*
*
* When checkboxes are part of a group, an ArrayList
of
* selected checkboxes is maintained. If any checkboxes within a group are
* selected, a request attribute whose name is the value of the
* name
property is created and added to the
* RequestMap
. The request attribute value is an
* ArrayList
containing the value of the
* selectedValue
property of each selected
* checkbox. If no checkboxes are selected, no request attribute is
* created. The selected
property of each selected checkbox
* within the group will also contain the value of the
* selectedValue
property of the respective selected checkbox.
*
* Using a checkbox
tag as a boolean control
*
* If the selectedValue
property is not specified or its
* value is null
then the checkbox behaves like a
* boolean control.
*
*
* To use the Checkbox
as a boolean control, do not
* specify a value for the selectedValue
property. The
* checkbox is selected if the selected
property is not
* null and has the value of a Boolean instance with a true
* value. If the checkbox is not selected, then the value of the
* selected
property is a false Boolean
instance.
*
* Note that using a boolean checkbox in a group and
* referencing the request property for the selected checkboxes is not
* useful, since the value of the request property will be an ArrayList
*
of indistinguishable true
values.
*
* Using a Checkbox
to represent a developer defined
* value
* The selectedValue
property can be assigned a
* developer defined object value to represent the value of a selected
* checkbox. If the checkbox is selected, the value of the selected
* property is assigned the value of the selectedValue
* property.
*
*
* If the value of the selectedValue
property is a
* developer defined object, a Converter
must be registered
* to convert to and from a String
value.
* In addition the object must support an
* equals
method that returns true
when the
* value of the selectedValue
property is compared to
* the selected
property value in order to detect a
* selected checkbox.
*
* Using a Checkbox
as one control in a group
*
* The name
property determines whether a
* checkbox is part of a group. A checkbox is treated as part of a group
* of checkboxes if the name
property of the checkbox is
* assigned a value equal to the name
property of the other
* checkboxes in the group. In other words, all checkboxes of a group have the
* same name
property value. The group behaves
* like a multiple selection list, where zero or more checkboxes
* can be selected. The value of the name property must
* be unique within the scope of the Form parent containing the
* checkboxes.
*
* Facets
*
* The following facets are supported:
*
*
* - image If the image facet exists, it replaces the
* {@link com.sun.webui.jsf.component.ImageComponent} subcompoent
* normally created for the image associated with the checkbox
* if the
imageURL
property is not null.
* - label If the label facet exists, it replaces the
* {@link com.sun.webui.jsf.component.Label} subcomponent normally
* created for the label associated with the checkbox, if the
* label property is not null.
*
*
* Add an image or label facet to the Checkbox
if more
* control over the properties of the subcomponents is needed.
*
*
* Note that if a facet is exists, Checkbox
properties
* that would normally be assigned to the created subcomponent, will
* not be assigned to the facet
*
*
* Note that unexpected layout of the Checkbox
may occur
* if the component specified by the facet is not a
* {@link com.sun.webui.jsf.component.ImageComponent} for the image facet or
* {@link com.sun.webui.jsf.component.Label} for the label facet.
*
* ImageComponent and Label subcomponents
*
* An image and a label may be associated with the Checkbox
.
* If the imageURL
property is not null and an image facet
* does not exist then a {@link com.sun.webui.jsf.component.ImageComponent}
* component is created.
* If the label
property is not null and a label facet does not
* exist then a {@link com.sun.webui.jsf.component.Label} component is
* created.
*
*
* The following Checkbox
properties are assigned to the
* subcomponents only if a facet does not exist.
* For the {@link com.sun.webui.jsf.component.ImageComponent} subcomponent
*
* - this.getId() + "_image" is assigned to the
id
property.
* - this.getImageURL() is assigned to the
url
property.
* - this.getToolTip() is assigned to the
toolTip
property.
* - this.getToolTip() is assigned to the
alt
property.
* - this.isVisible() is assigned to the
visible
property.
* - this.isRendered() is assigned to the
renderer
property.
*
*
*
* For the {@link com.sun.webui.jsf.component.Label} subcomponent
*
* - this.getId() + "_label" is assigned to the
id
* property.
* - this.getClientId() is assigned to the
for
* property.
* - this.getLabel() is assigned to the
text
property.
* - this.getLabelLevel is assigned to the
labelLevel
property.
* - this.getToolTip is assigned to the
toolTip
property.
* - this.isVisible is assigned to the
visible
property.
* - this.isRendered is assigned to the
renderer
property.
*
*
*
* Note that if a value binding exists for one of the Checkbox
* properties mentioned above, the value binding is set on the subcomponent
* for that property.
*
*/
@Component(type = "com.sun.webui.jsf.Checkbox", family = "com.sun.webui.jsf.Checkbox", displayName = "Checkbox", tagName = "checkbox",
helpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_checkbox",
propertiesHelpKey = "projrave_ui_elements_palette_wdstk-jsf1.2_propsheets_checkbox_props")
public class Checkbox extends RbCbSelector {
/**
* Constructor for a Checkbox
.
*/
public Checkbox() {
super();
// When used in a group you can choose multiple
// and this behavior is provided, but the single
// implementation of Checkbox vs. CheckboxGroup
// does not need Multiple to be explicit.
//
setMultiple(false);
setRendererType("com.sun.webui.jsf.Checkbox");
}
/**
* Return the family for this component.
*/
@Override
public String getFamily() {
return "com.sun.webui.jsf.Checkbox";
}
/**
* Return an ArrayList
containing the value of the
* selectedValue
property of each selected checkbox
* in the group of checkboxes identified by the name
* parameter.
* A Checkbox
is one of a group of checkboxes
* if more than on checkbox has the same value for the
* name
property.
* When one of the checkboxes among that group is selected,
* the value of its selectedValue
property
* is maintained within an ArrayList
that is stored
* in a request attribute identified by the value of its name
* property.
*
* @param name the value a Checkbox name property.
*/
public static ArrayList getSelected(String name) {
Map rm = FacesContext.getCurrentInstance().getExternalContext().
getRequestMap();
if (name != null) {
return (ArrayList) rm.get(name);
} else {
return null;
}
}
/**
* Update the request parameter that holds the value of the
* selectedValue
property of the selected check box.
* If the name
property has been set
* a request attribute is created.
* The value of the name
property will
* be used for the request attribute name and the value of the request
* attribute will be an ArrayList
containing the value of the
* selectedValue
property of the selected check boxes
* that have the same name
property value.
* If no check box is selected then no request attribute
* will be created.
*
*
* The request attribute described above is available during
* a ValueChangeEvent
.
*
*
* @param context The context of this request.
*/
@Override
public void validate(FacesContext context) {
super.validate(context);
// If not valid or in a group don't add the checkbox to
// the request map.
//
if (!isValid()) {
return;
}
String groupName = getName();
if (groupName == null) {
return;
}
// If the submitted value is valid and the
// checkbox is selected add it to the
// request map array list. To check if the component
// is selected, can't call "isChecked" or getValue()
// cause if there is a value binding, it will return the previously
// selected state and not the state of this submit
// so use getLocalValue() which is set if isValid is true.
//
Object selected = getLocalValue();
if (!getSelectedValue().equals(selected)) {
return;
}
addToRequestMap(context, groupName, selected);
}
protected void addToRequestMap(FacesContext context, String groupName,
Object selected) {
Map requestMap = context.getExternalContext().getRequestMap();
ArrayList selectedCB = (ArrayList) requestMap.get(groupName);
if (selectedCB == null) {
selectedCB = new ArrayList();
requestMap.put(groupName, selectedCB);
}
if (!selectedCB.contains(selected)) {
selectedCB.add(selected);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Tag attribute methods
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hide items
@Property(name = "items", isHidden = true, isAttribute = false)
@Override
public Object getItems() {
return super.getItems();
}
// Hide required
@Property(name = "required", isHidden = true, isAttribute = false)
@Override
public boolean isRequired() {
return super.isRequired();
}
// Hide value
@Property(name = "value", isHidden = true, isAttribute = false)
@Override
public Object getValue() {
return super.getValue();
}
/**
* Sets the style level for the generated label, provided the
* label attribute has been set. Valid values are 1 (largest), 2 and
* 3 (smallest). The default value is 3.
*/
@Property(name = "labelLevel", displayName = "Label Level", category = "Appearance",
editorClassName = "com.sun.webui.jsf.component.propertyeditors.LabelLevelsEditor")
private int labelLevel = Integer.MIN_VALUE;
private boolean labelLevel_set = false;
/**
* Sets the style level for the generated label, provided the
* label attribute has been set. Valid values are 1 (largest), 2 and
* 3 (smallest). The default value is 3.
*/
@Override
public int getLabelLevel() {
if (this.labelLevel_set) {
return this.labelLevel;
}
ValueExpression _vb = getValueExpression("labelLevel");
if (_vb != null) {
Object _result = _vb.getValue(getFacesContext().getELContext());
if (_result == null) {
return Integer.MIN_VALUE;
} else {
return ((Integer) _result).intValue();
}
}
return 3;
}
/**
* Sets the style level for the generated label, provided the
* label attribute has been set. Valid values are 1 (largest), 2 and
* 3 (smallest). The default value is 3.
* @see #getLabelLevel()
*/
@Override
public void setLabelLevel(int labelLevel) {
this.labelLevel = labelLevel;
this.labelLevel_set = true;
}
/**
* Restore the state of this component.
*/
@Override
public void restoreState(FacesContext _context, Object _state) {
Object _values[] = (Object[]) _state;
super.restoreState(_context, _values[0]);
this.labelLevel = ((Integer) _values[1]).intValue();
this.labelLevel_set = ((Boolean) _values[2]).booleanValue();
}
/**
* Save the state of this component.
*/
@Override
public Object saveState(FacesContext _context) {
Object _values[] = new Object[3];
_values[0] = super.saveState(_context);
_values[1] = new Integer(this.labelLevel);
_values[2] = this.labelLevel_set ? Boolean.TRUE : Boolean.FALSE;
return _values;
}
}