1

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>
Addison
  • 7,322
  • 2
  • 39
  • 55
  • What version of PrimeFaces do you happen to use? Is there any JavaScript error on the browser console? What is the status of AJAX request/response? If horizontal space is the concern in displaying a data table with many columns, choose a horizontally scrollable data table. – Tiny Aug 04 '15 at 02:54
  • I'm using Primefaces version 5.0 - And the horizontal space isn't any issue, as the columns just get thinner. My console isn't displaying anything whatsoever. – Addison Aug 04 '15 at 03:38
  • What if you use native jsf controls in the cellEditor? And did you try a newer PF verions, just to see if behaviour changed/improved? – Kukeltje Aug 04 '15 at 06:09

3 Answers3

3

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).

Addison
  • 7,322
  • 2
  • 39
  • 55
  • And an additional piece of information: If you have other submits in the same form as a datatable, then you can place: `else {cfg.partialSubmitFilter = 'not[data-ri] :input';}`, to exclude the datatable rows from being submitted. Note that this is pretty slack JavaScript, and can probably be improved upon to be more generic. – Addison Sep 17 '15 at 03:42
3

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:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This is a far cleaner and more convenient solution than mine, as it not only prevents changing the servers settings for a single page, but also minimises the data sent, speeding up queries to a constant time. Unfortunately, I couldn't get it to work - The result was exactly the same. I'd like to use this approach, but it breaks even before I can even edit anything (i.e: Unrelated links at the top/bottom of page don't work, etc) – Addison Aug 06 '15 at 02:08
1

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" />
Kukeltje
  • 12,223
  • 4
  • 24
  • 47
GreenTea
  • 344
  • 3
  • 9
  • 1
    The downside is, is that you should not forget to add this to each datatable while the other solution can be added to a template and work for each datatable. So the 'more elegant' is debatable ;-) – Kukeltje Sep 01 '16 at 09:17
  • Good point @Kukeltje. But even so, this has plenty of uses as well - The same problem happened on a few other elements, but I never could figure out a way to fix them. With this, I'd be able to specify exactly what a particularly uncooperative event does. – Addison Sep 02 '16 at 02:28