Re: Activation context for a component?

2010-02-14 Thread Thiago H. de Paula Figueiredo
On Sun, 14 Feb 2010 17:33:43 -0200, Nathan Kopp  
 wrote:



Even with your suggested change, this would still generate a null pointer
exception (NPE) in the same place, since the problem lies with  
"fooLoopVar" being null when the eventlink is click is processed by  
Tapestry.


You simply can't use it in the EventLink method handler.


The NPE
happens before I even get to rendering the description text field.


Never forget that T5 uses redirect after post, so the event handling  
request is not the same as the render request.


--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.

http://www.arsmachina.com.br

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



Re: Activation context for a component?

2010-02-14 Thread Nathan Kopp
Good thought, but the copy of Donkey isn't the problem.  (Actually, when
using Hibernate or JPA, you'd want to make a copy to allow "cancel" to work,
because altering a JPA entity by binding directly to the "real" instance
could cause the database to be updated immediately... JPA/Hibernate doesn't
wait for you to call any saveToDb or persist method.)  Note that my instance
used for editing has the @Persist annotation, so Tapestry does a great job
remembering its state.

Even with your suggested change, this would still generate a null pointer
exception (NPE) in the same place, since the problem lies with "fooLoopVar"
being null when the eventlink is click is processed by Tapestry.  The NPE
happens before I even get to rendering the description text field.

-Nathan

On Sun, Feb 14, 2010 at 2:02 PM,  wrote:

> Hi Nathan,
>
> > Anywhere on my site where I display a Donkey, I want to let the user edit
> the instance.
> So then do exactly that... Tapestry 5 is sometimes simpler than you might
> expect, to me it seems you are complicating things unnecessarily... why are
> you creating new instances when editing? You shouldn't need to, simply pass
> in foo and call getDonkey and edit that instance. Your loop should just
> work, simply bind foo and the correct instance will always be bound, with a
> new instance of the inlinedit component for every iteration, so you have no
> need for extended context info in this case.
>
>
>Here's a foo: ${fooLoopVar.name}
> 
>
>
>
> public class ViewDonkeyInlineEdit
> {
>@Parameter (allownull=false, required=true)
>@Property
>private Foo foo;
>
>
>//wired to your event onEdit etc.
>@Persist @Property private Boolean isEditing;
>
>
>public void onSaveEditDonkey() {
>foo.getDonkey().saveToDB();
>}
> }
>
>
> Description: 
>
> Its that simple.
>
> Peter
>
>
> - Original Message -
> From: "Nathan Kopp" 
> To: users@tapestry.apache.org
> Sent: Sunday, 14 February, 2010 04:10:02 GMT +02:00 Athens, Beirut,
> Bucharest, Istanbul
> Subject: Activation context for a component?
>
> Hey everyone!  I'm new here and I apologize for not lurking long before
> posting.  I have searched the archives extensively for this issue and have
> come up empty, so I'm just going to jump in.
> [clip]
>


Re: Activation context for a component?

2010-02-14 Thread Thiago H. de Paula Figueiredo

Hi!

On Sun, 14 Feb 2010 00:10:02 -0200, Nathan Kopp   
wrote:



There are two things preventing this from working:
First, Tapestry does not replay the loop when processing the eventlink  
(like it did in the 3.x and 4.x days).  Therefore, "fooLoopVar" never  
gets changed from its default of null.


Tapestry 5 doesn't have the rewind phase like previous versions had. And  
that's a very good thing, because it was quite complicated to understand  
and make it work. You should use the context parameter of EventLink and  
ActionLink to pass information to the event handler method.



Second, there's only one instance of  the ViewDonkeyInlineEdit component
inside the loop.


Yes. Less memory usage! The solution is the same as above.


All of the eventlink URLs look identical, so there's no
way to tell which Donkey should be edited.


See above.

I tried using the "context" parameter of the eventlink component, but  
since events start at the deepest level and bubble up,


It starts at the EventLink instance level, not from the deepest one.

I got the null pointerexception before I could use the context for  
anything useful at the outer

(page) level.


This looks like a bug in your code, most probably by working in a T4-ish  
way in T5.



In Test.java, I added:
String onPassivate() {
return fooLoopVar==null?null:fooLoopVar.getName();
}


You shouldn't rely in a variable used as a Loop object (in this case,  
fooLoopVar), as T5 doesn't have a rewind phase.


Basically, I need something that works like the page activation context,  
but generalized to work with any component at any level of the component  
tree.


Inject ComponentEventLinkEncoder and use its  
decodePageRenderRequest(Request request) method (when rendering) or  
decodePageRenderRequest(Request request) (when handling an event). Both  
methods return an object that contains the page activation context.


