How to extend functionality for JSF primefaces component? - jsf

I'm using Primefaces 4.0.
The datatable has an issue that after a table update the filter values are away. There is a new attribute in Primefaces p:column "filterValue". The attribute binds the value of a filter to a backing bean property. The problem is that the value of this attribute is only used for backing bean propertie getter. The setter method is not called.
I have made a patch for this component. In classes DataTabe and DataTableRenderer, the setter for the method checks in param's what is the client setting for filter and set the backing bean propertie. The changes is made in DataTableRender decode and FilterFeature decode methods.
Links to original classes on grepcode:
DataTable decode
FilterFeature decode
So the question: if you want to call setter for a component in which JSF-Phase or which method is suitable for this. Is decode-Method place where you can call setters ? What is standard approach in this situation ?

Related

Saving a Composite Component bean attribute in ViewScoped

I would like some technique/pattern advice on retaining each single bean I bind to my Composite Components.
I am adding composite components to a form pragmatically based on user actions, and when the user is finished I want to harvest the single bean behind each composite component they added. Ex: If user selects & adds 4 composite components, that's one bean for each, so when the user is finished I want the 4 beans with the user's entered values.
This seems a bit hairy in the JSF world, but I continue to dig through stackoverflow and experiment. I'm relatively new to JSF details, but having fun.
I've got the composite components loading, each being given a bean to be used as "cc.attrs.bean" and it properly adds the control to the form. Here is what I am currently doing and what I expected:
Load Composite Component
Instantiate its Bean
Save Bean reference in a separate list in a ViewScoped bean (my hook to the bean for later)
Give Bean to Composite Component (as an attribute)
Add Composite Component to form
...User interacts with form and Composite Components adding/editing values...
User finally pushes "Done" (now I need the modified beans).
Thought I could get all the user's values from the "separate list in a ViewScoped bean" from #3 above.
My preliminary experiments tell me that if I instantiate the bean, save the bean reference in a separate ViewScoped list then give the bean to the Composite Component, the bean I saved won't have the Composite Component's values. Between all the build/render phases it seems to lose the connection between the bean I saved and the bean the Composite Component is bound to.
I don't know if I should be following this path, or if I should use a FacesComponent event technique to intercept the bean attribute being passed along, or if I should be using filters, or maybe even magical pixie dust etc...
This seemed promising: I already wrap each of my user selectable Composite Components in a single common Wrapper Composite Component (lets me put a nice PrimeFaces collapsible panel frame around them). For example, I put "Composite Component A" into "Wrapper", then I add "Wrapper" to the form. If I passed the single bean as an attribute to both those Composite Components, I was hoping that the FacesComponent event "init" technique on the Wrapper could nicely capture the "real bound bean" in my separate list in the ViewScoped bean. In my attempts on this today I'm having trouble finding the right event type and getting access to the bean... and getting lots of strange errors (probably due to my lack of detailed understanding of the lifecycle).
Stack: Eclipse Mars, JSF 2.2, Mojarra 2.2, Tomcat 8.0

Manipulating a disabled attribute in client side; does JSF test properly if component is disabled?

Primefaces 3.5.10, Mojarra 2.1.21, Omnifaces 1.5
I am thinking about security issues.
I set the component attribute with the component.getAttributes() method. This method returns a HashMap with attributes. Is it safe to set the ("disabled", true)-pair in this map to disable the component (for example p:inputText-component)? I use it from an actionListener, (Phase 5 or 4) of jsf pipeline. So possibly it has implications for render phase only. But I could manipulate the disabled attribute from input method on the client and then post the manipulated values. Does the server make test if the component is disabled and rejects the changes ?
What is the best way to go ?
all components in panelGrid will be disabled:
xhtml:
<p:panelGrid>
<my:component/>
<p:input value=#{mybean.value} />
</p:panelGrid>
Bean:
for (UIComponent component : l) {
component.getAttributes().put("disabled", true);
recursion(....);
}
But I could manipulate the disabled attribute from input method on the client and then post the manipulated values.
Yes, the enduser could.
Does the server make test if the component is disabled and rejects the changes ?
Yes, JSF does it based on component tree state, not on the submitted value. So that part is safe. It does that by the way also for readonly and rendered attribtues.
See also:
Why JSF saves the state of UI components on server?
Which properties in a JSF backing bean can be set by a user?
commandButton/commandLink/ajax action/listener method not invoked or input value not updated (point 5)

