You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Francois Armand <fa...@linagora.com> on 2007/06/20 10:40:36 UTC

[T5] How to retrieve the id of an event emitter in handler method ?

Hello,

I would like to know how I can retrieve the ID of the component which 
triggered an even when I'm in an event handler method ?

Well, perhaps that my problem is not this problem, so there is a little 
background to help you to decide...

In my application, I have to create a component to manage an editable 
list of string. The available (functional) actions are "add a string", 
"remove a string", "edit string".
I need to present the edit form so that all action can be done in the 
same page :
8<---------------
(note: "string?" are input text field)
| string1 |   _delete_
| string2 |   _delete_
| string3 |   _delete_
_add_a_value
_submit_change_
_reset_
8<---------------

So, there's no real problem to do this : in the html template, I used a 
form component, with a loop component which goes through the list.
I want that if an user edit some field and then want to add/delete a 
value, his modification are kept, so _add_a_value_ and _delete_ are 
submit button. The template looks like :

8<---------------
<t:loop t:source="range"  t:value="index">
    <p>
        <input t:type="TextField"/>
        <t:submit t:id="remove"  value="Remove"/>
    </p>
</t:loop>
<t:submit t:id="add"  value="Add"/>
...
8<---------------

In the Java code, I have two event handler : onSelectedFromAdd() and 
onSelectedFromRemove(), and they are called when matching button are 
submitted.
But for the delete button, I don't know which one was really submitted. 
I would be happy if I can retrieve the id of the submitted "remove": I 
can generate it so that I can retrieve the matching value to remove.
An other option would be to pass a context to the submit event, but I 
don't think it's possible...

So, if you have any idea to help me, they will be well-appreciated...

Francois Armand




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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Francois Armand <fa...@linagora.com>.
Nick Westgate wrote:
> Ok, here is a solution. Took me 5 minutes to write, 20 mins to test. ;-)
Oh. I should have attempt to do it :) thank you very much, works like a 
charm :)
> Yeah, this is exactly what I have implemented. Eventually a shared hidden
> input should probably be used, but I can't see (or perhaps grok) the form
> support for this yet. Also a context that is a list of objects was my 
> plan,
> but the context "passivation" is all internal and relies on the 
> TypeCoercer
> stuff which is a bit involved. This should do for a first cut.
Well, I need at least to deals with List<String> argument, even if it is 
as a (two) simple way, so a change your code as wrote at the end of the 
message. The string of the list are concatenated in the same way a for 
an action link (ex: "value0/value1/value2") so that in the event 
handler, a split give me the different argument. Well, it's clearly not 
robust, it would be better to use TypeCoercer and some other remarks, 
but for now, it would be greatly better to use.

Thanks again for your time !

And thanks to Tapestry developers for the ease of use of T5 !


The code :

8<-------------------------
    @Parameter
    private String _context;
==================>
    @Parameter
    private List<String> _context;
8<-------------------------

8<-------------------------
    void beginRender(MarkupWriter writer)
    {
        // write a hidden input for the context
        String elementName = getElementName();
        writer.element("input", "type", "hidden", "name", elementName + 
"X", "value", _context);
        writer.end();

        // now the submit
        writer.element("input", "type", "submit", "name", elementName, 
"id", getClientId());
    }
==================>
    void beginRender(MarkupWriter writer)
    {
        /* convert context to a string : 
context[0]/context[1]/context[2] ... */
        StringBuilder contextStringBuilder = new StringBuilder("");
        if(null != _context) {
            int j;
            for(int i = 0;  (j = _context.size()-i) > 0 ;i++) {
                contextStringBuilder.append(_context.get(i));
                if(j >1) { contextStringBuilder.append("/"); }
            }
        }
        // write a hidden input for the context
        String elementName = getElementName();
        writer.element("input", "type", "hidden", "name", elementName + 
"X", "value", contextStringBuilder.toString());
        writer.end();

        // now the submit
        writer.element("input", "type", "submit", "name", elementName, 
"id", getClientId());
    }
8<-------------------------

> Diff it to Submit and you'll see it's only a few extra lines. Hope it 
> helps.
>
> Cheers,
> Nick.

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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Ulrich Stärk <ul...@spielviel.de>.
Nick Westgate schrieb:
> Ok, here is a solution. Took me 5 minutes to write, 20 mins to test. ;-)
> 
>  > Ulrich Stark wrote:
>  >> Nick,
>  >>
>  >> there is no difference whether your event method gets triggered upon
>  >> clicking a link or a button. Except that you can pass parameters like
>  >> an index when using actionlink. And that's exactly what you want.
>  >>
> 
> As I said, not if you want your form input fields sent/preserved.
> 

Ahh, now I see the problem. That won't work with what I proposed, indeed.

Uli

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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Nick Westgate <ni...@key-planning.co.jp>.
Ok, here is a solution. Took me 5 minutes to write, 20 mins to test. ;-)

 > Ulrich Stark wrote:
 >> Nick,
 >>
 >> there is no difference whether your event method gets triggered upon
 >> clicking a link or a button. Except that you can pass parameters like
 >> an index when using actionlink. And that's exactly what you want.
 >>