--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.

http://www.arsmachina.com.br

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



Re: Activation context for a component?

2010-02-14 Thread P . Stavrinides
Hi Nathan,

> Anywhere on my site where I display a Donkey, I want to let the user edit the 
> instance.
So then do exactly that... Tapestry 5 is sometimes simpler than you might 
expect, to me it seems you are complicating things unnecessarily... why are you 
creating new instances when editing? You shouldn't need to, simply pass in foo 
and call getDonkey and edit that instance. Your loop should just work, simply 
bind foo and the correct instance will always be bound, with a new instance of 
the inlinedit component for every iteration, so you have no need for extended 
context info in this case.  


Here's a foo: ${fooLoopVar.name}




public class ViewDonkeyInlineEdit
{
@Parameter (allownull=false, required=true)
@Property
private Foo foo;


//wired to your event onEdit etc.
@Persist @Property private Boolean isEditing;


public void onSaveEditDonkey() {
foo.getDonkey().saveToDB();
}
}


Description: 

Its that simple.

Peter

 
- Original Message -
From: "Nathan Kopp" 
To: users@tapestry.apache.org
Sent: Sunday, 14 February, 2010 04:10:02 GMT +02:00 Athens, Beirut, Bucharest, 
Istanbul
Subject: Activation context for a component?

Hey everyone!  I'm new here and I apologize for not lurking long before
posting.  I have searched the archives extensively for this issue and have
come up empty, so I'm just going to jump in.

I'm working in Tapestry 5.1.0.5 (the latest as far as I know) and I've run
into a use-case that I can't figure out how to solve cleanly with T5.  I
actually used Tapestry extensively back in the 3.x and 4.x days, partially
because it could solve this particular use case very well when other
frameworks would fall flat.  Unfortunately, Tapestry works differently now,
so I think I need some help solving this in the new paradigm.  Also, this is
really long, because I wanted to include lots of code to give really good
context to my question.  Here goes:

I have two objects, let's call them Foo and Donkey (shout-out to the Java
Posse).  Each Foo object contains a Donkey object, like this:

public class Donkey {
private String name;
private String descr;
// constructor & getters/setters go here
}

public class Foo {
private String name;
private Donkey donkey;
// constructor & getters/setters go here
}

Now... the Donkey object represents user-contributed content.  Anywhere on
my site where I display a Donkey, I want to let the user edit the instance.
 To do this, I've created a reusable custom component that displays the
Donkey, including inline editing capabilities.  It's rudimentary now, but
eventually it'll probably use an Ajax modal popup from ChenilleKit.

==ViewDonkeyInlineEdit.tml===
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
xmlns:p="tapestry:parameter">
Donkey's name: ${donkey.name}



Description: 
 Cancel


Description: ${donkey.descr} Edit



ViewDonkeyInlineEdit.java=
public class ViewDonkeyInlineEdit
{
@Property @Parameter private Donkey donkey;
@Persist @Property private Donkey editDonkey;
public boolean isEditing() {
return (editDonkey!=null &&
editDonkey.getName().equals(donkey.getName()));
}
public void onStartEditDonkey() {
editDonkey = new Donkey(donkey.getName(), donkey.getDescr());
}
public void onSaveEditDonkey() {
donkey.setDescr(editDonkey.getDescr());
editDonkey = null;
}
public void onCancelEditDonkey()  {
editDonkey = null;
}
}
==

Now, let's use it in a page:
 Test.tml ==
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
  xmlns:p="tapestry:parameter">

Here's a foo: ${firstFoo.name}


Here's a foo: ${secondFoo.name}


Here's a foo: ${thirdFoo.name}


=

This works great.  No problems.

Clearly, though, this is *screaming* to be put into a loop.  So, let's try
this:

=== Test.tml (version 2) =
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
   xmlns:p="tapestry:parameter">

Here's a foo: ${fooLoopVar.name}



==

Of course, this doesn't work.  (If it did work, I wouldn't be writing this
message right now.)  When I click the "edit" link to triggger the
"startDonkeyEdit" event, I get a null pointer exception.

There are two things preventing this from working:
First, Tapestry does not replay the loop when processing the eventlink (like
it did in the 3.x and 4.x days).  Therefore, "fooLoopVar" never gets changed
from its default of null.
Second, there's only one instance of  the ViewDonkeyInlineEdit component
inside the loop.  All of the eventlink URLs look identical, so there's no
way to tell which Donkey should be edited.

I tried

Re: [T5.2.0-SNAPSHOT] Block to String without MarkupWriter

2010-02-14 Thread Howard Lewis Ship
Nothing obvious is coming to me; a Block represents markup and needs a
markup writer to execute. You can leverage some of the internal
Tapestry services to render the content much like a partial page
render, perhaps.