What to do with the inner converter of view scoped backing bean

Yet another problem among others with view scoped backing beans in JSF. I created an inner class in my view scoped backing bean. That inner class is converter. I need the inner class because I have to access some fields from my backing bean (list of select-one items in this case). Suddenly I figure out that my backing bean's #PostConstruct method is called after every request. After some inspection I realized that converter attribute is the problem and after some google search a find on (as always) BalusC's blog reason for this.
So, my question is how to make my converter to work fine, and also have my list of data which is necessary for conversion?
Decouple the converter into a stand alone class and use Application#evaluateExpressionGet() to access the view scoped bean instance inside the converter method.
ViewBean viewBean = context.getApplication().evaluateExpressionGet(context, "#{viewBean}", ViewBean.class);
This is however a bit nasty design. If I understand your concrete functional requirement of converting the selected item based on the list of available items right, an alternative is to use a generic converter which converts based on the physical <f:selectItem>/<f:selectItems> components. The JSF utility library OmniFaces has two converters for exactly this purpose, the SelectItemsConverter and SelectItemsIndexConverter.

bean and jsf validation annotation inisde managed bean vs entity bean

I'm new in JSF and not sure about a few fundamental issues.
I found i few ways for defining validation for my input fields, but i'm not sure which is the right way to do it.
I'm using bean validation and jsf validation by using ExtVal.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
This question leads me to a more basic one , that I still don't really understand -
I have an entity bean with fields and their setters and getters, also I have a managed bean and a xhtml file with a form that displays the fileds inside inputs.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ?
again what is the diffrence for each approch?
Thank's In Advance.
should I use the validation annotation like #Size , #Length inside my entity bean, or should it be inside the managed bean? what is the diffrence for each option?
Depends on the concrete functional requirement. Key point is: how reuseable should the validation be? If configured at entity level, it's reuseable for all frameworks other than JSF. If configured at JSF level, it's not reuseable for frameworks other than JSF which happen to use the same entity.
should I define the same fields with their getters and setters inside the managed bean? and when approaching them from the xhtml file I do it by MBname.FiledName ? or is it better not to create the fields again in the managed bean and approch them from the xhtml by calling MBname.details.FiledName (when details return the object) ? again what is the diffrence for each approch?
You should not duplicate/expand the data model in the controller. This makes no sense. This is not DRY and is thus only maintenance headache.

JSF Required=Yes not working inside a datatable?

I searched everywhere but could not find a solution to this. I am trying to used
required=yes to validate whether a value is present or not. I am using it inside inputtext.
The problem is it does not work inside a datatable. If I put the text box outside the datatable it works. I am using JSF 1.7 so I don't have the validateRequired tag from JSF 2.0.
I even used a validator class but it is still not working. Does anyone know why does required=yes or validator='validationClass' inside a inputtext inside a datatable is not working.
I appreciate the help.
Thanks.
First of all, the proper attribute values of the required attribute are the boolean values true or false, not a string value of Yes. It's an attribute which accepts a boolean expression.
The following are proper usage examples:
<h:inputText required="true" />
<h:inputText required="#{bean.booleanValue}" />
<h:inputText required="#{bean.stringValue == 'Yes'}" />
As to the problem that it doesn't work inside a <h:dataTable>, that can happen when the datamodel is not been preserved properly (the datamodel is whatever the table retrieves in its value attribute). That can in turn happen when the managed bean is request scoped and doesn't prepare the datamodel during its (post)construction which causes that the datamodel is null or empty while JSF is about to gather, convert and validate the submitted values.
You need to ensure that the datamodel is exactly the same during the apply request values phase of the form submit request as it was during the render response phase of the initial request to display the form with the table. An easy quick test is to put the bean in the session scope. If that fixes the problem, then you definitely need to rewrite the datamodel preserving logic. You could also use Tomahawk's <t:saveState> or <t:dataTable preserveDataModel="true"> to store the datamodel in the view scope (like as JSF2's new view scope is doing).
Finally, JSF 1.7 doesn't exist. Perhaps you mean JSF 1.2?

Resources