Primefaces selectors not updating a panelGroup - jsf-2

I am trying Primefaces selectors and it appears that it couldn't update an panelGroup.
<h:panelGroup layout="block" styleClass="updateMe">
<h:outputText value="#{bean.value}"/>
</h:panelGroup>
<h:form>
<h:inputText value="#{bean.value}"/>
<h:commandButton value="submit">
<p:ajax process="#form" update="#(.updateMe)" oncomplete="alert(1)"/>
</h:commandButton>
</h:form>
In this case the panelGroup never gets updated. But if I change the panelGroup to <p:outputPanel>, then it worked fine.
Observing the generated HTML, the only difference is that the <span> generated by panelGroup doesn't have an id while the one generated by outputPanel has an id. Could this be the reason why the first one is not getting updated (cos jQuery selector couldn't find the component id?)
If that is the case, is there any other component that does not have any ids and should be avoided when using Primefaces selectors?

When using Primefaces selector jQuery is used to select components on client side, and discover their client ids. When AJAX is sent one of parameters that is sent is javax.faces.partial.render whose value are client ids of components which should be updated. If component doesn't have client id it can't be updated directly, you can update parent component for example. Provide id attribute for panelGroup and try to update it with Primefaces selector.

Related

How to hide components by selecting a new value on h:selectOneMenu?

I have a page with a h:selectOneMenu, and I want to hide a dataTable when I choose a new value on the h:selectOneMenu while some bean attribute values update. I'm trying diferent things, and I'm able to hide the dataTable by reloading the page. I have tried this using some JavaScript code, on onsomething attributes. In that case, those bean attribute values disapear although I use t:saveState (and I also need the view scope for the bean).
Here is a little example to clarify this:
<h:selectOneMenu id="list" value="#{Bean.id}">
<f:selectItems value="#{Bean.List}" var="element" itemLabel="#{element.name}" itemValue="#{element.id}"/>
<t:saveState value="#{Bean.id}"/>
<f:ajax listener="#{Bean.populateBean}" render=":form:period" event="change"/>
</h:selectOneMenu>
<h:selectOneMenu id="period" value="#{Bean.period}">
<f:selectItems value="#{Bean.listaPeriod}" var="period" itemLabel="#{period[1]}" itemValue="#{period[0]}"/>
<t:saveState value="#{Bean.period}"/>
</h:selectOneMenu>
<h:commandButton id="search" action="#{Bean.doSearch}"></h:commandButton>
<t:dataTable id="data" value="#{Bean.configList}" rendered="#{Bean.search}"
<t:column>
...
</t:dataTable>
And Bean.doSearch changes Bean.search to true. How can I hide the dataTable when I choose a new value on h:selectOneMenu id="list"?
EDIT:
In short, the search button renders the table, and I would want to hide that table when I just choose a new value on the "list" dropdown without reloading the page. Now, the <f:ajax> is used only to rerender the "period" dropdown value.
Thanks in advance!
Your question is hardly understandable, but if you want to kick the datatable out of your view on ajax request triggered by your dropdown, you need to enclose it in a component that's always present in the view so that HSF would know what to rerender when ajax call successfully finishes:
<h:panelGroup id="rerender">
<t:dataTable rendered="#{bean.condition}" ...>
....
</t:dataTable>
<h:panelGroup>
Of course, to get it working you should specify id of the component to be rerendered:
<h:selectOneMenu ...>
...
<f:ajax listener="#{bean.populate}" render="rerender" />
</h:selectOneMenu>
Note that if both dropdown and datatable components belong to the same form, it's not necessary to specify absolute id of the latter's parent. Also note that specifying event is redundant, as it already defaults to the right one. Finally, as you're on JSF 2.x, using save state is not necessary, just bind the values of your form data to a view scoped bean.
The last thing to note is the fact that you fail to conform to the Java Naming Conventions, the thing you should correct as soon as possible.

Update sibling component in JSF 2 / Primefaces