On Thu, Jan 28, 2010 at 8:36 AM, Joost Schouten (ml)
 wrote:
> Hi,
>
> I have Build a GridToCSVExport mixin. This all works great up to the stage
> where I try render the override parameter blocks like "propertyNameCell". I
> can obtain the Block's, but can see no way to render the block to String
> without a MarkupWriter. Any pointers would be  appreciated.
>
> Cheers,
> Joost
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

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



Activation context for a component?

2010-02-14 Thread Nathan Kopp
Hey everyone!  I'm new here and I apologize for not lurking long before
posting.  I have searched the archives extensively for this issue and have
come up empty, so I'm just going to jump in.

I'm working in Tapestry 5.1.0.5 (the latest as far as I know) and I've run
into a use-case that I can't figure out how to solve cleanly with T5.  I
actually used Tapestry extensively back in the 3.x and 4.x days, partially
because it could solve this particular use case very well when other
frameworks would fall flat.  Unfortunately, Tapestry works differently now,
so I think I need some help solving this in the new paradigm.  Also, this is
really long, because I wanted to include lots of code to give really good
context to my question.  Here goes:

I have two objects, let's call them Foo and Donkey (shout-out to the Java
Posse).  Each Foo object contains a Donkey object, like this:

public class Donkey {
private String name;
private String descr;
// constructor & getters/setters go here
}

public class Foo {
private String name;
private Donkey donkey;
// constructor & getters/setters go here
}

Now... the Donkey object represents user-contributed content.  Anywhere on
my site where I display a Donkey, I want to let the user edit the instance.
 To do this, I've created a reusable custom component that displays the
Donkey, including inline editing capabilities.  It's rudimentary now, but
eventually it'll probably use an Ajax modal popup from ChenilleKit.

==ViewDonkeyInlineEdit.tml===
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
xmlns:p="tapestry:parameter">
Donkey's name: ${donkey.name}



Description: 
 Cancel


Description: ${donkey.descr} Edit



ViewDonkeyInlineEdit.java=
public class ViewDonkeyInlineEdit
{
@Property @Parameter private Donkey donkey;
@Persist @Property private Donkey editDonkey;
public boolean isEditing() {
return (editDonkey!=null &&
editDonkey.getName().equals(donkey.getName()));
}
public void onStartEditDonkey() {
editDonkey = new Donkey(donkey.getName(), donkey.getDescr());
}
public void onSaveEditDonkey() {
donkey.setDescr(editDonkey.getDescr());
editDonkey = null;
}
public void onCancelEditDonkey()  {
editDonkey = null;
}
}
==

Now, let's use it in a page:
 Test.tml ==
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
  xmlns:p="tapestry:parameter">

Here's a foo: ${firstFoo.name}


Here's a foo: ${secondFoo.name}


Here's a foo: ${thirdFoo.name}


=

This works great.  No problems.

Clearly, though, this is *screaming* to be put into a loop.  So, let's try
this:

=== Test.tml (version 2) =
http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
   xmlns:p="tapestry:parameter">

Here's a foo: ${fooLoopVar.name}



==

Of course, this doesn't work.  (If it did work, I wouldn't be writing this
message right now.)  When I click the "edit" link to triggger the
"startDonkeyEdit" event, I get a null pointer exception.

There are two things preventing this from working:
First, Tapestry does not replay the loop when processing the eventlink (like
it did in the 3.x and 4.x days).  Therefore, "fooLoopVar" never gets changed
from its default of null.
Second, there's only one instance of  the ViewDonkeyInlineEdit component
inside the loop.  All of the eventlink URLs look identical, so there's no
way to tell which Donkey should be edited.

I tried using the "context" parameter of the eventlink component, but since
events start at the deepest level and bubble up, I got the null pointer
exception before I could use the context for anything useful at the outer
(page) level.

Next, I tried adding an activation context to the page.

In Test.java, I added:
String onPassivate() {
return fooLoopVar==null?null:fooLoopVar.getName();
}
public void onActivate(String fooName) {
for(Foo foo : list) {
if(foo.getName().equals(fooName)) {
this.fooLoopVar = foo;
}
}
}

This worked really well.  It appears that the page's onPassivate() method is
called for each generation of eventlink, yielding a different URL each time.
 I thought I had found my solution!  Of course, if that were true I wouldn't
be writing this email. Because I'll be using this inline-editing component
throughout the site, loops will often occur embedded inside a few layers of
components instead of at the page level.  If you convert Test.java to a
component and put it into a page, then the activation context won't work any
more.  Activation contexts are only for pages.  Now I'm back to square one.
 :-(

Basically, I need something th