jsf-2primefacesdatatabletablecelleditorselectbooleancheckbox

SelectBooleanCheckbox in editable DataTable doesn't change


I have a dataTable that is editable (editMode = "cell").

Editing free text field and list box is quite straightforward. However, I cannot figure out how to edit checkbox field. To be more specific when I try to edit checkbox selection, the data in the output facet is not actualized after the change was made.

<p:dataTable id="submodels" var="submodel" value="#{projectMB.submodels}" 
             editable="true" editMode="cell" widgetVar="cellSubmodels">
  <p:column headerText="Mapping file">
    <p:cellEditor>
      <f:facet name="output">
        <h:selectBooleanCheckbox value="#{submodel.mapping}" onclick="return false;"
           style="width:96%" label="Root model" readonly="true"/>
      </f:facet>
      <f:facet name="input">
        <h:selectBooleanCheckbox value="#{submodel.mapping}" style="width:96%" 
           label="Root model"/>
      </f:facet>
    </p:cellEditor>
  </p:column>
</p:dataTable>

What is a bit suprising, when I change input facet into inputText (and enter true/false value in it), checkbox is updated properly:

<p:dataTable id="submodels" var="submodel" value="#{projectMB.submodels}" 
             editable="true" editMode="cell" widgetVar="cellSubmodels">
  <p:column headerText="Mapping file">
    <p:cellEditor>
      <f:facet name="output">
        <h:selectBooleanCheckbox value="#{submodel.mapping}" onclick="return false;"
           style="width:96%" label="Root model" readonly="true"/>
      </f:facet>
      <f:facet name="input">
        <p:inputText value="#{submodel.mapping}" style="width:96%" />
      </f:facet> 
    </p:cellEditor>
  </p:column>
</p:dataTable>

Can you point out what I have done wrong? I get no errors in javascript console and on Java server side.

I'm using Primefaces version 4.0


Solution

  • This is a bug, or at least an oversight, in PrimeFaces.

    According to the JavaScript code involved (saveCell() function in datatable.js), it only compares the input's new value with the old value before submitting the new value to the server, like so if (input.value != oldvalue). However, in case of checkboxes (and radio buttons) the input value is never changed. It's always the same. It's only the checked state which should trigger the browser to actually send the state to the server or not.

    In other words, the JavaScript code involved should have checked if it's a checkbox (or radiobutton) and then check by if (input.checked != oldchecked) instead.

    There's no way to fix it other than editing the primefaces.js/datatable.js. You'd best report this issue to PrimeFaces guys and get them to fix it.

    In the meanwhile, you can workaround it by copying the value to a hidden input field.

    <f:facet name="input">
        <h:inputHidden value="#{submodel.mapping}" />
        <h:selectBooleanCheckbox value="#{submodel.mapping}" onclick="$(this).prev().val(this.checked)" />
    </f:facet>