I have the following component tree on my page
form
tabView
datatable
dialog
Now I want to update the dialog component when a row is selected in the datatable.
I tried something like:
<p:ajax event="rowSelect" update="#parent:detailsView" oncomplete="detailsViewDialog.show()" />
where detailsView is the id of a panelGroup within the p:dialog.
Only having update="#parent" works but is it not a solution to always reload the whole table only to display the dialog.
Can anybody give me a hint?
Regards,
Florian
The data table is by itself a NamingContainer component, so it's hard to use a relative client ID. You'd basically need to specify the absolute client ID:
<p:ajax ... update=":formId:tabViewId:detailsView" />
Alternatively, you could also bind the UIComponent with ID detailsView to the view by binding attribute and use UIComponent#getClientId() in the update attribute:
<p:ajax ... update=":#{detailsView.clientId}" />
...
<h:panelGroup id="detailsView" binding="#{detailsView}">

How to edit data in Primefaces DataTable without in-cell editing?

I have 2 pages.
Add Page for add a new item
List Page for show all items
When I click on Edit icon on List Page, I want to show selected data on Add Page for editing and update its data if I click on save button. How to do this?
Pass the row identifier as a parameter to the button. For example, assuming that #{item} is the currently iterated item and has some Long id property which uniquely identifies the item.
<p:button icon="ui-icon-pencil" outcome="edit.xhtml">
<f:param name="id" value="#{item.id}" />
</p:button>
In the target page, edit.xhtml, you can use <f:viewParam> to convert, validate and set it as a bean property.
<f:metadata>
<f:viewParam name="id" value="#{bean.item}" required="true" converter="itemConverter" />
</f:metadata>
...
<p:inputText value="#{bean.item.name}" />
<p:inputText value="#{bean.item.shortName}" />
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
Communication in JSF 2.0 - Processing GET request parameters

Understanding navigation in JSF

Trying to build a simple JSF application. One i don't get is, what mechanism is to use to trigger page reload. I have tried following
<h:selectOneMenu
id="ChallengesListBox"
onchange="submit()"
valueChangeListener="#{bean.projectselected}">
<f:selectItems value="#{bean.projectnames}"/>
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
with
public String submit() {
this.description.setRendered(true);
return null;
}
But this has no effect. The bean method
public String submit()
remains untouched, as I can see in debug mode.
This is not related to navigation. There are many causes why a bean action method is not invoked. You can find them all in this answer: commandButton/commandLink/ajax action/listener method not invoked or input value not updated
I suspest that you've either simply no <h:form>, or that you have multiple buttons in the form (the first one would then be invoked on submit()), or that the button is by itself not rendered during processing of the form submit.
Unrelated to the concrete problem, this JSF 1.x style approach is very clumsy. As you're apparently already on JSF 2.x, I suggest the following much simpler approach:
<h:selectOneMenu value="#{bean.projectname}">
<f:selectItems value="#{bean.projectnames}" />
<f:ajax render="somepanel" />
</h:selectOneMenu>
<h:panelGroup id="somepanel">
<h:outputText value="#{bean.description}" rendered="#{not empty bean.projectname}" />
</h:panelGroup>
(this will render the #{bean.description} value whenever the #{bean.projectname} is not null/empty according to the selection of the drop down list)
And make sure that you remove all binding attributes to the backing bean. Also make sure that the bean is #ViewScoped whenever you have input/button components inside the <h:panelGroup id="somepanel">.

JSF2 CommandButton Action request params

<h:commandButton value="Add Order" action="#{orderBasket.addItems(param['orderItemId'])}"/>
I can't get the above to work...when you click on the button the param seems to get set to null. Is there a way around this?
Is there another way of passing the URL params into the action method? I'm using Spring EL resolver which limits my ability to pass in the parameters into beans as I'm not using faces-config.
First, I think you could use JSF better, a lot of problems would be much simpler. It looks that you are using JSF as a request/response framework, like Struts. JSF is an object oriented component framework, you should use it this way to get the best of it.
I'll try to solve your problem, but I'm missing some information on what you are doing.
If you have a list of books that you can order, let's say they are displayed in a datatable (you could use ui:repeat instead) :
<h:dataTable value="#{bookController.books}" var="book">
<h:column>
<h:outputText value="#{book.title}" />
</h:column>
<h:column>
<h:commandButton value="Add Order" action="#{orderBasket.addItems(book)}" />
</h:column>
</h:dataTable>
In orderBasket backing bean, you simply take a Book (or whatever) as parameter. You don't need to handle the request/response cycle, certainly not in your views.
You can use f:ajax tag if you need to display that in your shopping cart immediately.
Let me know if you need more explanation (backing beans source or else).

Resources