As I said, not if you want your form input fields sent/preserved.

Francois Armand wrote:
 > My use case was : I have a form with a list of text field, for each
 > field a delete (link|button), and a submit button.
 > I want that if an user modify some fields and then click to delete
 > (without submitting the form), the matching value is deleted _and_ other
 > modification are kept.

I've just tested that this works with my SubmitContext component below.

 > To achieve that, the field values have to be transmitted to the server,
 > what is not done with an action link.

Exactly, we need a submit ...

 > So, Nick Westgate point out the good solution (I think), I just need to
 > be done ;)
 >
 > Just to be sure : there is no other solution than to use javascipt to do
 > that ? I was thinking that as Tapestry handle the form action link, it
 > would be possible to add a context to submit button, as example :

The Javascript was used to assign a "tag" (like a context) to a shared
hidden input and then submit the form. But I found another way - just use
a hidden input for each submit.

 > <:tform>
 > ....
 > <t: submit t:id="context" context="value">
 > <t: submit t:id="submit">
 > </t:form>
 >
 > With submit from "submit" button  mapped to action link
 > myformcomponent.form and "context" button mapped to
 > myformcomponent.form/value, and in Java code, context available as now
 > for action link : onSelectedFromContext(String value) {...}

Yeah, this is exactly what I have implemented. Eventually a shared hidden
input should probably be used, but I can't see (or perhaps grok) the form
support for this yet. Also a context that is a list of objects was my plan,
but the context "passivation" is all internal and relies on the TypeCoercer
stuff which is a bit involved. This should do for a first cut.

Diff it to Submit and you'll see it's only a few extra lines. Hope it helps.

Cheers,
Nick.


// Copyright 2007 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.

package your.package.tapestry.components;

import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.MarkupWriter;
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.corelib.base.AbstractField;
import org.apache.tapestry.services.FormSupport;
import org.apache.tapestry.services.Heartbeat;
import org.apache.tapestry.services.Request;

/**
  * Corresponds to &lt;input type="submit"&gt;, a client-side element that can force the
  * enclosing form to submit. The submit responsible for the form submission will post a
  * notification that allows the application to know that it was the responsible entity. The
  * notification is named "selected" and has a String context.
  */
public final class SubmitContext extends AbstractField
{
     static final String SELECTED_EVENT = "selected";

     /**
      * If true, then any notification sent by the component will be deferred until the end of
      * the form submission (this is usually desirable).
      */
     @Parameter
     private boolean _defer = true;

     @Parameter
     private String _context;

     @Environmental
     private FormSupport _formSupport;

     @Environmental
     private Heartbeat _heartbeat;

     @Inject
     private ComponentResources _resources;

     @Inject
     private Request _request;

     public SubmitContext()
     {
     }

     SubmitContext(Request request)
     {
         _request = request;
     }

     void beginRender(MarkupWriter writer)
     {
         // write a hidden input for the context
         String elementName = getElementName();
         writer.element("input", "type", "hidden", "name", elementName + "X", "value", _context);
         writer.end();

         // now the submit
         writer.element("input", "type", "submit", "name", elementName, "id", getClientId());
     }

     void afterRender(MarkupWriter writer)
     {
         writer.end();
     }

     @Override
     protected void processSubmission(FormSupport formSupport, String elementName)
     {
         String value = _request.getParameter(elementName);
         final String context = _request.getParameter(elementName + "X");

         if (value == null)
             return;

         Runnable sendNotification = new Runnable()
         {
             public void run()
             {
                 _resources.triggerEvent(SELECTED_EVENT, new Object[] {context}, null);
             }
         };

         // When not deferred, don't wait, fire the event now (actually, at the end of the current
         // heartbeat). This is most likely because the Submit is inside a Loop and some contextual
         // information will change if we defer. Another option might be to wait until the next
         // heartbeak?

         if (_defer)
             _formSupport.defer(sendNotification);
         else
             _heartbeat.defer(sendNotification);

     }

     // For testing:

     void setDefer(boolean defer)
     {
         _defer = defer;
     }

     void setup(ComponentResources resources, FormSupport support, Heartbeat heartbeat)
     {
         _resources = resources;
         _formSupport = support;
         _heartbeat = heartbeat;
     }
}


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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Francois Armand <fa...@linagora.com>.
Ulrich Stärk wrote:
> Nick,
>
> there is no difference whether your event method gets triggered upon 
> clicking a link or a button. Except that you can pass parameters like 
> an index when using actionlink. And that's exactly what you want.
>
Ok, but if the data are not transmitted to the server, we are not going 
anywhere.
My use case was : I have a form with a list of text field, for each 
field a delete (link|button), and a submit button.
I want that if an user modify some fields and then click to delete 
(without submitting the form), the matching value is deleted _and_ other 
modification are kept.
To achieve that, the field values have to be transmitted to the server, 
what is not done with an action link.

