All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redijedi.tapestry.components.RatingField Maven / Gradle / Ivy

The newest version!
package com.redijedi.tapestry.components;

import java.util.List;

import org.apache.tapestry.Asset;
import org.apache.tapestry.MarkupWriter;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.ValueEncoder;
import org.apache.tapestry.annotations.Component;
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.annotations.SetupRender;
import org.apache.tapestry.corelib.base.AbstractField;
import org.apache.tapestry.corelib.components.Label;
import org.apache.tapestry.corelib.components.Loop;
import org.apache.tapestry.corelib.components.Radio;
import org.apache.tapestry.corelib.components.RadioGroup;
import org.apache.tapestry.dom.Element;
import org.apache.tapestry.services.Environment;
import org.apache.tapestry.services.FormSupport;
import org.apache.tapestry.util.EnumValueEncoder;

import com.redijedi.tapestry.internal.EnvironmentData;
import com.redijedi.tapestry.internal.GenericValueEncoder;
import com.redijedi.tapestry.internal.InternalUtils;
import com.redijedi.tapestry.internal.LongValueEncoder;
import com.redijedi.tapestry.internal.StringValueEncoder;

/**
 * This component provides the ability to associate a RadioGroup and its
 * subordinate Radio fields with a set of values displayed as a rating scale.
 * This is typified by the "star field" where grayed stars represent the choices
 * and highlighted stars represent the chosen value and all values up to the
 * chosen value from left to right.
 * 

* This is in fact that default visual appearance. However, the images can be * overridden via parameters and the entire component can, of course, be styled * via CSS. *

* As an added benefit, since the underlying representation is simply a * RadioGroup with Radio fields it should degrade well when JS and/or CSS is * disabled. This should keep the component rather accessible. *

* By default the first value display image will be hidden as this typically * will indicate no value. * * @author torr * */ public class RatingField extends AbstractField { @Parameter(value = "prop:componentResources.id", defaultPrefix = "literal") private String _id; @Parameter(required = true) private T _value; @Parameter(required = true) private Object _source; private List _listSource; @Parameter private ValueEncoder _encoder; @Parameter(required = false) private Asset _selectedImage; @Parameter(required = false) private Asset _unselectedImage; @Inject private Environment _environment; @Inject private PageRenderSupport _pageRenderSupport; @Inject @Path("rating.css") private Asset _styleSheet; @Inject @Path("rating_default_selected.gif") private Asset _defaultSelectedImage; @Inject @Path("rating_default_unselected.gif") private Asset _defaultUnselectedImage; @SuppressWarnings("unused") @Component(parameters = { "value=prop:value", "encoder=encoder" }) private RadioGroup _radioGroup; @SuppressWarnings("unused") @Component(parameters = { "source=prop:source", "value=loopValue" }) private Loop _loop; private T _loopValue; @SuppressWarnings("unused") @Component(parameters = { "value=loopValue", "label=prop:radioLabel" }) private Radio _radio; @SuppressWarnings("unused") @Component(parameters = { "for=radio" }) private Label _label; @Inject @Path("rating.js") private Asset _ratingScript; /** * Returns the component's ID. * * @return */ public String getId() { return _id; } public T getValue() { return _value; } public void setValue(T value) { _value = value; } /** * Returns the image representing an unselected value. * * @return */ public Asset getUnselectedImage() { if (_unselectedImage == null) { return _defaultUnselectedImage; } else { return _unselectedImage; } } /** * Returns the image representing a selected value. * * @return */ public Asset getSelectedImage() { if (_selectedImage == null) { return _defaultSelectedImage; } else { return _selectedImage; } } /** * Returns an appropriate ValueEncoder implementation based on the value * type. * * @return */ @SuppressWarnings("unchecked") public ValueEncoder getEncoder() { if (_encoder != null) { return _encoder; } if (getValue() instanceof Long) { return new LongValueEncoder(); } else if (getValue() instanceof Enum) { return new EnumValueEncoder(getValue().getClass()); } else if (getValue() instanceof String) { return new StringValueEncoder(); } else { return new GenericValueEncoder(getSource()); } } /** * Returns a reasonable label for the radio value. If the value is primitive * it will be returned as is. Otherwise the toString() method will be called * on the value object. * * @return */ public String getRadioLabel() { return _loopValue.toString(); } /** * Getter for the loop iteration's value. * * @return */ public Object getLoopValue() { return _loopValue; } /** * Setter for the loop iteration's value. */ public void setLoopValue(T loopValue) { _loopValue = loopValue; } /** * Returns an Iterable implementation of the source provided. * * @return */ public List getSource() { return _listSource; } /* * Event listeners */ /** * Manages adding the correct JS includes into the page head section as well * as initializing the source, etc. */ @SetupRender void setupComponent(MarkupWriter writer) { if (!getIsHeadWritten()) { Element head = writer.getDocument().find("html/head"); // NOTE rating.js has to be included after prototype so it has to // use PageRenderSupport // head.element("script", "type", "text/javascript", "src", // _ratingScript.toClientURL()); _pageRenderSupport.addScriptLink(_ratingScript); head.element("link", "type", "text/css", "href", _styleSheet .toClientURL(), "rel", "stylesheet"); setIsHeadWritten(true); } initSource(); } /* * (non-Javadoc) * * @see org.apache.tapestry.corelib.base.AbstractField#processSubmission(org.apache.tapestry.services.FormSupport, * java.lang.String) */ @Override protected void processSubmission(FormSupport arg0, String arg1) { initSource(); } @SuppressWarnings("unchecked") private boolean getIsHeadWritten() { // see if the head content has been set yet EnvironmentData data = _environment.peek(EnvironmentData.class); if (data == null) { return false; } if (data.containsKey("isRatingHeadSet")) { return (Boolean) data.get("isRatingHeadSet"); } else { return false; } } @SuppressWarnings("unchecked") private void setIsHeadWritten(Boolean written) { // see if the head content has been set yet EnvironmentData data = _environment.peek(EnvironmentData.class); if (data == null) { data = new EnvironmentData(); } data.put("isRatingHeadSet", written); _environment.push(EnvironmentData.class, data); } private void initSource() { if (_source instanceof String) { String stringSource = (String) _source; _listSource = InternalUtils .convertStringToListOfStrings(stringSource); } else if (_source != null && _source.getClass().isArray()) { _listSource = InternalUtils .convertArrayToListOfObjects((Object[]) _source); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy