use of cellEditor in facet not working primefaces - jsf

In a project, I have to merge two datatables (the first to set the header of the second and the second displaying the informations contained in an uploaded file) into one to simplify the legibility on the page.
Since the first datatable was using a cellEditor I tried using one in the merged one the following way for the header:
<f:facet name="header">
<p:cellEditor>
<f:facet name="output">
<h:outputLabel id="output" value="some text" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{handler.selectItems}">
<!-- List of selectItems -->
<p:ajax event="change" update="output" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</f:facet>
But when I build the project and click on the header of my columns, I don't have any list of selectItems appearing to give me the possibility to change the header. It was used in <p:column> before without problem so I imagine the <f:facet> is the problem
I succesfully made the possibility to change the value of the header using <p:inplace> instead, but it doesn't behave exactly like I want.
I want that even if I don't modify the value when I click on the header (and make the list appears), I can click somewhere on the page and make the list disappear to have a "clean" header. I don't really want to use the editor="true" option of inplace because the goal is also to try to reduce the number of click needed for the user. I also made it a bit using <p:ajax event="blur" update="output" /> but some value of the list of selectItems make one or two inputText appear. And with that event, when I click in the text box, it closes the field automatically and I can only the value of the field once. After, the moment I click on the list to open it, it closes the field.
How can I fix that ?

Related

PrimeFaces 12.0.0 DataTable disabledSelection behaviour

Am i missing something or PF 12.0.0 DataTable selection is not working as expected when using disabledSelection?
client-side does not have any CSS class to differentiate between selectable an non-selectable rows
select all checkbox in column header (<p:column selectionMode="multiple">) selects all rows (not just selectable ?!) - by this i mean, browser is sending form parameter myForm:myTable_selection:#all and then server sets every list item from value to selection - at the same time, only selecteble rows are checked on client side
If selectionMode=multiple is present in p:dataTable then it's not working at all (by 'not working at all' i mean client-side checkboxes are all disabled without console error logs)? Only if selectionMode is omitted it's working but still, because of 2) i need to filter out rows on server side manually
I'm using something like this (without Ajax events for row select)
<h:form id="tblForm">
<p:dataTable id="myTable" widgetVar="myTableWv" value="#{myBean.list}" var="item" size="small"
sortBy="#{myBean.defaultSort}" filterBy="#{myBean.defaultFilter}"
selection="#{myBean.listOfSelected}" selectionPageOnly="false"
rowKey="#{item.id}" disabledSelection="#{myBean.shouldDisable(item)}">
<p:column selectionMode="multiple" />
<p:column>
<f:facet name="header">
<p:commandButton process="#this myTable" action="#{myBean.doSomethingWithSelectedItems}" />
</f:facet>
</p:column>
</p:dataTable>
</h:form>
Edit: 12.0.2 release notes are saying 1) is solved
Edit2: It's not working only when selectionPageOnly=false is used
OK turns out it was a similar issue to previously reported. The issue was not checking if the selection was also disabled!
Fixed here for 13.0: https://github.com/primefaces/primefaces/pull/9553

Create dropdown menu in h:dataTable for one specific row

I have a form that has a few fields that take input from the user. That input is then used to generate a dataTable that is being populated via Hibernate with info from the database, according to the options/fields selected by the user in the initial form.
I need to somehow generate a dropdown menu for a specific record that is being clicked on, and then download that record in a specific file format (I already kind of have a similar method for doing this made by someone else).
Here's how my dataTable looks like:
<h:form id="form2">
<t:dataTable binding="#{table}" rendered="#{searchArhivaUIBean.renderTable}" value="#{searchArhivaUIBean.nonEdiAbstractList}"
var="dataItem" border="0" cellspacing="2" width="100%" id="tdtbl"
headerClass="tableHeader" rowClasses="rowOdd,rowEven" columnClasses="Column">
<t:column>
<!-- display currently selected row number -->
<f:facet name="header">
<t:outputText value="Nr"/>
</f:facet>
<t:outputText value="#{table.rowIndex + 1}"/>
</t:column>
<t:column>
<f:facet name="header">
<t:outputText value="Data Mesaj"/>
</f:facet>
<t:outputText value="#{dataItem.dataMesaj}">
<f:convertDateTime timeZone="#{tzUIBean.tz}" pattern="dd.MM.yyyy" />
</t:outputText>
</t:column>
<t:column>
<f:facet name="header">
<t:outputText value="Numar Mesaj"/>
</f:facet>
<t:outputText value="#{dataItem.numarMesaj}"/>
</t:column>
<t:column>
<f:facet name="header">
<t:outputText value="Societate Sender"/>
</f:facet>
<t:outputText value="#{dataItem.societateSender}"/>
</t:column>
<t:column>
<f:facet name="header">
<t:outputText value="Societate Receiver"/>
</f:facet>
<t:outputText value="#{dataItem.societateReceiver}"/>
</t:column>
</t:dataTable>
</h:form>
This will generate a dataTable, populated with items. Any ideas on how can I make now a dropdown appear as I click a message (either the "Nr" column (the first column in the dataTable)) or the "Numar Mesaj" column? I need the dropdown to appear underneath that specific row in the dataTable, so I can choose the file format from that dropdown and download that specific record as a .pdf, .xls or whatever else type of file.
At least, this is how I thought it to work. Any ideas are appreciated.
Well, it would much easier to do with proper JSF framework like for instance Prime Faces. They have dedicated components for that kind of stuff.
With default JSF it will be a chunk of job. I can imagine something like that:
First you need to make one of your columns clickable with for instance h:commandLink. This (click) action may change special flag(s) which will be used to show an extra row with formats.
Next step is making extra rows for each data row where second row is hidden (by above flags). Clicking the link in your column will show that extra row with formats.
It seems the only difficulty is to show just 1 row, not all of them so the event and flags need to quite clever. You have to track the current row selection and use it when showing an extra row.

