SelectOneRadio inside subtable ajax call not working - ajax

I'm using primefaces 3.4.1 and I'm trying to use a SelectOneRadio with an ajax call inside a subtable
but it doesn't work, the ajax listener isn't called
<p:dataTable id="competenciesTable" var="competency" value="#{evaluationControl.currentEvaluation.evaluatedCompetencies}">
<f:facet name="header">
<h:outputText value="#{gchmsg['global.competencies']}" />
</f:facet>
<p:subTable id="descriptorsTable" var="descriptor" value="#{competency.evaluationDescriptors}">
<f:facet name="header">
<h:outputText class="strong" value="#{competency.competency.name}" />
</f:facet>
<p:column>#{descriptor.descriptor.description}</p:column>
<p:column>
<p:selectOneRadio required="true" styleClass="calification_scale" id="descriptorCalification" value="#{descriptor.calification}" converter="calification">
<f:selectItems value="#{competency.competency.calificationSchema.scales}" var="scale" itemLabel="#{scale.qualitativeValue}" itemDescription="#{scale.description}" itemValue="#{scale}" />
<p:ajax process="#this" listener="#{evaluationControl.handleRadioChange}" update=":evaluationForm:finalResultText, descriptorCalificationMsg" />
</p:selectOneRadio>
<p:message id="descriptorCalificationMsg" for="descriptorCalification" display="icon" />
</p:column>
</p:subTable>
</p:dataTable>
The evaluationControl is a SessionBean and the method is
public void handleRadioChange() {
log.debug("Listener called");
}
Help is appreciated.

After too many debugging and tests I finally found the issue, the primefaces Subtable component doesn't put back the values to the Backing Bean for itself you must process the whole DataTable component, so I had to remove the required="true"(to avoid validation errors) for each selectOneRadio and add the process="competenciesTable" to the p:ajax

You can try, deleting process="#this". It worked in my case. I'm not sure why it happens with p:subTable because I've never had this issue with p:dataTable.

Related

p:treeTable - p:ajax listener method not being called

Using p:treetable selectionMode="checkbox", I am trying to have a checkbox on the header so that selecting it would select all the checkboxes in all the rows of the treetable. All my attempts to invoke the p:ajax listener method processSelectAllRows have failed. I was able to get this done using p:datatable and need the same functionality using p:treetable. Any help will be greatly appreciated.
Below is the code:
<h:form id="searchFormId">
<p:panel id="searchPanelId">
<p:outputPanel id="ResultsPanelId">
<p:treeTable id="resultsTreeTableId" value="#{aBean.resultsRoot}"
scrollRows="20" scrollable="true" var="aNode"
selectionMode="checkbox" selection="#{aBean.selectedResultNodes}">
<p:ajax event="select" listener="#{aBean.onNodeSelect}"
update="resultsTreeTableId" />
<p:ajax event="unselect" listener="#{aBean.onNodeUnselect}"
update="resultsTreeTableId" />
<p:column>
<f:facet name="header">
<p:selectBooleanCheckbox id="allChkb" name="allChkb"
value="#{aBean.selectAll}">
<p:ajax listener="#{aBean.processSelectAllRows}"
process="#this" update="resultsTreeTableId" />
</p:selectBooleanCheckbox>
</f:facet>
<h:outputText value="#{aNode.name}" />
</p:column>
</p:treeTable>
</p:outputPanel>
</p:panel>
</h:form>
Here is the listener method
public void processSelectAllRows(AjaxBehaviorEvent event) {
System.out.println("Select all rows.");}
Environment:
1) Primefaces 3.5 (Won't be able to upgrade any time soon)
2) myfaces-bundle 2.1.15
3) Tomcat server
4) Java 1.7
Instead of AjaxBehaviorEvent you can use NodeSelectEvent.
NodeSelectEvent is a subclass of AjaxBehaviorEvent present in Primefaces 3.5 API. If you is using a not final primefaces version is better use Primefaces Objects instead of Faces Objects.
Hope I have help you! :)

Datatable not refreshing with ajax

