When is the attribute's value of a Primefaces component updated? - jsf

I would like to understand when and how often an attribute's value is updated. I often see that component's attributes are updated even thought I didn't explicitly call an update on the component.
For example:
<p:panel id="panelA"
styleClass="#{controller.conditionA ? '.styleA' : 'styleB'}"
rendered="#{controller.conditionB() }">
</p:panel>
When the conditionB changes from true to false, the panels rendered attribute is updated as well without me calling an updated on the panel with panelA.
How are the both attributes styleClass and rendered evaluated and when?
Are all attributes, which have a non-static value, evaluated and updated periodically?
Instead of the panel, styleClass and rendered there could be other Primefaces components and attributes. I am interested in the general mechanism behind that.

Related

rowkey attribute in primefaces is not rendered, without selection or selectionMode attribute

I want use the rowkey attribute within a datatable primefaces (for use it in javascript script),
but I've noticed that is necessary set at least the selectionMode or selection attribute,
otherwise the rowkeyattribute (data-rk) is not rendered.
It 's true, or am I wrong?
I did some tests and it seems to be so.
Below an example from the showcase:
(rowkey attribute seems to be always used in combination with the selectionMode or selection attribute)
http://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml
I would need to take advantage of the rowkey attribute without using selectionMode or selection attribute;
you would know how to do?
Or, you know how to set a custom attribute for each row of datatable without using the component p:row;
The only thing that comes to mind is use the rowClass attribute to insert in, the value of a bean property,
as is the case here
http://www.primefaces.org/showcase/ui/data/datatable/rowColor.xhtml
But I wanted to associate the property of the bean to a specific attribute of row without creating a fake class CSS.
thanks in advance
I assume that you want to achieve the presence of 'data-rk' attribute on a <tr> without the rendering of the selection column.
I did some tests and if you put this styling on the then you will not have the selection column but still the 'data-k' attribute:
<p:column selectionMode="multiple" style="display: none;" />
You have to put this tag, but you do not need to place the selection attribute on the <p:dataTable>.
If this is what you are looking for, then this worked for me on Primefaces 6.0 and JSF 2.2

Missing parameter values in invoked method with composite components using ui:repeat

So after several days of debugging, we were eventually able to reproduce some strange interactions between composite components, ui:repeat, p:remoteCommand and partial state saving in JSF that we do not understand.
Scenario
A composite component iterates over a list of objects using ui:repeat. During each iteration, another composite component is included and arguments are passed.
<ui:composition (...)>
<ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam"/>
In the included composite component, there is an auto-run p:remoteCommand calling a method using parameters defined in the component's interface.
<ui:component (...)>
<p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
autoRun="true"
async="true"
global="false">
However, when setting a breakpoint in someMethod(...), an empty string is passed. This only happens if partial state saving is set to false.
Solutions
We tried several solutions and the following ones appear to work (however we do not understand why and cannot foresee any further problems that could occur):
We can set partial state saving to true.
We can change the composite component pattern to ui:include.
We can remove one or both of the composite components and directly include the content instead.
Question
Why does JSF behave this way? What is this interaction between composite component, ui:repeat and argument passing that changes depending on whether we use ui:include / partial state saving or not?
We're using Primefaces 5.3, Glassfish 4.1, Mojarra 2.2.12, Java 8.
Your code is all fine. It's just that Mojarra's <ui:repeat> is broken. You're not the first one facing a state management related problem with <ui:repeat>.
Checkbox inside ui:repeat not refreshed by Ajax
Dynamically added input field in ui:repeat is not processed during form submit
Components are with the same id inside ui:repeat
<h:form> within <ui:repeat> not entirely working, only the last <h:form> is processed
Composite component with custom backing component breaks strangely when nested inside ui:repeat
ui:repeat in o:tree not working as expected
Root cause of your problem is that #{cc} is nowhere available at the moment the <ui:repeat> needs to visit the tree. Effectively, the <ui:repeat value> is null. A quick work around is to explicitly push the #{cc} in UIRepeat#visitTree() method. Given Mojarra 2.2.12, add below lines right before line 734 with pushComponentToEL(facesContext, null).
UIComponent compositeParent = getCompositeComponentParent(this);
if (compositeParent != null) {
compositeParent.pushComponentToEL(facesContext, null);
}
And add below lines right after line 767 with popComponentFromEL(facesContext).
if (compositeParent != null) {
compositeParent.popComponentFromEL(facesContext);
}
If you don't build Mojarra from source, copy the entire source code of UIRepeat into your project, maintaining its package structure and apply above changes on it. Classes in /WEB-INF/classes have higher classloading precedence than those in /WEB-INF/lib and server's /lib. I have at least created issue 4162 to address this.
An alternative is to replace Mojarra by MyFaces, or to replace the <ui:repeat> by an UIData based component which got state management right such as <h:dataTable> or <p:dataList>.
<p:dataList type="none" var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam" />
</p:dataList>
You might only want to apply some CSS to get rid of widget style (border and such), but that's trivial.
See also:
Should PARTIAL_STATE_SAVING be set to false?

