You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Apache Wiki <wi...@apache.org> on 2006/05/05 01:18:38 UTC

[Jakarta-tapestry Wiki] Update of "PopupLinkSubmit" by HenriDupre

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jakarta-tapestry Wiki" for change notification.

The following page has been changed by HenriDupre:
http://wiki.apache.org/jakarta-tapestry/PopupLinkSubmit

New page:
== PopupLinkSubmit ==

This is a solution for submitting a form and at the same time open a popup with an external link. It is a little lousy since it requires alot of copy paste from Tapestry code. I hope this can look better with future Tapestry versions.

=== Example===
{{{
<a href="#" jwcid="@PopupLinkSubmit" parameters="ognl:article" listener="listener:acheterArticle" popuppage="PopupPanier" popupparameters="ognl:article.AR_Design">Acheter</a>
}}}


{{{
package actualis.web.tapestry.components;

import java.util.HashMap;
import java.util.Map;

import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.service.BodyBuilder;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.engine.ExternalServiceParameter;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.form.FormConstants;
import org.apache.tapestry.link.DirectLink;

import actualis.web.tapestry.components.form.FormMessages;

/**
 * Implements a component that submits its enclosing form via a JavaScript link. [<a
 * href="../../../../../ComponentReference/LinkSubmit.html">Component Reference</a>]
 * 
 * @author Richard Lewis-Shell
 * @version $Id$
 */

public abstract class PopupLinkSubmit extends CustomSubmit {
  /**
   * The name of an {@link org.apache.tapestry.IRequestCycle}attribute in which
   * the current submit link is stored. LinkSubmits do not nest.
   */

  public static final String ATTRIBUTE_NAME = "actualis.web.tapestry.PopupLinkSubmit";

  public static final String ATTRIBUTE_NAME_SCRIPT = "actualis.web.tapestry.PopupLinkSubmitScript";

  /**
   * The name of an {@link org.apache.tapestry.IRequestCycle}attribute in which
   * the link submit component that generates the javascript function is stored.
   * The function is only required once per page (containing a form with a
   * non-disabled LinkSubmit)
   */
  public static final String ATTRIBUTE_FUNCTION_NAME = "actualis.web.tapestry.PopupLinkSubmit_function";

  @InjectObject("engine-service:external")
  public abstract IEngineService getExternalService();

  /**
   * Checks the submit name ({@link FormConstants#SUBMIT_NAME_PARAMETER}) to
   * see if it matches this LinkSubmit's assigned element name.
   */
  protected boolean isClicked(IRequestCycle cycle, String name) {
    String value = cycle.getParameter(FormConstants.SUBMIT_NAME_PARAMETER);

    return name.equals(value);
  }

  public ILink getLink(IRequestCycle cycle) {
    Object[] pageParameters = DirectLink.constructServiceParameters(getPopupParameters());
    ExternalServiceParameter esp = new ExternalServiceParameter(getPopupPage(),
        pageParameters);

    return getExternalService().getLink(false, esp);
  }

  public abstract Object getPopupParameters();

  public abstract String getPopupPage();

  /**
   * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter,
   *      org.apache.tapestry.IRequestCycle)
   */
  @Override
  protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) {
    boolean disabled = isDisabled();

    if (!disabled) {
      PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle,
          this);

      if (cycle.getAttribute(ATTRIBUTE_NAME_SCRIPT) == null) {
        BodyBuilder builder = new BodyBuilder();

        builder.addln("function {0}(form, elementId, url)", "submitPopupLink");
        builder.begin();
        builder.addln("var form = document.getElementById(form);");       
        builder.addln("form.events.submit(elementId);");        
        builder.addln("aWindow = window.open(url, '" + PopupDirectLink.POPUP_WINDOWNAME
            + "', " + PopupDirectLink.POPUP_FEATURES + ", false);");
        builder.addln("aWindow.focus();");
        builder.end();

        pageRenderSupport.addBodyScript(builder.toString());
        cycle.setAttribute(ATTRIBUTE_NAME_SCRIPT, this);
      }

      IForm form = getForm();

      String slink = getLink(cycle).getURL(null, true);
      Map symbols = new HashMap();
      symbols.put("form", form);
      symbols.put("name", getName());
      symbols.put("popupLink", slink);

      getScript().execute(cycle, pageRenderSupport, symbols);

      writer.begin("a");
      writer.attribute("href", (String) symbols.get("href"));

    }

    renderBody(writer, cycle);

    if (!disabled)
      writer.end();
  }

  public abstract IScript getScript();

  /**
   * @see org.apache.tapestry.AbstractComponent#prepareForRender(org.apache.tapestry.IRequestCycle)
   */
  protected void prepareForRender(IRequestCycle cycle) {
    IComponent outer = (IComponent) cycle.getAttribute(ATTRIBUTE_NAME);

    if (outer != null)
      throw new ApplicationRuntimeException(FormMessages
          .linkSubmitMayNotNest(this, outer), this, getLocation(), null);

    cycle.setAttribute(ATTRIBUTE_NAME, this);
  }

  /**
   * @see org.apache.tapestry.AbstractComponent#cleanupAfterRender(org.apache.tapestry.IRequestCycle)
   */
  protected void cleanupAfterRender(IRequestCycle cycle) {
    cycle.removeAttribute(ATTRIBUTE_NAME);
  }

  /**
   * Links can not take focus, ever.
   */
  protected boolean getCanTakeFocus() {
    return false;
  }

  /**
   * Returns true; the LinkSubmit's body should render during a rewind, even if
   * the component is itself disabled.
   */
  protected boolean getRenderBodyOnRewind() {
    return true;
  }

}
}}}


