text field on change event (onKeyUp binding)

1,056 views
Skip to first unread message

Tadeáš Palusga

unread,
Sep 28, 2011, 7:22:29 AM9/28/11
to tapestry...@googlegroups.com
Hi, I need to use onKeyUp event mixin in my project. I tried to code something ( w-w-w...palusga...cz/2011/09/26/tapestry5-jquery-onkeyup-mixin-for-textfield-elements/#more-69), but I'm not sure, if it is a right way how to do it.

Can anyone review my code and tell me his opinion - it is not full code I used, but I think the base parts are not missing?

Emmanuel DEMEY

unread,
Sep 28, 2011, 12:09:41 PM9/28/11
to tapestry...@googlegroups.com
Hi

It look ok. But we will prefer to use the jQuery philosophy (widget or plugin) instead of a method. You should change your js file, and use the Tapestry-jQuery Widget class.

Manu

Tadeáš Palusga

unread,
Sep 28, 2011, 1:22:56 PM9/28/11
to tapestry...@googlegroups.com
Emmanuel, thanks for your reply. I tried to improve my code to correspond your suggestions.


OnKeyUp.js
$.fn.onkeyup = function(params) {
    zone = params.zone;
    url = params.url;
    options = params.options;

    this.bind('keyup', function() {
        $("#" + zone).tapestryZone('update' , {
              url : url,
              params:  $.extend( { name: $(this).val() }, options),
          });
    });
};

OnKeyUp.java
@ImportJQueryUI({ "jquery.ui.widget", "jquery.ui.core" })
@Import(library = { "OnKeyUp.js" })
public class OnKeyUp extends Widget {
}

example usage:
<t:TextField t:mixins="onkeyup" t:value="name" t:options="{ id: ${id}, url: '${eventLink.value}' ,zone: 'validNameZone'}"/>
<span t:type="zone" class="validNameZone" t:id="validNameZone" id="validNameZone" t:update="show"></span></td>

But I found some problems which I'm not able to solve.
(1. This is not tapestry-jquery-related problem ... I need to improve my code to fire event each xx seconds (e.g. user is typing long text and this means a lot of requests) .. I'll explore autocomplete mixin for solution how "delay" is implemented.)
2. this is tapestry5-jquery related. I need to update zone if after each call of onUpdate event. As you see from my usage example, I'm giving zone name in JSON options, but I want to use standard notation t:zone="XXX". I see simple solution, but it means complete rewrite of widged class and im not sure it is the right way.

trsvax

unread,
Sep 28, 2011, 3:06:28 PM9/28/11
to tapestry5-jquery

I think all you need is a mixin

public class Keyup extends Bind {
}

then
<t:textfield t:mixins="keyup" keyup.event="yourevent"
keyup.zone="yourzone" />

Check out the Bind documentation for more options

Tadeáš Palusga

unread,
Sep 28, 2011, 3:49:53 PM9/28/11
to tapestry...@googlegroups.com
Hi, I know bind and I already tried it,

but there is problem when using bind

imagine this situation:

you need to test if given name exists in BD or not, so need to use something like

onKeyUp(String name)

where name is not static value (so it can't be defined as context parameter .. i need to get this value from $(this).val();) and that is the problem (i think) why bind cannot be used...

I agree that BIND-like solution should be the best solution but im totally lost...


trsvax

unread,
Sep 28, 2011, 4:29:53 PM9/28/11
to tapestry5-jquery
add a parm something like

keyup.callback="function (event,ui,url) {url.addContext( $
{selector:this}.val() )}"

This will add val() to the url so

onKeyUp(String name)

will be called with name set to ${selector:this}.val()

Tadeáš Palusga

unread,
Sep 28, 2011, 6:01:52 PM9/28/11
to tapestry...@googlegroups.com
trsvax, thank you

This solution works perfectly - i used this code in callback: function (event,ui,url) {url.addContext( $(event.target).val() )}

Tadeáš Palusga

unread,
Sep 29, 2011, 8:10:23 AM9/29/11
to tapestry...@googlegroups.com
I'm reopening this discussion again. Solution is perfect, but there is a problem with spaces, diacritics etc.

I have to downgrade to WIDGET solution, because bind method with callbackEvent appends context parameter directly to url. I checked definition of URL object which is passed to callback function and there is only "addContext"  method and Url object does not contains any information about request parameters (and if I ?stepped into? the code, only url value of Url object is used while creating  request) - so there is no chance to change request to store parameter as RequestParameter. So finally i used widget-like code and it works perfectly. I did this, becouse i can have field with czech interpunction, spaces, enters and other white chars etc. I can encode/decode by hand, but when using RequestParameters, Tapestry encodes/decodes it automatically for me and it is much cleaner, because I'm not doing something which is already done and tested.


But in simple cases i see bind-like solution as very useful.


this is my final code


$.fn.onkeyup = function(params) {
    if (!params.delay)
        params.delay = 1500;
    params.queue = "queue_" + "zone";

    this.bind('keyup', function() {
        $(this).unbind();
        bindKeyUp($(this), params);
        valBefore = $(this).val();
        $(this).delay(params.delay, params.queue).queue(params.queue, function(){
            $(this).onkeyup(params);
            valAfter = $(this).val();
            if (valBefore != valAfter)
                bindKeyUp($(this), params);
        }).dequeue(params.queue);
    });
};

function bindKeyUp(element, params) {

    $("#" + zone).tapestryZone('update' , {
          url : url,
          params:  $.extend( { name: element.val() }, params),
      });
}

Barry Books

unread,
Sep 29, 2011, 9:58:26 AM9/29/11
to tapestry...@googlegroups.com
I ran into this same problem and in fact my first implementation of
this used the request parameters but that changes the Tapestry side
event params and I decided I did not like that. Perhaps there should
be a url.addEncodedContext method
Reply all
Reply to author
Forward
0 new messages