0

I have been looking at Primefaces 3.4.2 since IceFaces 3.2.0 has too many issues. I have a dataGrid of vehicles which are contained in a panel. I have an add button and each vehicle panel contains a remove button.

The add works fine; it adds a new vehicle panel each time. The issue is when I delete a vehicle, the panel is removed, but the value(s) remain. For instance, if I have 3 vehicles with the year as 2008, 2010, 2012, and then I delete the first vehicle, you'd think you would see 2 panels remaining with the year as 2010, and 2012. Instead, I see 2008 and 2012. The backing bean is doing it correctly and I do see the correct values if I manually refresh the screen. Now that I have presented my case here's the code:

<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
    <p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
        <h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
                <ui:include src="../components/vehicleinfo/vehiclecomponents.xhtml">
                    <ui:param name="currentVehicle" value="#{currentVehicle}" />
                    <ui:param name="labelOnly" value="false" />
                </ui:include>
            <div class="deleteButton">
                <p:commandButton value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update=":vehicleInfoForm:vehicleGrid" process="@this">
                    <f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
                </p:commandButton>
            </div>
        </h:panelGrid>
    </p:panel>
 </p:dataGrid>

Any ideas? I have tried all sorts of update values including @form, but it's all the same. I haven't used a dataGrid before but I need the iterative capabilities that ice:panelSeries has.

UPDATE: Here's the code in the include:

<h:panelGrid columns="2">
    <p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label=""
                 required="true" requiredMessage="VIN is required" >
        <p:ajax update="@this vinMsg"/>
    </p:inputText>
    <p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
    <p:outputLabel value="-----OR-----"/>
</h:panelGrid>

1/14/2013 - Updated code

<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
    <p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
        <h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
            <p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label="" required="#{empty param['vehicleGrid:0:btnDelete'] and empty param['btnAdd']}" requiredMessage="VIN is required" >
            </p:inputText>
            <p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
            <p:outputLabel value="-----OR-----"/>
            <h:inputText id="yearInput" styleClass="stdFieldControl" value="#{currentVehicle.year}" label=""
                                             required="#{empty param['vehicleGrid:0:btnDelete']}" requiredMessage="Year is required">
            </h:inputText>
            <p:message id="yearMsg" for="yearInput"
                                           errorClass="ui-state-error-text"/>
            <div class="deleteButton">
                <p:commandButton id="btnDelete" value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update="@form">
                    <f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
                </p:commandButton>
            </div>
        </h:panelGrid>
    </p:panel>
</p:dataGrid>

The add code looks like this:

<div class="addButton" style="padding-left: 2.17%; float: left; clear: both">
    <p:commandButton id="btnAdd" value="AddVehicle" label="Add Vehicle" actionListener="#{vehicleInfoBean.addVehicle}" update="vehicleGrid"/>
</div>

Instead of putting the check on the buttons, I decided to set the required attribute of the components referring to the buttons. This code works if I hardcode the iterator index. For example, required="#{empty param['vehicleGrid:0:btnDelete']}". This code points to the first delete button in the panelGrid. What I need is to dynamically derive the index to this - required="#{empty param['vehicleGrid:#{rowIdx}:btnDelete']}". The add button was easy since it doesn't reside in an iterator. How do I code the param in a way that I can dynically refer to the rowId of the panelGrid? The RowId looks confusing but this is coded in a way that each Vehicle Panel is displayed next to the previous panel. The row in this case can be thought of as a column. Anyone have any ideas?

  • Can you please try it skipping the `ui:include` component? As the tagHandlers are rendering before the most JSF components in page processing, this can cause you problems. http://www.ninthavenue.com.au/blog/c:foreach-vs-ui:repeat-in-facelets Just give it a try without it. – Aritz Jan 11 '13 at 21:48
  • Tried but no change; I have updated the original code above to show what the include contains. So, replace the ui:include with this code. – Patrick Dezenzio Jan 11 '13 at 22:17
  • Have you tried wrapping with ? – Omirp Jan 11 '13 at 22:30
  • Ok, that's not the point. I suggest you to comment the content you have inside the `h:panelGrid` (except *delete* button), since it also has ajax calls can be conflicting. Do it during test and if you get it work add again. If you say it's well formed when refreshing page it is obviusly an ajax update problem. I would try removing `process="@this"` in your remove button and if doesn't work, try surrounding the `h:panelGrid` with a `p:panel` and try updating it. – Aritz Jan 11 '13 at 22:35
  • Ok, did what you requested and it works now. Originally, I had to have the p:ajax in the inputText or nothing got processed. These fields are required so either I put immediate=true on the delete button or use process="@this" on the delete button. What do you think? – Patrick Dezenzio Jan 11 '13 at 22:41
  • I don't see the point of having the `f:ajax` tag inside the input text. Delete button shouldn't go with `immediate=true` because this attribute is attached to non-ajax requests http://stackoverflow.com/a/7708335/1199132. – Aritz Jan 11 '13 at 22:52
  • But without an immediate=true the required fields will be validated if you delete a vehicle. Case in point, you add a vehicle, then turn around and try to delete that new vehicle. The required fields will require you to enter data in the new vehicle before you can delete it. What if a user added by mistake? – Patrick Dezenzio Jan 14 '13 at 14:57
  • I have added an update to the requests and I'm stuck at how to determine the rowIdx of the dataGrid. I need to check each delete button to determine if any were pressed. If so, ignore the validation for that vehicle panel. – Patrick Dezenzio Jan 14 '13 at 19:58
  • Since the original question was answered, I'll add a new question for the JSF EL expression with param. Thanks! – Patrick Dezenzio Jan 14 '13 at 20:29

0 Answers0