So, Nick Westgate point out the good solution (I think), I just need to 
be done ;)

Just to be sure : there is no other solution than to use javascipt to do 
that ? I was thinking that as Tapestry handle the form action link, it 
would be possible to add a context to submit button, as example :
<:tform>
....
<t: submit t:id="context" context="value">
<t: submit t:id="submit">
</t:form>

With submit from "submit" button  mapped to action link 
myformcomponent.form and "context" button mapped to 
myformcomponent.form/value, and in Java code, context available as now 
for action link : onSelectedFromContext(String value) {...}

But I have absolutely no idea on the feasibility of that.

Between, thanks for the advice and your propositions !


Francois

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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Ulrich Stärk <ul...@spielviel.de>.
Nick,

there is no difference whether your event method gets triggered upon clicking a link or a button. 
Except that you can pass parameters like an index when using actionlink. And that's exactly what you 
want.

Uli

Nick Westgate schrieb:
> This is not useful in a form.
> (Francois did not quote his original email which describes his use case.)
> 
> Cheers,
> Nick.
> 
> 
> Ulrich Stärk wrote:
>> Use an actionlink and it's context parameter. See here: 
>> http://tapestry.apache.org/tapestry5/tapestry-core/guide/event.html
>>
>> Uli
>>
>> Nick Westgate schrieb:
>>> Hi Francois.
>>>
>>> I had a similar situation but was able to use multiple forms,
>>> so each had a different context used for identification.
>>>
>>> T5 needs a LinkSubmit component like that in previous versions
>>> which uses a hidden field and submits the form with Javascript.
>>> I suppose that's a hint if you have time to write one. ;-)
>>>
>>> Cheers,
>>> Nick.
>>>
>>>
>>> Francois Armand wrote:
>>>> Francois Armand wrote:
>>>>> Hello,
>>>>>
>>>>> I would like to know how I can retrieve the ID of the component 
>>>>> which triggered an even when I'm in an event handler method ?
>>>>>
>>>>> [....]
>>>> I'm still interested by an hint on this topic...
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Nick Westgate <ni...@key-planning.co.jp>.
This is not useful in a form.
(Francois did not quote his original email which describes his use case.)

Cheers,
Nick.


Ulrich Stärk wrote:
> Use an actionlink and it's context parameter. See here: 
> http://tapestry.apache.org/tapestry5/tapestry-core/guide/event.html
> 
> Uli
> 
> Nick Westgate schrieb:
>> Hi Francois.
>>
>> I had a similar situation but was able to use multiple forms,
>> so each had a different context used for identification.
>>
>> T5 needs a LinkSubmit component like that in previous versions
>> which uses a hidden field and submits the form with Javascript.
>> I suppose that's a hint if you have time to write one. ;-)
>>
>> Cheers,
>> Nick.
>>
>>
>> Francois Armand wrote:
>>> Francois Armand wrote:
>>>> Hello,
>>>>
>>>> I would like to know how I can retrieve the ID of the component 
>>>> which triggered an even when I'm in an event handler method ?
>>>>
>>>> [....]
>>> I'm still interested by an hint on this topic...
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 

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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Ulrich Stärk <ul...@spielviel.de>.
Use an actionlink and it's context parameter. See here: 
http://tapestry.apache.org/tapestry5/tapestry-core/guide/event.html

Uli

Nick Westgate schrieb:
> Hi Francois.
> 
> I had a similar situation but was able to use multiple forms,
> so each had a different context used for identification.
> 
> T5 needs a LinkSubmit component like that in previous versions
> which uses a hidden field and submits the form with Javascript.
> I suppose that's a hint if you have time to write one. ;-)
> 
> Cheers,
> Nick.
> 
> 
> Francois Armand wrote:
>> Francois Armand wrote:
>>> Hello,
>>>
>>> I would like to know how I can retrieve the ID of the component which 
>>> triggered an even when I'm in an event handler method ?
>>>
>>> [....]
>> I'm still interested by an hint on this topic...
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

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

I had a similar situation but was able to use multiple forms,
so each had a different context used for identification.

T5 needs a LinkSubmit component like that in previous versions
which uses a hidden field and submits the form with Javascript.
I suppose that's a hint if you have time to write one. ;-)

Cheers,
Nick.


Francois Armand wrote:
> Francois Armand wrote:
>> Hello,
>>
>> I would like to know how I can retrieve the ID of the component which 
>> triggered an even when I'm in an event handler method ?
>>
>> [....]
> I'm still interested by an hint on this topic...
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 

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


Re: [T5] How to retrieve the id of an event emitter in handler method ?

Posted by Francois Armand <fa...@linagora.com>.
Francois Armand wrote:
> Hello,
>
> I would like to know how I can retrieve the ID of the component which 
> triggered an even when I'm in an event handler method ?
>
> [....]
I'm still interested by an hint on this topic...



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