AbstractSubmit has package visibility! So you need to copy/paste the whole thing.

{{{
package actualis.web.tapestry.components;

import java.util.Collection;

import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.listener.ListenerInvoker;

/**
 * Copy of AbstractSubmit
 */
public abstract class CustomSubmit extends AbstractFormComponent {
  
  /**
   * Determine if this submit component was clicked.
   * 
   * @param cycle
   * @param name
   * @return true if this submit was clicked
   */
  protected abstract boolean isClicked(IRequestCycle cycle, String name);

  /**
   * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
   */
  protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
  {
      if (isClicked(cycle, getName()))
          handleClick(cycle, getForm());
  }
  
  void handleClick(final IRequestCycle cycle, IForm form)
  {
      if (isParameterBound("selected"))
          setSelected(getTag());

      final IActionListener listener = getListener();
      final IActionListener action = getAction();

      if (listener == null && action == null)
          return;

      final ListenerInvoker listenerInvoker = getListenerInvoker();

      Object parameters = getParameters();
      if (parameters != null)
      {
          if (parameters instanceof Collection)
          {
              cycle.setListenerParameters(((Collection) parameters).toArray());
          }
          else
          {
              cycle.setListenerParameters(new Object[]
              { parameters });
          }
      }

      // Invoke 'listener' now, but defer 'action' for later
      if (listener != null)
        listenerInvoker.invokeListener(listener, CustomSubmit.this, cycle);
      
      if (action != null) {
            Runnable notify = new Runnable()
            {
                public void run()
                {
                    listenerInvoker.invokeListener(action, CustomSubmit.this, cycle);
                }
            };
    
          form.addDeferredRunnable(notify);
      }
  }

  /** parameter */
  public abstract IActionListener getListener();

  /** parameter */
  public abstract IActionListener getAction();

  /** parameter */
  public abstract Object getTag();

  /** parameter */
  public abstract void setSelected(Object tag);

  /** parameter */
  public abstract boolean getDefer();

  /** parameter */
  public abstract Object getParameters();

  /** Injected */
  public abstract ListenerInvoker getListenerInvoker();  
}
}}}

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org