I was doing a custom component in JSF, and I kept getting an extra input field with the clientId as the id attribute, and I did not know why. I searched the web and did not find anybody who had ever encountered this. Since it always came last in the component I could not even figure out a way to hide the thing because any JavaScript I put in the component came prior to the existance of the field. I do not do anything in my encodeBegin() that asks for this.
Then I started wondering if extending the UIInput component required something that I was not doing; either that I figured or it was putting this darn extra field.
After studying other custom components' code, it finally occurred to me that if you extend a custom component (like UIInput) you have to be mindful of what methods that component implements, and what it does in those implemented methods. Then you have to decide if you still want that particular part of the component you are extending.
In my case, UIInput used encodeEnd() method to actually produce its field, so I just overrode encodeEnd() and made it do nothing. Then I started to wonder why I even was extending UIInput instead of UIComponent or something...
I guess that is another lesson...
This site promotes and supports the development and deployment of JSF, Oracle ADF applications, and other web development topics. If you have interesting facts to share about any of these or any related technologies, please feel free to post a comment.
Showing posts with label custom component. Show all posts
Showing posts with label custom component. Show all posts
Saturday, January 17, 2009
Thursday, January 1, 2009
Hah! I found it.
I am working my way through Schalk and Burns's JSF: The Complete Reference.
I skipped ahead to Chapter 10 because I promised my groupies (hah!) that I would put some juicy nuggets about custom JSF component definition in my paper for RMOUG (Rocky Mountain Oracle Users Group) in a month and a half.
So I had to study more about custom component definition.
As I worked through the chapters on that subject in this book, I got to one of the examples, and it just did not work. As I debugged the code, I saw that the component's property called listener (a MethodBinding) was being set in the component's Tag Handler class, in its setProperties() method.
Then, the component (on a different request) tried to do something with this listener value that was set...but lo! The value of this property was null.
That let me to ask a question that I have asked before, but had grown fuzzy on the answer. The question was...what scope are components at? Request? Session? Does scope even apply to this, since they are not managed beans?
The partial answer is that components by default span requests. But if you start adding extra properties to the component then you had better override a couple of properties, if your component or one of its ancestors implemented the StateHolder interface at some point. If you are extending UIInput for example, this already has implemented this.
So what are these properties you need to override? saveState() and restoreState(). In the following example, the "extra" property we are adding is called listener and is a MethodBinding object:
@Override
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
listener = (MethodBinding) values[1];
}
@Override
public Object saveState(FacesContext context) {
Object values[] = new Object[2];
values[0] = super.saveState(context);
values[1] = listener;
return (values);
}
After adding these methods, the books example worked fine.
The name of the example component was HtmlHelloInputMB if anybody else is working through that same book.
I have informed the primary author through the email given on the books website, which has all the sample code for the book by the way: http://www.jsfcompref.com/
I skipped ahead to Chapter 10 because I promised my groupies (hah!) that I would put some juicy nuggets about custom JSF component definition in my paper for RMOUG (Rocky Mountain Oracle Users Group) in a month and a half.
So I had to study more about custom component definition.
As I worked through the chapters on that subject in this book, I got to one of the examples, and it just did not work. As I debugged the code, I saw that the component's property called listener (a MethodBinding) was being set in the component's Tag Handler class, in its setProperties() method.
Then, the component (on a different request) tried to do something with this listener value that was set...but lo! The value of this property was null.
That let me to ask a question that I have asked before, but had grown fuzzy on the answer. The question was...what scope are components at? Request? Session? Does scope even apply to this, since they are not managed beans?
The partial answer is that components by default span requests. But if you start adding extra properties to the component then you had better override a couple of properties, if your component or one of its ancestors implemented the StateHolder interface at some point. If you are extending UIInput for example, this already has implemented this.
So what are these properties you need to override? saveState() and restoreState(). In the following example, the "extra" property we are adding is called listener and is a MethodBinding object:
@Override
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
listener = (MethodBinding) values[1];
}
@Override
public Object saveState(FacesContext context) {
Object values[] = new Object[2];
values[0] = super.saveState(context);
values[1] = listener;
return (values);
}
After adding these methods, the books example worked fine.
The name of the example component was HtmlHelloInputMB if anybody else is working through that same book.
I have informed the primary author through the email given on the books website, which has all the sample code for the book by the way: http://www.jsfcompref.com/
Labels:
custom component,
JSF,
restoreState,
saveState
Subscribe to:
Posts (Atom)