You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by ty renner <my...@gmail.com> on 2005/06/15 02:52:34 UTC

problem with tapestry and javascript, need help!

Hi,

I have a table whose rows are rendered dynamically usinf tapestry
ForEach component. I want to make these rows "hot" so they can be
selected by clicking anywhere on the row. The only way to capture the
onclick event is through javascript and then I want to call a listener
method in the page class. How can this be done? How can I call a
listener method from inside javascript?

Can someone help?

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


Re: problem with tapestry and javascript, need help!

Posted by Norbert Sándor <de...@freemail.hu>.
You can still use Tapestry's link components like DirectLink.
What you need to do is to create a custom link renderer (an implementation 
of ILinkRenderer) and pass it as the "renderer" parameter.

Check out the source code of the built-in ButtonLinkRenderer (4.0). (If you 
use Tapestry 3 then looking at DefaultLinkRenderer may help too but 
ButtonLinkRenderer is very similar to what you want to do!)
ButtonLinkRenderer generates a <button> element, you need to change it to 
<tr>, remove the "type" and "disabled" attributes and you are ready (I think 
:).
Of course if you take this approach then your Foreach component should not 
generate the <tr> tags.

Hope this helps.
Br,
Norbi

----- Original Message ----- 
From: "ty renner" <my...@gmail.com>
To: <ta...@jakarta.apache.org>
Sent: Wednesday, June 15, 2005 2:52 AM
Subject: problem with tapestry and javascript, need help!


Hi,

I have a table whose rows are rendered dynamically usinf tapestry
ForEach component. I want to make these rows "hot" so they can be
selected by clicking anywhere on the row. The only way to capture the
onclick event is through javascript and then I want to call a listener
method in the page class. How can this be done? How can I call a
listener method from inside javascript?

Can someone help?

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





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


Re: problem with tapestry and javascript, need help!

Posted by Nick Westgate <ni...@key-planning.co.jp>.
Hi.

I've created clickable table elements.

Your javascript can't directly call a listener method.
This must be done from within a Tapestry component as
Norbert pointed out in his post.