selection issue p:dataTable with selectionmode set to multiple nested in p:dataGrid

I'm working on a PrimeFaces project, where I choose to use a p:DataTable inside a p:DataGrid. The DataTable has the selectionMode attribute set to "multiple". I have a button on the page and when I click on it, I want to get all the selected checkboxes inside the various generated tables. All the checkboxes bring the same type of information (they are in different tables because of an information grouping scheme I use in the project).
Since I have multiple DataTables in the final rendered page, how can I get the selected checkboxes? I tried using the selection="#{myBean.selectedOptions}" attribute of the DataTable, but it seems to get just one of the generated tables' selected options (aparently the first one). What can I do to get the selected options of all tables generated by the p:DataGrid? Javascript? Is there any point I'm missing in the DataTable behavior?
(Well.. I don`t know whether I was able to make myself clear enough - English is not my native language).
[edited]
More information:
The number o DataTables generated is variable
I tried using the jsf visit method to traverse the user interface component view as shown here, looking for all checkboxes inside the DataGrid, but it couldn't find any of the checkboxes (I printed out to the console all the elements found). I think it's because the checkboxes are encapsulated in DataTable component. This made me think about not using the selectionMode="multiple" and, instead, manually add the checkboxes and a hidden input element for each one so I can find the checkboxes (or the "input hidden") using the visit method. The sad part of this aproach is that I'd have to stop using some good stuff of the DataTable selectionMode="multiple" feature, like hilighting the row if the corresponding checkbox is checked, and the ready to use "check all" checkbox it automatically put in the header of the ckeckboxes column.
I tried using a nested List in the selection attribute, but it didn't work. The main idea was using something like selection="#{bean.myListOfLists.get(t.counter)}". The "counter" variable is taken from the very object that is used to fulfill the current row of the DataTable (represented by the t variable in the attribute var="t"). The DataTable seems to not accept this approach. It doesn`t fulfill the nested lists.
I tried using the above approch with a modification: instead of a list of lists, a build a new class "B" and made a list of B (selection="#{bean.myListOf_B_Objects.get(t.counter).listInsideBObject}"). The result is simliar to the last approach: none of the lists inside the B objects were fulfilled.
Below there is a simplified view of what I did (more similar to the last case, but it's just to get the big picture)
<p:dataGrid var="gridCellContent"
value="#{myBean.dataGridContent}"
layout="grid" id="id01" columns="3"">
<p:dataTable var="something"
value="#{gridCellContent.listOfSomething}"
rowKey="#{something.id}"
selection="#{myBean.listOf_B_Objects.get(gridCellContent.counter).listInside_B_Object}">
<p:column selectionMode="multiple" />
<p:column>
<h:outputText value="#{something.sometext}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton id="btnSave" value="Save"
actionListener="#{myBean.btnSave}"/>
</f:facet>
</p:dataGrid>
[edited 2] Following #JaqenH'ghar's sugestion I tried out the modifications below, which unfortunately still din't work:
<p:dataGrid var="gridCellContent"
value="#{myBean.dataGridContent}"
layout="grid" id="id01" columns="3"
rowIndexVar="count">
<p:dataTable var="something"
value="#{gridCellContent.listOfSomething}"
rowKey="#{something.id}"
selection="#{myBean.listOfLists.get(count)}">
<p:column selectionMode="multiple" />
<p:column>
<h:outputText value="#{something.sometext}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton id="btnSave" value="Save"
actionListener="#{myBean.btnSave}"/>
</f:facet>
</p:dataGrid>
And for myBean:
#ManagedBean
public class MyBean {
...
private List<List<Something>> listOfLists = new ArrayList<List<Something>>();
public List<List<Something>> getListOfLists(){
this.listOfLists.add(new ArrayList<Something>());
return this.listOfLists;
}
public void setListOfLists(List<Something> listOfSomething) {
this.listOfLists.add(listOfSomething);
}
...
}

Too much data in p:dataTable results in broken row/cell edit submits

I've been using datatables to allow users to enter and edit large amounts of data, but have found that once a large (but uncertain) amount of columns and rows are reached, the form becomes unable to be submitted, and all forms of communication with the server are cut off (unrelated buttons, ajax, etc) until a page refresh is performed.
Is this a limitation of my computer/browser, or is there a hard-coded limit on the maximum quantity of editable data able to be displayed in a datatable? Could this be because of a maximum limit to the number of input fields in a form?
Is the only solution to use paginator for my datatables?
The following is an example that will fail (for me) to be editable if there are too many rows/columns.
<h:form>
<p:dataTable var="_var" value="#{bean.values}" editable="true">
<p:column headerText="Value">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{_var.value}" /></f:facet>
<f:facet name="input"><p:inputText value="#{_var.value}" /></f:facet>
</p:cellEditor>
</p:column>
<!-- Copy and paste this^ column 15 times -->
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
When using row or cell editor, instruct the cellEdit event to use partialSubmit="true".
<p:dataTable ... editable="true">
<p:ajax event="cellEdit" process="#this" partialSubmit="true" />
...
</p:dataTable>
This will send only the input fields covered by process attribute (which is either the row or the cell itself) instead of every single input field.
See also:
How to decrease request payload of p:ajax during e.g. p:dataTable pagination
Okay, I found a solution.
Apparently each input is sent as a GET/POST parameter, and there is a default limit of 512 on servers to prevent DoS attacks.
Unfortunately, Primefaces does not seem to display this error, making it very hard to find.
EDIT: It displays the error, if the logging is set to the correct level. The error is also displayed in the F12 developer tools debugging log.
In short, you must go to your servers standalone.xml and add:
<property name="org.apache.tomcat.util.http.Parameters.MAX_COUNT" value="10000"/>
Under <system-properties>
EDIT
I refused to give up on a better solution than sending thousands of parameters, and revisited this problem.
It seems that PrimeFaces 5.2 added in the <p:ajax partialSubmitFilter=""> attribute, which allows filtering the inputs that you want. This didn't work for me, as I couldn't narrow down the submitted data to the row using just this.
Instead, I decided to override the PrimeFaces.ajax.Request.send function, like so:
var pfsend = PrimeFaces.ajax.Request.send;
PrimeFaces.ajax.Request.send = function(cfg) {
if (cfg.event === 'rowEdit' || cfg.event === 'rowEditCancel') {
// This is an operation on a datatable row. Filter for only that row
cfg.partialSubmitFilter = '[data-ri=' + cfg.ext.params[0].value + '] :input';
}
pfsend(cfg); // Run the original function
};
In this way, the value of the first parameter of the cfg (which is the row being edited) is used as the value for finding an element with the attribute data-ri set to that value (the row).
Note that this does require you to have primefaces 5.2, but for older versions, the same can be achieved by overriding the entire package, and tactically placing similar lines in the right place of the same function (mind that cfg.partialSubmitFilter will not exist).
I found more elegant solution, without overriding function PrimeFaces.ajax.Request.send and still only have it happen on the rowEdit event.
Firstly, define javascript function:
function sendOnlyEditedRow(cfg) {
cfg.partialSubmitFilter = "[data-ri=" + cfg.ext.params[0].value + "] :input";
}
Then call it in onstart callback:
<p:ajax onstart="sendOnlyEditedRow(cfg)" event="rowEdit" listener="#{cc.attrs.detectedFormations.confirmDetectedFormation(i)}"
process="#this detectedFormations" update="detectedFormations"
partialSubmit="true" />

OpenFaces Composite Filter does not render the user search input text field

Good Afternoon,
I am trying to use the composite filter but in vain. While we struggled the whole day trying to know that it does not work if the table contains a column with action buttons and no data type, now we are wondering why it does not render the text field for the user to type his filter criteria.
We click on the (+) button = A drop
down with column names is rendered.
2- From this dropdown, we choose a
column.
3- A 'NOT' checkbox and Another
dropdown with expressions (equals,
contains...etc) is rendered.
4- We choose an expression from the
list.
5- The input text field supposed to be rendered is not rendered at all.
Which makes the composite filter non usable as the user cannot type his search criteria!
Please help.
<div>
<h:form>
<o:compositeFilter id="bookfilter" for="bookstable" autoDetect="true"/>
<o:dataTable id="bookstable" sortColumnId="title" value="#{bookController.items}" var="item" >
<o:singleRowSelection />
<f:facet name="header">
Book TABLE
</f:facet>
<f:facet name="columnMenu">
<o:columnMenu/>
</f:facet>
<o:column id="title" sortingExpression="#{item.title}" header="title">
<h:outputText value="#{item.title}"/>
</o:column>
<o:column id="topic" header="topic">
<h:outputText value="#{item.topic}"/>
</o:column>
<o:column id="writer" header="writerid" >
<h:outputText value="#{item.writer}"/>
</o:column>
</o:dataTable>
Appearently It is a bug affecting versions of Mojarra ulterior to 2.0.3 (2.0.4+).
http://requests.openfaces.org/browse/OF-81
And not fixed yet in the nightly builds.

Resources