Action/ActionListener method checked even if rendered=false

I have a composite component representing a table, that depending on the editable attribute (which I have created) may or may not display links to edit a row.
The edit links are of type <h:commandLink> and have actionListeners pointing to a method in a backing bean. The backing bean for handling editing is provided as a <cc:attribute name="editBean"... /> like the attribute editable, when I want the table to be editable.
If I don't need the table to be editable I set the editable attribute to false and the links rendered attribute gets set to false as well.
My problem is that if I set editable to false and therefore don't set the attribute editBean either, I get errors pointing out that there is no method for handling editing (e.g. java.lang.String does not have the property xxxxx).
I had hoped that as the links are set to not be rendered at all, what has been specified in the action/actionListener would be ignored. To me it feels logical to first check the rendered attribute and then, if it's set to true, check the other attributes.
So, my questions are: why does it work like this and if there's an elegant way of handling this scenario?
Use JSTL <c:if> to conditionally build the component in JSF component tree instead of rendered attribute to conditionally render the HTML output (it's that you're using JSF 2.2, otherwise I'd have explicitly mentioned that this requires a minimum of Mojarra 2.1.18 to avoid broken view state).
<c:if test="#{cc.attrs.editable}">
<h:commandLink ... />
</c:if>

<h:selectBooleanCheckbox> doesn't work if put inside <ui;repeat>

There are couple of limitation(defect?) of jsf which causes this issue.
<ui:repeat value="#{myBean.myAttrs}" var="attr">
<h:outputText value="#{myBean.selectedObj.values[attr.name]}"
rendered="#{attr.dataType=='Text'}"/>
<h:selectBooleanCheckbox value="#{myBean.selectedObj.values[attr.name]}"
rendered="#{attr.dataType=='Boolean'}"/>
.... render other data type like list, date etc.
</ui:repeat>
First "render" property limitation in jsf, the component is still processed even render is false. This causes every attr type in ui:repeat will try to evaluate value for each output component. i.e. value of selectBooleanCheckbox will try to evaluate for date type. If render is false, the component won't be rendered eventually. Everything is fine even with this issue if without selectBooleanCheckbox(2nd issue).
Second issue, selectBooleanCheckbox will always assume the input value is Boolean type. So evaluate value (due to 1st issue) will fail for date type.
Is this code sniper common for display different data type dynamically in JSF? I tried to configure customization renderer, converter for the selectBooleanCheckbox. But it still fail with data type convert exception. Any idea? How to change the default "expectedType" for selectBooleanCheckBox from "Boolean" to "Object" just like other JSF input component.
--Update: the issue is only for mojarra instead of myfaces.

rendered attribute on inputText

I have a search form tied to a backing bean that contains 4 input text fields. The design i am working from indicates that the user should be able to see the search results, but they should not be editable. i decided to use the rendered attribute to show the inputs if the managed bean is empty, and to show an output text tag if it's not:
<t:inputText styleClass="inputText" id="name" rendered="#{not searchCriteria.fieldsEntered}"
value="#{searchCriteria.name}" autocomplete="off"></t:inputText>
<h:outputText value="#{searchCriteria.name}" rendered="#{searchCriteria.fieldsEntered}"></h:outputText>
The display part works correctly, but I am noticing that only the first field is stored in the managed bean when more than 1 search field is entered.
I removed a rendered attribute from an inputText, and sure enough that's causing my problems. I can infer what's going on here, but I don't understand why.
I believe in this situation I will just remove the outputText tags and change rendered to disabled. I am just curious why my initial plan is incorrect.
The rendered="false" will cause the input element not being rendered and thus its value will not be submitted to the server side. If you're using a request scoped bean, the initial value will not be set. You'd like to either put the bean in session scope or to add a h:inputHidden along the h:outputText which transfers the value to the subsequent request.
Since you're already using Tomahawk's t:inputText I'd suggest to rather use its displayValueOnly attribute instead of the rendered attribute and a complementary h:outputText.
In a nut:
<t:inputText displayValueOnly="#{searchCriteria.fieldsEntered}" ... />

Resources