Just choose a component most similar to what you want.
(I chose LinkSubmit, because I'm operating inside a form.)
Then hack it to output what you want.

For instance, I mixed in functionality from the "Any"
component. This means my "AnySubmit" is used like this:

<td jwcid="@AnySubmit" listener="..."/>

It automatically takes the <td> tag from the template.
Source code is below, though it's still a bit hacky.
Diff this to the original LinkSubmit source to see that
it's not so hard.

Cheers,
Nick.


---
AnySubmit.java
---

//Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import org.apache.tapestry.ApplicationRuntimeException;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IBinding;
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.form.LinkSubmit;
import org.apache.tapestry.html.Body;

/**
  *  Implements a component that submits its enclosing form via JavaScript onClick.
  *
  *  @author Richard Lewis-Shell (original LinkSubmit code)
  *  @author Nick Westgate (hacked into AnySubmit)
  *  @version $Id: Submit.java,v 1.6 2003/04/21 13:15:41 glongman Exp $
  *
  **/

public abstract class AnySubmit extends AbstractFormComponent
{
     /**
      *  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          = LinkSubmit.ATTRIBUTE_NAME;

     /**
      * 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 = LinkSubmit.ATTRIBUTE_FUNCTION_NAME;

     protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
     {
         String element = getElement();

         if (element == null)
             throw new ApplicationRuntimeException(
                 Tapestry.getMessage("Any.element-not-defined"),
                 this,
                 null,
                 null);

         IForm form = getForm(cycle);
         String formName = form.getName();

         boolean rewinding = form.isRewinding();

         String name = form.getElementId(this);

         IMarkupWriter wrappedWriter;

         if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
             throw new ApplicationRuntimeException(
                 Tapestry.getMessage("LinkSubmit.may-not-nest"), this, null, null);

         cycle.setAttribute(ATTRIBUTE_NAME, this);

         boolean disabled = isDisabled();
         if (!disabled)
         {
             if (!rewinding)
             {
                 Body body = Body.get(cycle);

                 if (body == null)
                     throw new ApplicationRuntimeException(Tapestry.format(
                         "must-be-contained-by-body", "LinkSubmit"), this, null, null);

                 // make sure the submit function is on the page (once)
                 if (cycle.getAttribute(ATTRIBUTE_FUNCTION_NAME) == null)
                 {
                     body.addBodyScript("function submitLink(form, elementId) { form._linkSubmit.value = elementId; if (form.onsubmit == null || form.onsubmit()) form.submit(); }");
                     cycle.setAttribute(ATTRIBUTE_FUNCTION_NAME, this);
                 }

                 // one hidden field per form:
                 String formHiddenFieldAttributeName = ATTRIBUTE_FUNCTION_NAME + formName;
                 if (cycle.getAttribute(formHiddenFieldAttributeName) == null)
                 {
                     body.addInitializationScript("document." + formName + "._linkSubmit.value = null;");
                     writer.beginEmpty("input");
                     writer.attribute("type", "hidden");
                     writer.attribute("name", "_linkSubmit");
                     cycle.setAttribute(formHiddenFieldAttributeName, this);
                 }
             }
             else
             {
                 // How to know which Submit link was actually
                 // clicked?  When submitted, it sets its elementId into a hidden field

                 String value = cycle.getRequestContext().getParameter("_linkSubmit");

                 // If the value isn't the elementId of this component, then this link wasn't
                 // selected.

                 if (value != null && value.equals(name))
                 {
                     IBinding selectedBinding = getSelectedBinding();
                     if (selectedBinding != null)
                         selectedBinding.setObject(getTag());
                     IActionListener listener = getListener();
                     if (listener != null)
                         listener.actionTriggered(this, cycle);
                 }
             }

             writer.begin(element);
             writer.attribute("style", "cursor:pointer;");
             writer.attribute("onClick", "javascript:submitLink(document." + formName + ",\""
                 + name + "\");");
         }
         else
         {
             writer.begin(element);
         }

         // Allow the wrapped components a chance to render.
         // Along the way, they may interact with this component
         // and cause the name variable to get set.

         wrappedWriter = writer.getNestedWriter();

         renderBody(wrappedWriter, cycle);

         // Generate additional attributes from informal parameters.
         renderInformalParameters(writer, cycle);

         // Dump in HTML provided by wrapped components
         wrappedWriter.close();

         // Close the tag
         writer.end();

         cycle.removeAttribute(ATTRIBUTE_NAME);
     }

     public abstract boolean isDisabled();

     public abstract void setDisabled(boolean disabled);

     public abstract IActionListener getListener();

     public abstract void setListener(IActionListener listener);

     public abstract Object getTag();

     public abstract void setTag(Object tag);

     public abstract void setSelectedBinding(IBinding value);

     public abstract IBinding getSelectedBinding();

     public abstract String getElement();
}

---
AnySubmit.jwc
---

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Copyright 2004 The Apache Software Foundation

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
-->
<!-- $Id: Any.jwc,v 1.5 2004/02/29 18:49:13 harishkswamy Exp $ -->
<!DOCTYPE component-specification PUBLIC
   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<component-specification class="jp.co.key_planning.common.AnySubmit">

   <description>
   Dynamically emulates any element, including attributes (provided as
   informal parameters).
   </description>

   <parameter name="listener"
   	type="org.apache.tapestry.IActionListener"
   	direction="in">
   	<description>
	    The listener is invoked during the rewind as the link component is encountered.  This is
	    both attractive and dangerous when combined with a form.  When the listener is
	    invoked, the form has not completely rewound, so not all form values have necessarily
	    been processed, so the listener might be performing its logic based on inconsistent
	    data.
   	</description>
   </parameter>
   	
   <parameter name="element" type="java.lang.String" direction="in" required="no" default-value="templateTag">
   	<description>
   	The element to emulate.
   	</description>
   </parameter>
     <parameter name="disabled" type="boolean" direction="in"/>
     <parameter name="selected"/>
     <parameter name="tag" type="java.lang.Object" direction="in"/>

   <parameter name="templateTag" type="java.lang.String" direction="auto" required="no" default-value="null">
   	<description>
   	The tag used to add this component in a template.
   	</description>
   </parameter>

   	<reserved-parameter name="name"/>
     <reserved-parameter name="onClick"/>

     <property-specification name="name" type="java.lang.String"/>
     <property-specification name="form" type="org.apache.tapestry.IForm"/>
</component-specification>


ty renner wrote:
> Hi,
> 
> I have a table whose rows are rendered dynamically usinf tapestry
> ForEach component. I want to make these rows "hot" so they can be
> selected by clicking anywhere on the row. The only way to capture the
> onclick event is through javascript and then I want to call a listener
> method in the page class. How can this be done? How can I call a
> listener method from inside javascript?
> 
> Can someone help?
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 

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