Looks good! It would be even safer to generate a link with placeholders, but your approach is probably safe enough. The thing we're really missing here is a hook in Tapestry.js that does something similar to the example code below.
Tapestry.prototype.appendLinkContext = function(linkId, value) { var oldHref = $(linkId).href; return oldHref + '/' + encode(value); } On Sun, Nov 15, 2009 at 1:44 AM, Jonhy Pear <jonhy.p...@gmail.com> wrote: > Thanks Magnus and Inge, > > Your really helped me to find a possible solution. > I created a mixin called InjectClientValue and used it like this: > > <a t:type="actionlink" t:id="verifyDuplicatedLogin" href="#" > t:mixins="injectClientValue" > t:sourceElementId="login" > > > t:updateElementId="loginDuplicatedNotice">${message:verify-login-duplicated-link}</a> > > sourceElementId is the id of the input from where I want to read the value > to send to the server. > > > In my tml I have a div: > > <div id="loginDuplicatedNotice"></div> > > My InjectClientValue.js is as follows: > > InjectClientValue.prototype = { > initialize : function(sourceElement, eventElement, updateElement) { > this.sourceElement = $(sourceElement); > this.element = $(eventElement); > this.updateElement = $(updateElement) > this.element.observe('click', > this.onClick.bindAsEventListener(this)); > }, > > onClick : function(event) { > var currentInstance = this; > Tapestry.debug(this.sourceElement.value); > Tapestry.debug(this.element.href); > > if (this.sourceElement == null) { > Tapestry.error("Error: sourceElement is null"); > event.stop(); > return; > } > if (this.element == null) { > Tapestry.error("Error: element is null"); > event.stop(); > return; > } > if (this.updateElement == null) { > Tapestry.error("Error: updateElement is null"); > event.stop(); > return; > } > if (this.sourceElement.value == "") { > > Tapestry.warn("Error: sourceElement is empty"); > event.stop(); > return; > } > > new Ajax.Request(this.element.href + "/" + this.sourceElement.value, > { > method : 'get', > onSuccess : function(transport) { > currentInstance.updateElement > .update(transport.responseJSON.content); > } > }); > event.stop(); > > } > > } > > //End > > This is working now, but I would like you to comment. > > Thank you > > > On Thu, Nov 12, 2009 at 11:15 AM, Inge Solvoll <inge.tapes...@gmail.com > >wrote: > > > See my blog for a relevant implementation that has (among other things) a > > possible pattern to solve your problem. The pattern is to generating the > > action link with placeholders on page setup, pass it to javascript, and > > create a javascript function that replaces the placeholders runtime on > > client. Then wrap it in a component or a mixin. > > > > > > > http://tinybits.blogspot.com/2009/05/update-zone-on-any-client-side-event.html > > > > You could vote for this JIRA-issue, which also is a suggestion for making > > these things easier to do: > > > > https://issues.apache.org/jira/browse/TAP5-521 > > > > Inge > > > > On Thu, Nov 12, 2009 at 9:41 AM, Magnus Rundberget <run...@me.com> > wrote: > > > > > Hi, > > > > > > > > > Others will surely correct me if I'm wrong... > > > - Ideally you should be able to create a mixin for the onclick event on > > the > > > actionlink that picks up the value of the textfield and sets the > context > > > before the tapestry actionlink event triggers. However since the > > actionlink > > > is tied to a zone this is not so trivial. Something to do with > > > indeterministic ordering of events in javascript i believe > > > > > > > > > I can see a couple of other alternatives; > > > 1. Event and a little javascript using prototype and its inbuildt > support > > > for ajax requests. Haven't tested the below so a big disclaimer here > :-) > > > > > > A) Sample Javascript - checkusername.js; > > > CheckUserNameLink.prototype = { > > > initialize: function(elementId, requestUrl) > > > { > > > this.elementId = elementId; > > > this.requestUrl = requestUrl; > > > > > > Event.observe($(this.elementId), 'click', > > > this._click.bindAsEventListener(this)); > > > }, > > > _click: function(theEvent) > > > { > > > var url = this.requestUrl + "/" + > > encodeURIComponent($('userName')); > > > // adding the username as a context param to event > > > new Ajax.Request(this.requestUrl, { > > > method: 'get', > > > onSuccess: function(transport) { > > > var isTaken = transport.responseJSON.isTaken; > > > if (isTaken === 'true') { > > > // javascript to tell user the username is take... > update > > a > > > div/span or whatever > > > } > > > } > > > }); > > > } > > > }; > > > > > > B) In your TML > > > remove the zone/replace with an empty div/span or whatever > > > <a href="#" > > > > > > id="d="verifyDuplicatedUserName"">${message:verify-username-duplicated-link}</a> > > > > > > > > > C) In your page class > > > // above class definition > > > @IncludeJavaScriptLibrary({"context:js/checkusername.js"}) > > > > > > > > > // inside class body > > > private static final String CHECK_USER_NAME_EVENT = "checkusername"; > > > > > > @Inject > > > private RenderSupport renderSupport; > > > > > > @Inject > > > private ComponentResources componentResources; > > > > > > @AfterRender > > > void afterRender() { > > > Link link = > > > componentResources.createEventLink(CHECK_USER_NAME_EVENT); > > > renderSupport.addScript("new CheckUserNameLink('%s', '%s');", > > > "verifyDuplicatedUserName", link.toAbsoluteURI); > > > } > > > > > > @OnEvent(value = CHECK_USER_NAME_EVENT) > > > public Object onVerifyUserName(String userName) { > > > > > > //... do whatever you need to verify if username is taken > > > > > > // return result as json > > > JSONObject response = new JSONObject(); > > > response.put("isTaken", isTaken); > > > return response; > > > } > > > > > > > > > 2. Autocomple: You might use the autocomplete mixin for textfield ? > > > ...have to be creative to make it user friendly though ... > > > > > > > > > > > > cheers > > > rundis > > > > > > > > > > > > > > > > > > > > > I'm still getting started with Tapestry by doing some stuff, but... > many > > >> questions. > > >> > > >> This one is in regards to AJAX. It's a "How to" kinda question. > > >> > > >> I Have a form like this in my page.tml: > > >> > > >> <form t:type="form" t:id="registrationForm" clientValidation="false"> > > >> <t:label for="userName" /> > > >> > > >> <input t:type="TextField" t:id="userName" value="user.name" > > >> t:validate="required, > > >> maxlength=15, minLength=3" size="15" /> > > >> <t:zone t:id="userNameDuplicatedNotice">${userExistMessage}</t:zone> > > >> > > >> <a t:type="actionlink" t:id="verifyDuplicatedUserName" > > >> context="literal:testing" > > >> href="#" > > >> > > > t:zone="userNameDuplicatedNotice">${message:verify-username-duplicated-link}</a> > > >> > > >> <input type="submit" value="${message:label.submit.create.user}" /> > > >> > > >> </form> > > >> > > >> What I'm trying to figure out is: What is the best way to give the > > current > > >> value of textfield "userName" to the context of the link > > >> "verifyDuplicatedLogin"? > > >> > > >> Let me try to express with a user story: > > >> > > >> As a user I want to introduce a user name and click in a link to > > >> automatically(AJAX) receive a message informing me if the "userName" > is > > >> already taken or not > > >> > > >> > > >> > > >> Thank you, > > >> > > >> jp > > >> > > > > > > > > > --------------------------------------------------------------------- > > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > > > For additional commands, e-mail: users-h...@tapestry.apache.org > > > > > > > > >