• Post Reply Bookmark Topic Watch Topic
  • New Topic

When to use JSF 2 Renderer for custom component  RSS feed

 
john lazeraski
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

Still learning custom components, trying to build my dynamically adding email panel, where clicking a + sign adds a new input field without refreshing the entire page, and pressing - removes one, and submitting the form properly stores all the emails entered into the dynamic fields.

So, I am reading from Core JSF 3rd edition, chapter 11 custom components. Also some stuff online. From what I read I thought I just declare a FacesComponent and provide the encodeBegin, encodeEnd and decode methods in this one class, to handle adding/rendering the dynamic email components, as well as (in decode) when the form is submitted reading the request parameters and populating the POJO email object. But, looking at their example of TabbedPane, it renders children (tabs) and uses a Renderer implementation. So I am trying to make sense of it all. If a @FacesComponent can override the encode/decode methods, why would I need a separate renderer class with those methods and the component class is pretty much empty?

I am attempting to do this the right way, but perhaps there is more than one way this can be done correctly?

Also, since my component basically needs to be wrapped in a container, does it make sense to extend UIPanel as opposed to UIINput?

Thanks.
 
Tim Holloway
Bartender
Posts: 18662
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, you are doing it very much the hard way.

If you are going to implement custom components, always try to use the Facelets (XML) component architecture. The JSF native component architecture is much more complicated and more likely to break when future releases of JSF come out.

Although actual practice on JSF is almost always rendered as HTML4, JSF was architected to specifically decouple the JSF bean data logic (Model) from the JSF rendering logic (Controller-to-View). You can thus plugin alternative renderers and if you have been well-behaved (for example, didn't embed raw HTML in the View Template, allowed for flexible display layout), the application could switch from, say, HTML to WAP without recoding. Of course, WAP is not too common anymore, since modern mobile devices are generally full-HTML, but this also allows for things like PDF output.

Anyway, back to hard way and easy way.

The hard way is to design, debug, and use a custom component. The easy way is to leverage MVC. I've got tons of apps that behave basically like what you've described, but I use a dataTable. The "+" button invokes a Model-side AJAX listener that adds a new blank row to the table's DataModel object and re-renders the table. Presto! a new row appears. All basically done in POJO, with no esoteric and tempermental JSF internal meddling.
 
john lazeraski
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

I was sort of going on what you said in my previous thread, regarding the one scenario when I should make a custom component. I thought from what you said, in my case where I needed to add a bunch of components with each + click that it would fit the role of a custom component, and not using the composite component path. Maybe I misunderstood, but I thought what I was trying to do was too complex for a composite component.

At any rate, I'll try that again with composite, but to answer my question, if you know, is there any specific reason to use a Renderer like the Core JSF book is showing, or maybe that book is just showing how to do it, but that is more for cases where you will need different renderer's? From what you are saying, it sounds like the book is just showing how to do it, but in most custom component cases that are strictly HTML, it's fine to use the @FacesComponent class and the encodeAll() method to render the html response?

One thing about composite components I am not quite clear on yet... in my case I have a user object with a collection of emails, but I also have another page where it's used that has a different object and thus a different backing bean, that also has a collection of emails. How do I tell the composite component to use a specific beans collection of emails to show and/or add to/delete from? I am sure this must have something to do with the cc. use and defined in the interface to allow for EL to be passed to the component.
 
Tim Holloway
Bartender
Posts: 18662
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can do all sorts of complex things with a composite component. In fact, the Windows ComboBox controls is a complex composite component, marrying an Input control and dropdown list control. The reason for doing a binary tag isn't complexity, it's that you need resources that the core tags can't be wired together to do. Such as a Google Maps control. Which is something I've actually implemented as a binary tag. Just about the only thing I've implemented as a custom binary tag, in fact!

Definitely don't take shortcuts and cram rendering into non-render parts of a tag implementation. If for no other reason than that at some point you might need 2 different behaviors, such as a legacy rendering for HTML 4 and an advanced rendering for HTML5. Even though it's extra work and you might NEVER need it, at least your tag wouldn't drive someone else crazy trying to make sense of it if it at least follows the documented design standards. Well, OK, at least it's less likely to drive them insane. And while insane code may be job security, it's also a millstone you may end up saddled with when you'd rather be doing something more fun.

You do not have to have a separate backing bean for each View. Nor is a View limited to only reference one backing bean. I'm not really clear on your exact requirements, but it sounds possible that what you really need is a third bean for your email collection itself and inject that bean into the 2 page UI Model backing beans.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!