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 }