I have two calendar controls and one command button. basically i want to give a range of date to pick the data from the database and then when i press the command button the datatable is displayed in the dialog box, the problem is java bean class is working it is loading the exact data which i want, but the datatable is not refreshing with command button click
my code is given;
<h:form id="form" >
<p:calendar value="#{calendarBean.dateFrom}" id="calFrom" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectFrom}" />
</p:calendar>
<p:calendar value="#{calendarBean.dateTo}" id="calTo" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectTo}" />
</p:calendar>
<p:commandButton value="Submit" action="#{calendarBean.submit()}" update="fTable" onclick="aDlg.show()">
<f:ajax render=":form:fTable" execute="#form"></f:ajax>
</p:commandButton>
<p:dialog id="aDialog" header="Filter List" widgetVar="aDlg"
modal="true" showEffect="explode"
hideEffect="explode" >
<p:panel id="pnl">
<p:dataTable id="fTable" value="#{calenderBean.list}" var="row" >
<p:column headerText="ID">
<h:outputText value="#{row.ID}"/>
</p:column>
<p:column headerText="Name">
<h:outputText value="#{row.Name}"/>
</p:column>
<p:column headerText="Time">
<h:outputText value="#{row.Time}"/>
</p:column>
<p:column headerText="User">
<h:outputText value="#{row.userName}"/>
</p:column>
</p:dataTable>
</p:panel>
</p:dialog>
</h:form>
kindly guide me regarding this issue
First thing to do, is remove the f:ajax, it's not working good with Primefaces. Also the update attribute should do everything.
This said, I have the very same code as yours which is working good.
If removing f:ajax is not working, try to check your managed bean scope (May be it's of request scope and data is re-initialized with every request)
Try Updating the dialog instead.
update="fTable"

How to realize rowToggle in primefaces 3.3?

I'm now using primefaces 3.3, but this version doesn't support event="rawToggle" for datatable. So I chose to use the onExpandStart instead of rowToggle, but I met with another problem. Here I want to put another datatable as the expanded row, so everytime I toggle one row in nodetable, I need to pass the nodeId of that row to backingbean to get all the contents of that node. If I have event="rowToggle", I can do it without any problem! But if I use the attribute onExpandStart of the dataTable, I cannot get the somenode.nodeId in the backingbean, anyone knows how to solve it?
I've also tried to put a hidden input tag <input type="hidden" name="hidden" value="#{somenode.nodeId}"/> inside the rowToggler, but the value I get in backingbean is null.
Have been worked on it for several days, but still no ideas. Help please please please!
<p:dataTable id="nodetable" value="#{nodeedit.list}" var="somenode"
styleClass="datatable" editable="true"
onExpandStart="#{nodeedit.toggle(somenode.nodeId)}" >
<p:ajax event="rowEdit" listener="#{nodeedit.save('node')}"/>
<p:column style="width:4%">
<p:rowToggler>
<h:form>
<input type="hidden" name="hidden" value="#{somenode.nodeId}"/>
</h:form>
</p:rowToggler>
</p:column>
<p:column>
<f:facet name="header">ID</f:facet>
<h:form>
<h:commandLink action="nodeedit">#{somenode.norder}</h:commandLink>
</h:form>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{somenode.title}" />
</f:facet>
<f:facet name="input">
<p:inputTextarea value="#{somenode.title}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="width:50px">
<p:rowEditor />
</p:column>
<p:rowExpansion>
<p:dataTable id="contentId" var="content"
value="#{nodeedit.contents}" id="contents" editable="true">
<p:ajax event="rowEdit" listener="#{nodeedit.save('content')}"/>
<p:column headerText="Text" style="width:450px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{content.text}" escape="false" />
</f:facet>
<f:facet name="input">
<p:inputTextarea value="#{content.text}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="width:50px">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
I have also tried another way. The Content of a Node is also an object, in the Node Class I have defined
List<LibContent> contents = new ArrayList<LibContent>();
so, like what siebzOr said, I wrote in my jsf something like:
<p:rowExpansion>
<p:dataTable var="content" value="#{somenode.content}">
**<p:ajax event="rowEdit" listener="#{nodeedit.save()}"/>**
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
and in backingbean nodeedit, I have
public void save() {
for (Content content : node.contents)
System.out.println("content.text");
}
I found that the content.text never changed no matter what I did in the page. But if I define List<Content> contents = new ArrayList<Content>() directly in nodeedit, it can get the new value!! That's why I tried to get the nodeId everytime I toggle the node-table and then update the contents in backingbean. Did I do something wrong with it?
p:rowExpansion is dynamic and loads it's data using AJAX. Something like this should work:
<h:form>
<p:dataTable value="#{nodeedit.list}" var="somenode" styleClass="datatable">
<p:column>
<p:rowToggler />
</p:column>
<!-- Your columns here -->
<p:rowExpansion>
<p:dataTable var="content" value="#{nodeedit.contentOf(somenode)}">
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
</h:form>
In your backing bean you should have a method to get the content of a node, in my example contentOf(Node node)
#Named // or #ManagedBean
#ViewScoped // or some other scope
public class Nodeedit
{
private List<Node> list;
//Getters and Setters
public List<SomeClass> contentOf(Node node)
{
// get and return the content of the node
}
}
If your Node has a method to get the Content you can do something like this in stead:
<p:rowExpansion>
<p:dataTable var="content" value="#{somenode.content}">
<p:column>
<h:outputText value="#{content.someValue}" />
</p:column>
<!-- Other columns -->
</p:dataTable>
</p:rowExpansion>
If a Node's content isn't a Collection of some sort I'm not sure it will work in a p:dataTable as the value.
I don't know what your classes look like so the above is just an idea.
Note also that I have put a h:form around the p:dataTable in stead of putting multiple forms in the p:dataTable itself. This is needed for multiple things like AJAX, selection, etc. You cannot nest forms.

Primefaces ajax update

I have primefaces datatable,
<p:panel id="resultpanel">
<p:dataTable id="tbl" var="job" value="#{report.jobModel}"
paginator="true" rows="#{report.jobModel.pageSize}"
paginatorPosition="bottom" lazy="true" scrollable="true"
resizableColumns="true" rendered="#{!empty report.jobModel}"
emptyMessage="#{messages['common.datatable.emptymessage']}">
<p:ajax event="filter" listener="#{report.jobModel.onFilter}"
update="#form" />
<p:column sortBy="#{job.detail4}" filterBy="#{job.detail4}">
<f:facet name="header">
<h:outputText value="#{messages['content.donejobs.ftdi.datatable.fixedfeecolumn.header']}" />
</f:facet>
<h:outputText value="#{job.detail4}">
<f:converter converterId="KurusLiraConverter"></f:converter>
</h:outputText>
</p:column>
<f:facet name="footer">
<h:outputFormat value="#{messages['content.donejobs.ftdi.datatable.footer']}">
<f:param value="#{report.jobModel.rowCount}" />
</h:outputFormat>
<p:panel layout="block" style="border: 0px; text-align: center;">
<p:commandLink ajax="false" title="Download Report">
<p:graphicImage value="/images/excel.png" />
<p:fileDownload value="#{report.excelFileOfReportTable}" />
</p:commandLink>
</p:panel>
</f:facet>
</p:dataTable>
</p:panel>
I want to update the footer part when I filter the table. I have tried to update the footer by putting all the things in the footer in a single panel, giving it an ID, inspecting this ID via firebug, and giving it as a value to the update attribute of the primefaces ajax component. I have also performed this approach, to html outputformat and param components. But no success, lastly I have tried to update the form, this time the whole table has been rendered like a text file. Is there a way to update the table size, after filtering? By the way, I am using primefaces 3.0.RC1-SNAPSHOT, and testing in firefox 7.0.1. Thank you very much for your interest and comment.
There is an open issue for that here and they provide a patch for the dataTable code. My workaround (aka huge hack) doesn't require touching the primefaces codebase, which I prefer. I tested it for the events below, but I can't see why it wouldn't work for the rowEdit event.
<p:remoteCommand name="updateFilters" update="table:totalid"></p:remoteCommand>
<p:dataTable id="tabelaMunicipio" value="#{bean.model}" ...>
<p:ajax event="page" oncomplete="updateFilters()"/>
<p:ajax event="filter" oncomplete="updateFilters()"/>
<p:ajax event="sort" oncomplete="updateFilters()"/>
<p:column headerText="#{msg['id']}" sortBy="#{id}">
<h:outputText value="#{item.id}"></h:outputText>
<f:facet name="footer">
<h:outputText value="#{bean.model.totals['id']}" id="totalid"/>
</f:facet>
</p:column>
...
</p:dataTable>
Yes, I use a p:remoteCommand (invoked by the oncomplete client-side hook in p:ajax) to update the components inside the footer row. This causes a tiny delay on the footer update in comparison to the data itself, but I can live with that.
3.0.RC1-SNAPSHOT is not an official release, and from what I can tell it could mean any number of nightly builds after M4 or between M3 and M4. You should upgrade (or downgrade?) to a stable release such as M3 or M4 and see if you get the same problems.
Also you could try update="#this", but I'm unsure what effect that would have that shouldn't already work with #form.

Is it possible to pass Calendar new date in the bean without listener?

I am trying to pass new date from PrimeFaces p:calendar (placed in p:dataTable column) to the backing bean:
<p:column >
<p:calendar value="#{bean.date}">`
<p:ajax />
</p:calendar>
</p:column>
It does not update bean.date. Variants with
<p:ajax update="#this" event="change"/>
<p:ajax update="#this" event="select"/>
do not update bean.date too. The only way I have found is using of listener. However, I suppose, there should be a way without listener implementation like for simple facelets:
<p:column>
<h:inputText value="#{bean.note}" >
<f:ajax/>
</h:inputText>
</p:column>
that works fine for me. Does anybody know how to get it working!?
<p:calendar value="#{Bean.value}">
<p:ajax update="display" event="dateSelect" listener="#{Bean.handleDateSelect}"/>
</p:calendar>
This should be helpful...but without listener means i dont think soo..you cant...
p:calendar it's a bit tricky for ajax; onSelectUpdate & selectListener are the key;
<p:column>
<h:inputText id="itDate" value="#{bean.note}" >
<f:ajax/>
</h:inputText>
</p:column>
and you must implement the handleDateSelect method in the Bean;
public void handleDateSelect(DateSelectEvent event) {
Date date = event.getDate();
setDate(date);
}

Resources