jpangamarca
jpangamarca

Reputation: 713

Seam: Trouble updating data in h:inputText in a row of rich:dataTable

I'm trying to build an editable table to enter values of a buy order detail. I have a rich:datatable bound to a List, and I dinamically add rows to the table by adding elements to the list. The entity has two fields that must be entered manually so I'm using h:inputTexts to do it, but the values that are entered on those fields are not being saved to the objects in the list. I tried to do this with a rich:inplaceInput too(following the exact instructions on the Exadel Richfaces livedemo), to no avail. This is my code:

    <rich:panel>
 <f:facet name="header">#{messages.DetalleOrdenCompra}</f:facet>
 <h:outputLabel value="#{messages.Codigo}" for="txtCodigo" /> #{'   '}     
 <h:inputText id="txtCodigo">
  <rich:suggestionbox id="suggestionBox" for="txtCodigo"
   var="consumible" fetchValue="#{consumible.conNombre}"
   suggestionAction="#{ordenCompraHome.autoComplete}" minChars="1"
   reRender="tablaDetOrdComp" ignoreDupResponses="true"
   bypassUpdates="false">
   <h:column>
    <f:facet name="header">#{messages.Codigo}</f:facet>
    <h:outputText value="#{consumible.conNumber}" />
   </h:column>
   <h:column>
    <f:facet name="header">#{messages.Descripcion}</f:facet>
    <h:outputText value="#{consumible.conNombre}" />
   </h:column>
   <a:support event="onselect" immediate="true"
    ignoreDupResponses="true" bypassUpdates="false">
    <f:setPropertyActionListener value="#{consumible}"
     target="#{ordenCompraHome.conActual}" />
   </a:support>
  </rich:suggestionbox>
 </h:inputText>
 #{'   '}
 <!-- Add elements to the list -->
 <a:commandButton type="button" value="#{messages.Agregar}"
  action="#{ordenCompraHome.anadirSeleccionadoADetalle()}"
  reRender="tablaDetOrdComp" immediate="true" />    

 <!-- Hitting this button after entering any values in the table below shows that the values are never updated -->
 <a:commandButton type="button" value="Refrescar tabla"
  reRender="tablaDetOrdComp" immediate="true" />
 <br />
 <br />
 <rich:dataTable value="#{ordenCompraHome.detalleOrdenCompra}"
  var="detOrdComp" id="tablaDetOrdComp" rowKeyVar="row">
  <rich:column width="5%">
   <f:facet name="header">
    <h:outputText value="#"></h:outputText>
   </f:facet>
   <h:outputText value="#{row+1}"></h:outputText>
  </rich:column>

  <!-- ... more columns, just data output -->

  <!-- The two following columns are user inputs -- no updates in the underlying list when entering any value, both values are always null -->
  <rich:column width="10%">
   <f:facet name="header">
    <h:outputText value="#{messages.Cantidad}"></h:outputText>
   </f:facet>
   <s:decorate template="layout/edit-nolabel.xhtml">
   <h:inputText value="#{detOrdComp.ordCantidad}" id="txtCantidad" required="true">
    <!-- tried with both events, onblur and onviewactivated, first each on on its own, then both together, no results -->       
    <a:support event="onblur" reRender="columnaMonto" immediate="true"
     bypassUpdates="false" ajaxSingle="true" />
    <a:support event="onviewactivated" reRender="columnaMonto" immediate="true"
     bypassUpdates="false" ajaxSingle="true" />
   </h:inputText>
   </s:decorate>      
  </rich:column>

  <rich:column width="10%">
   <f:facet name="header">
    <h:outputText value="#{messages.CostoUnitario}"></h:outputText>
   </f:facet>
   <s:decorate template="layout/edit-nolabel.xhtml">
    <h:inputText value="#{detOrdComp.ordCostoUnitario}"
     id="txtCostoUnitario" required="true">
     <a:support event="onblur" reRender="columnaMonto"
      immediate="true" bypassUpdates="false" ajaxSingle="true" />
     <a:support event="onviewactivated" reRender="columnaMonto" immediate="true"
      bypassUpdates="false" ajaxSingle="true" />
    </h:inputText>
   </s:decorate>
  </rich:column>

  <!-- This column is the result of a multiplication between txtCantidad and txtCostoUnitario -- I don't get anything here since both factors are null (null values have been properly handled so 0.0 is displayed when any of the factors is null) --> 

  <rich:column id="columnaMonto" width="10%">
   <f:facet name="header">
    <h:outputText value="#{messages.Monto}"></h:outputText>
   </f:facet>
   <h:outputText value="#{detOrdComp.ordSubparcial}"></h:outputText>
  </rich:column>
 </rich:dataTable>

Bean:

// Underlying list. I used just @DataModel, then @DataModel(scope = ScopeType.PAGE), no results
 @DataModel(scope = ScopeType.PAGE)
 public List<OrdenCompraDetalle> getDetalleOrdenCompra() {
   return detalleOrdenCompra;
 }

Instead of the s:decorates I was using something like this before (from the Livedemo), but it didn't work, either

<rich:dataTable value="#{dataTableScrollerBean.allCars}" var="car" width="350px" columnClasses=",columns,columns,columns" rows="15" id="table" rowKeyVar="row">
<rich:column>
    <f:facet name="header">
        <h:outputText value="Price" />
    </f:facet>
    <rich:inplaceInput layout="block" value="#{car.price}"          
        id="inplace" required="true" selectOnEdit="true" editEvent="ondblclick">                        
            <a4j:support event="onviewactivated" reRender="table, messages"/>
    </rich:inplaceInput>
</rich:column>

What am I missing here? Any help would be appreciated. Thanks in advance.

Upvotes: 2

Views: 4474

Answers (1)

Markos Fragkakis
Markos Fragkakis

Reputation: 7771

I think that your problem is the ajaxSingle="true" attribute. This attribute means that, even if all the input elements in the form are submitted, only the input the one that triggered the submit will be processed.

If this is the problem, you can try any of the following (I assume that the a prefix is the common a4j prefix?):

  • Add the id of the h:inputText, to the processed attribute to <a:support>. This will force the input of the specific row to be processed. For example (not tested):

     <h:inputText value="#{detOrdComp.ordCostoUnitario}"
      id="txtCostoUnitario" required="true">
      <a:support event="onblur" reRender="columnaMonto"
       immediate="true" bypassUpdates="false" ajaxSingle="true" processed="txtCostoUnitario" />
      <a:support event="onviewactivated" reRender="columnaMonto" immediate="true"
       bypassUpdates="false" ajaxSingle="true" processed="txtCostoUnitario"/>
     </h:inputText>
    
  • Remove the ajaxSingle and instead surround the <h:inputText> in a a4j:region (analogous to ajaxSingle with processed, here all the inputs in the closest/enclosing region are processed):

     <a4j:region>
       <h:inputText value="#{detOrdComp.ordCostoUnitario}" id="txtCostoUnitario" 
               required="true">
           <a:support event="onblur" reRender="columnaMonto"
                  immediate="true" bypassUpdates="false" />
           <a:support event="onviewactivated" reRender="columnaMonto" 
               immediate="true" bypassUpdates="false" />
       </h:inputText>
     </a4j:region>
    
  • Remove the ajaxSingle. This will cause all the elements in your form to be processed. Will take more time.

Upvotes: 1

Related Questions