How to use PrimeFaces p:droppable inside datatable? - ajax

There is business need to categorize items. Best idea seems to be dragdrop items from one list into list of categories. Number of categories can vary so p:dataTable is used.
Ajax request is sent but onDrop method is not called from inside dataTable. When Removing datatable and column and having outputpanels statically then onDrop is called?
How to best drag and drop items into dynamically changing categories?
<h:form prependId="false">
<h:panelGrid columns="2">
<p:dataTable id="itemstable" value="#{categoryBean.items}" var="item">
<p:column>
<p:outputPanel id="itemrow">
<h:outputText value="#{item}"></h:outputText>
</p:outputPanel>
<p:draggable for="itemrow"></p:draggable>
</p:column>
</p:dataTable>
<p:dataTable value="#{categoryBean.categories}" var="cat">
<p:column>
<p:outputPanel id="cats1">
<h:outputText value="category1"></h:outputText>
</p:outputPanel>
<p:droppable for="cats1"
dropListener="#{categoryBean.onDrop}"
tolerance="pointer"
activeStyleClass="slotActive"
datasource="itemstable">
</p:droppable>
</p:column>
</p:dataTable>
</h:panelGrid>
</h:form>

There is a bug in PrimeFaces, when <p:droppable> is nested in any data repeating element the dropListener does not get called. I also tried using the Facelets repeat tag <ui:repeat> but the dropListener was not called just like dragging to the <p:dataTable> .
In the PrimeFaces showcase all of the drag an drop examples have static droppable areas.
PrimeFaces ShowCase

Related

Getting Primefaces datatable row variable via non-ajax button post request

I have a datatable and polling in my Primefaces page. On Datatable on every row there is a commanButton. Because of polling, f:setPropertyActionListener does not works properly on button click. So I set ajax=false at button and trying to get datatable row "var" via a POST request. Is there a way to do that?
<p:poll interval="15"
listener="#{batchOperation.generateImportFTDBatchFileReport}"
update=":batchOperationsForm:growl :batchOperationsForm:batchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDerrorbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDStatusTxtId"
widgetVar="myPoll" autoStart="true"/>
<p:dataTable id="batchfilestbl" var="batchFile"
value="#{batchOperation.batchFileModel}" paginator="true"
rows="#{batchOperation.batchFileModel.pageSize}"
paginatorPosition="bottom"
sortBy="#{batchOperation.createTime}"
sortOrder="descending"
emptyMessage="#{messages['common.datatable.emptymessage']}"
selectionMode="single"
selection="#{batchOperation.selectedFile}">
<p:column headerText="#{messages['content.batchoperations.datatable.header']}">
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:setPropertyActionListener value="#{batchFile}"
target="#{batchOperation.selectedFile}" />
</p:commandButton>
</p:column>
</p:dataTable>
If you want to send the whole model object as a parameter to a backing bean method, you can send it in using your var for the data table.
<p:dataTable var="myVar">
<p:column>
<p:commandButton actionListener="#{bean.method(myVar)}" />
</p:column>
</p:dataTable>
Alternatively, if you are only interested in the row index, you can send just that using the rowIndexVar value for the data table.
<p:dataTable rowIndexVar="rowIndex">
<p:column>
<p:commandButton actionListener="#{bean.method(rowIndex)}" />
</p:column>
</p:dataTable>
It looks like you are trying to do file download here. You may want to checkout this question.
Instead of using f:setPropertyActionListener, f:attribute solved my problem.
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:attribute name="bf" value="#{batchFile}" />
</p:commandButton>
Method:
public synchronized void createBatchFileForDownloadLatestRevision(ActionEvent event) throws Exception {
selectedFile = (BatchFile) ((CommandButton) event.getSource()).getAttributes().get("bf");
.
.
}

displaying the value of the p:dataTable cell on click event of the p:panelGrid using p:ajax

