001 package net.sf.tacos.components.scriptaculous;
002
003 import java.util.Collection;
004 import java.util.HashMap;
005 import java.util.Map;
006
007 import org.apache.tapestry.AbstractComponent;
008 import org.apache.tapestry.IActionListener;
009 import org.apache.tapestry.IDirect;
010 import org.apache.tapestry.IMarkupWriter;
011 import org.apache.tapestry.IRequestCycle;
012 import org.apache.tapestry.IScript;
013 import org.apache.tapestry.Tapestry;
014 import org.apache.tapestry.TapestryUtils;
015 import org.apache.tapestry.engine.DirectServiceParameter;
016 import org.apache.tapestry.engine.IEngineService;
017 import org.apache.tapestry.engine.ILink;
018 import org.apache.tapestry.listener.ListenerInvoker;
019
020 /**
021 * Implementation of the <a href="http://wiki.script.aculo.us/scriptaculous/show/Droppables">Droppables</a>.
022 * <p>
023 * This component makes a html element droppable. Droppables are elements which allow Draggables to be dropped on.
024 * When a draggable is released over a droppable, a listener method may be triggered to inform your application
025 * about the dropped element.
026 * </p>
027 *
028 * <p>Example:
029 * <pre><div jwcid="@tacos:Droppable" listener="listener:onDrop" hoverClass="literal:hoverCss" /></pre>
030 * </p>
031 *
032 * @author Igor Drobiazko
033 * @since 4.1
034 * @see Draggable
035 */
036 public abstract class Droppable extends AbstractComponent implements IDirect{
037 /**
038 * Name of the {@link IRequestCycle} parameter whose value is the
039 * identifier of the dropped draggable
040 * @see {@link IRequestCycle#getParameter(String)}
041 */
042 public static final String DRAGGABLE_PARAMETER = "draggable";
043
044 /**
045 * {@inheritDoc}
046 */
047 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
048 writer.begin(getTemplateTagName());
049 renderIdAttribute(writer, cycle);
050 renderInformalParameters(writer, cycle);
051 renderBody(writer, cycle);
052 writer.end();
053
054 Map params = new HashMap();
055 params.put("component", this);
056 params.put("accept", getAccept());
057 params.put("hoverClass", getHoverClass());
058 if(getListener()!=null)
059 params.put("url", getLink().getURL());
060
061 getScript().execute(this, cycle, TapestryUtils.getPageRenderSupport(cycle, this), params);
062 }
063
064 /**
065 * {@inheritDoc}
066 */
067 public void trigger(IRequestCycle cycle) {
068 IActionListener listener = getListener();
069 if (listener == null)
070 throw Tapestry.createRequiredParameterException(this, "listener");
071
072 getListenerInvoker().invokeListener(listener, this, cycle);
073 }
074
075 /**Returns a link*/
076 private ILink getLink(){
077 return getEngine().getLink(isStateful(), new DirectServiceParameter(this));
078 }
079
080 /** Injected listener parameter, may be null. */
081 public abstract IActionListener getListener();
082 /** Injected script. */
083 public abstract IScript getScript();
084 /** Injected listener invoker. */
085 public abstract ListenerInvoker getListenerInvoker();
086 /** Injected engine service . */
087 public abstract IEngineService getEngine();
088 /**
089 * Returns {@link String[]} or {@link Collection} of strings describing CSS classes.
090 * The Droppable will only accept {@link Draggable} that have one or more of these CSS classes.
091 */
092 public abstract Collection getAccept();
093 /**
094 * Returns the CSS class this Droppable will have
095 * when an accepted {@link Draggable} is hovered over it.
096 */
097 public abstract String getHoverClass();
098 }