You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by bobby rullo <br...@alexanderinteractive.com> on 2005/03/01 22:48:52 UTC
Re: JavaScript calling a listener
Funnily enough I ran into the same issue today! It took some doing, but what I
ended up doing is creating a custom component called DirectOnChange. What you
do is you give the DirectOnChange (DOC from now on) two params: one is the
form component that you wish to have trigger a listener, and the second is
the listener itself.
Whenever you change the value of the form component on the client side, a
javascript method triggers the listener method with the param being the new
value.
Caveats:
1) Right now it only works with radios (cuz that's what I needed it for. But
this is EASILY fixed with a little more javascript.
2) I've only tested this with Integers as the listener params, but String
should work.
Here is the code. It is VERY rough, but I just wanted to get it up here asap to
help. I obscured the package names to protect the guilty:
DirectOnChange.jwc:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->
<component-specification
class="com.xxx.xxx.xxx.DirectOnChange"
allow-body="yes"
allow-informal-parameters="yes">
<description>[CDATA[ Enter a description ]]</description>
<parameter name="listener" type="org.apache.tapestry.IActionListener"
direction="auto"
required="yes"/>
<parameter name="component"
type="org.apache.tapestry.form.AbstractFormComponent"
direction="auto"
required="yes"/>
</component-specification>
DirectOnChange.java
package com.xxx.xxx.xxx.xxx
import java.util.HashMap;
import org.apache.tapestry.AbstractComponent;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IDirect;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IResourceLocation;
import org.apache.tapestry.IScript;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.DirectService;
import org.apache.tapestry.engine.IScriptSource;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.html.Body;
/**
* @author br
*
*/
public abstract class DirectOnChange extends AbstractComponent
implements IDirect{
private IScript script = null;
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
if (cycle.isRewinding()){
return;
}
DirectService direct = (DirectService) cycle.getEngine().getService(
Tapestry.DIRECT_SERVICE);
String url = direct.getLink(cycle, this,
new Object[] { "REPLACE_ME" }).getURL();
HashMap symbols = new HashMap();
symbols.put("component", getComponent());
symbols.put("url", url);
getScript(cycle).execute(cycle, Body.get(cycle), symbols);
}
private IScript getScript(IRequestCycle cycle){
if (script == null){
IScriptSource source = cycle.getEngine().getScriptSource();
IResourceLocation specLocation = getSpecification().getLocation()
.getResourceLocation();
IResourceLocation scriptLocation = specLocation
.getRelativeLocation("DirectOnChange.script");
script = source.getScript(scriptLocation);
}
return script;
}
/**
* @param cycle
*
* @see org.apache.tapestry.IDirect#trigger(org.apache.tapestry.
* IRequestCycle)
*/
public void trigger(IRequestCycle cycle) {
IActionListener listener = getListener();
if (listener == null)
throw Tapestry.createRequiredParameterException(this, "listener");
listener.actionTriggered(this, cycle);
}
/**
* @return
*
* @see org.apache.tapestry.IDirect#isStateful()
*/
public boolean isStateful() {
return false;
}
public abstract IActionListener getListener();
public abstract AbstractFormComponent getComponent();
}
DirectOnChange.script
<?xml version="1.0"?>
<!DOCTYPE script PUBLIC
"-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Script_3_0.dtd">
<script>
<!--
This script is to support the DirectOnChange component
component: the component that when changed will trigger a listener.
url: the url with REPLACE_ME as the service params
-->
<input-symbol key="component"
class="org.apache.tapestry.form.AbstractFormComponent" required="yes"/>
<input-symbol key="url" class="java.lang.String" required="yes" />
<let key="formObject">
document.${component.form.name}
</let>
<let key="functionName" unique="yes">
onchange_${component.name}
</let>
<body>
<![CDATA[
function ${functionName}(param) {
var re = /SREPLACE_ME/ ;
var url = "${url}"
url = url.replace(re, param);
location.replace(url);
}
]]>
</body>
<initialization>
<![CDATA[
{
var element = ${formObject}["${component.name}"];
var elements = ${formObject}.elements;
//this means the element is a radio group or check group
if (element.length) {
//first define the function
var myFunction = function(){
var element = ${formObject}["${component.name}"];
var value;
for (var x = 0; x < element.length;x++) {
//alert(element[x]);
if (element[x].checked){
value = element[x].value;
${functionName}(value);
return;
}
}
};
for (x = 0 ; x < elements.length; x++) {
element[x].onchange = myFunction;
}
} else {
//alert("no!");
if (element.type == "radio") {
//alert("it's a radio");
var myFunction = function(){
var element = ${formObject}["${component.name}"];
${functionName}(element.value);
}
element.onchange = myFunction;
}
}
}
]]>
</initialization>
</script>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org