I have p:dataTable, inside column I have a panelGrid where i want the value of the ouputText on the click of the panelGrid without page refresh. The code is something like:
<p:column headerText="5/5" style="width:40px; font-size:9pt;">
<p:panelGrid>
<p:ajax event="click" listener="#{myBean.showSelectedValue(row)}" update=":mainForm"/>
<h:outputText value="#{row.value1}" />
</p:panelGrid>
</p:column>
</p:dataTable>
<h:panelGrid id="ForecastChartTab">
<h:outputText id="value1" value="#{myBean.showValue.value1}" />
</h:panelGrid>
This is working, but the value is seen only on page refresh...! is something wrong here? :(
If you need to update the table, you can use the following
update="#([id$=dtTableId])"
If you need to update the output text you need use the following
update="#([id$= value1])"
With this type of format #([id$= value1]), you can update another component out of the behavior of others.

<p:ajax update=""> inside nested components

Iam using Mojarra 2.2.11 (WildFly 9.0.1) with PF 5.3.
In relation with my original question:
<p:ajax update="...> cell or row update inside PF subTable
I am still struggling with the following line: <p:ajax update=":tabView1:form1:mainTable".../>
The following part has been changed: #{subTableView.getAllheaders(tabview)}. Below references have been used but the datatable refresh does not seem to work.
I have done several researches and tried multiple options without success.
The operation looks easy: I need to process a selectOneRadio value to update the outputLabel in the next column of the datatable. I am not getting any error: but the radio selection comes back to the initial position when another radio is clicked without updating the outputlabel.
I paid attention that outputLabel is surrounded by a panelGroup (see reference). NamingContainer with proper syntax has been tried:
BalusC ref: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
I tried with RequestContext#update("tabView1:form1:mainTable:panel") with the below references:
Primefaces p:ajax listener conditional update
PF Showcase
<f:ajax execute="" render=""/> has been tried
Reference: Mastering JSF 2.2 Book
I was thinking about the last jQuery option but I still think it is doable with JSF.
Thank you for your time.
<p:tabView id ="tabView1" value="#{bean.titles}" var="tabItem" >
<p:tab id="tab1" title="#{tabItem}" >
<h:form id="form1" >
<p:dataTable id="mainTable" value="#{subTableView.getAllHeaders(tabItem)}" var="head" >
<p:subTable id="subTable1" value="#{head.questions}" var="question" >
<f:facet name="header">
#{head.name}
</f:facet>
<p:column id="questionColumn">
#{question.question}
</p:column>
<p:column id="radioColumn">
<p:selectOneRadio id="mainSelect" value="#{question.select1}" >
<f:selectItem itemLabel="Yes" itemValue="#{question.responseOfYes}" />
<f:selectItem itemLabel="No" itemValue="#{question.responseOfNo}" />
// here is my pain:
<p:ajax update=":tabView1:form1:mainTable" process="#this"
listener="#{subTableView.updateSecond(question.select1)}"/>
</p:selectOneRadio>
</p:column>
<p:column id="responseColumn">
<h:panelGroup id="panel" >
<h:outputLabel id="display1" value="#{question.select1}" />
</h:panelGroup>
</p:column>
</p:subTable>
</p:dataTable>
</h:form>
</p:tab>
</p:tabView>

p:inputText in p:dataTable not setting the value in the bean

I'm trying to implement a dataTable which contains (among other things) a column with a textInput so I can modify a string value in the bean. My problem is that the bean does not update correctly, so this is part of my code:
<p:scrollPanel style="height:625px" mode="native">
<p:dataTable value="#{oaBean.documentos}" var="documento"
rowIndexVar="rowIndexVar" rowKeyVar="documentoKey" id="documentoList"
widgetVar="myTableWidget" paginator="true" rows="50"
emptyMessage="#{messages['norecords']}">
<f:facet name="header">
<h:outputText value="#{messages['documents']}" />
</f:facet>
<p:column style="width:1px;margin:0;padding:0;" headerText="#">
<h:outputText value="#{rowIndexVar+1}"
style="font-size:0.75em;margin:0;padding:0;" />
</p:column>
//lots of another columns
<p:column headerText="#{messages['documento.orden']}"
style="width:25px; text-align: center" id="columnOrden" widgetVar="columnOrden">
<p:inputText id="ordenDocumento" value="#{documento.orden}"
disabled="#{documento.eliminado}" style="font-size:0.9em" size="2"
validator="floatValidator">
</p:inputText>
</p:column>
</p:dataTable>
</p:scrollPanel>
The thing is that when the control returns to the bean the value of orden is not updated, I always have the old value. I've also tried adding an ajax listener for the change event and it seems to work fine, but if I change for example, 5 rows, at least one of them maintains the old value, so my question is: is there any known problem with dataTables and textInputs? Is something wrong with my code?
Any help will be really appreciated, thanks in advance guys.
UPDATE
Sorry, I've forgot to include some information. First of all, I'm working with Mojarra 2.1.5, PrimeFaces 3.4.2 and Facelets and running in Tomcat 7. Second, and probably the most important, the code presented above is included through a tab into a larger xhtml:
<ui:define name="body">
<rich:panel styleClass="createFormPanel">
<h:panelGroup layout="block" style="margin:0 auto;width:100%;" id="principalPanel">
<div style="height: 665px"><p:tabView id="tabs" widgetVar="tabsView" activeIndex="#{oaBean.activeTab}">
<p:tab id="tab5" title="#{messages['oa.tab.contenido']}">
<h:form id="formTab2">
<ui:include src="/pages/oa/tabContenido.xhtml" />
</h:form>
</p:tab>
</p:tabView></div>
</h:panelGroup>
</rich:panel>
</ui:define>
In this case, tabContenido.xhtml is the page containing the data table definition. Didn't include the java code because is just a bean with getter and setter values. If you need more information just let me know.
Regards.
Try adding an ajax event to the column and updating the hole table, something like this:
<p:column headerText="#{messages['documento.orden']}"
style="width:25px; text-align: center" id="columnOrden">
<p:inputText id="ordenDocumento" value="#{documento.orden}"
disabled="#{documento.eliminado}" style="font-size:0.9em" size="2"
validator="floatValidator">
<p:ajax event="change" update="documentoList" />
</p:inputText>
</p:column>

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.

Resources