Usage:
<input type=”text” t:type=”textField” value=”myValue” t:mixins=”zoneUpdater” zone=”searchResultZone” event=”performSearch” clientEvent=”onkeyup”/>
Then all you have to do is providing a listener method for the performSearch-event in your component/page class.
There is some room for improvement here in terms of more flexibility on event link context and other things. But it works.
There might be improvements in the Tapestry js library to make it easier to obtain and trigger zones. This code was developed with T 5.0.18.
ZoneUpdater.java
@IncludeJavaScriptLibrary("ZoneUpdater.js")public class ZoneUpdater {public static final String PLACEHOLDER = "XXX";@Injectprivate ComponentResources resources;@Environmentalprivate RenderSupport renderSupport;@Parameter(defaultPrefix = BindingConstants.LITERAL)private String clientEvent;@Parameter(defaultPrefix = BindingConstants.LITERAL, required = true)private String event;@InjectContainerprivate ClientElement element;@Parameterprivate Object[] context;@Parameter(defaultPrefix = BindingConstants.LITERAL)// To enable popups to fire events on this document, enter "document" here.private String listeningElement;@Parameter(defaultPrefix = BindingConstants.LITERAL, required = true)private String zone;protected Link createLink(Object[] context) {if (context == null) {context = new Object[1];}context = ArrayUtils.add(context, PLACEHOLDER); // To be replaced by javascriptreturn resources.createEventLink(event, context);}void afterRender() {String link = createLink(context).toAbsoluteURI();String elementId = element.getClientId();if (clientEvent == null) {clientEvent = event;}if (listeningElement == null) {listeningElement = "$('" + elementId + "')";}renderSupport.addScript("new ZoneUpdater('%s', %s, '%s', '%s', '%s', '%s')", elementId, listeningElement, clientEvent, link, zone, PLACEHOLDER);}}
ZoneUpdater.js
var ZoneUpdater = Class.create();ZoneUpdater.prototype = {initialize: function(zoneElementId, listeningElement, event, link, zone, placeholder) {this.zoneElement = $(zoneElementId);this.event = event;this.link = link;this.placeholder = placeholder;$T(this.zoneElement).zoneId = zone;listeningElement.observe(this.event, this.updateZone.bindAsEventListener(this));},updateZone: function(event) {var zoneObject = Tapestry.findZoneManager(this.zoneElement);if ( !zoneObject ) return;var param;if (this.zoneElement.value) {param = this.zoneElement.value;}if (!param) param = ' ';param = this.encodeForUrl(param);var updatedLink = this.link.gsub(this.placeholder, param);zoneObject.updateFromURL(updatedLink);},encodeForUrl: function(string) {/**
* See equanda.js for updated version of this*/string = string.replace(/\r\n/g,"\n");var res = "";for (var n = 0; n < string.length; n++){var c = string.charCodeAt( n );if ( '$' == string.charAt( n ) ){res += '$$';}else if ( this.inRange( c, "AZ" ) || this.inRange( c, "az" ) || this.inRange( c, "09" ) || this.inRange( c, ".." ) ){res += string.charAt( n )}else{var tmp = c.toString(16);while ( tmp.length < 4 ) tmp = "0" + tmp;res += '$' + tmp;}}return res;},inRange: function(code, range) {return code >= range.charCodeAt( 0 ) && code <= range.charCodeAt( 1 );}}
Wow this looks like just what the doctor ordered! Thank you!
ReplyDeleteMan, you have a wrong sample that caused me two hour of work. I've started learning Prototype framework also. So the problem is that event name in clientEvent parameter should not start with "on". It should be just "keyUp" in your sample.
ReplyDeletePlease see http://www.prototypejs.org/api/event/observe for more details of what I am trying to say.
I assure you that it would take more than 2 hours to implement it yourself. Debugging is excellent learning.
ReplyDeleteI guess the line:
ReplyDeleteif(context == null){context=new Object[1]}
should be:
if(context == null){context=new Object[0]}
or is there a need for a null-parameter in the context?
Can you publish the good code of this functionality please ?
ReplyDeleteHere's a similar mixin which is very configurable and supports passing multiple client field values and an optional context.
ReplyDeletehttp://tapestry-stitch.uklance.cloudbees.net/oneventdemo