Reputation: 6056
I'm having problems saving/updating rows within a table.
I have a method myBean.addRule to dynamically add new rows to the table.
This seems to work ok....I click it and a new row appears in the UI to enter new data.
But problems seem to arise when I save myBean.saveRules.
It looks like only the most recently added row is getting bound to my backing beans and updated.
For example if I have 3 rows of data:
- remove some text from row 1 and hit the save button this update is NOT saved.
- If I change text on row 3 this change is saved (Most recently added row).
Am I missing some binding attribute on any of my components that would fix this?
<a4j:repeat value="#{myBean.ruleSet}" var="rule" id="ruleIterator">
<h:dataTable value="#{rule}" var="currentRuleItem">
<h:column>
<h:panelGrid columns="2" cellspacing="5">
<h:outputLabel value="#{msg.FrequencyOfSpending}" />
<h:selectOneMenu id="ruleFrequencyOptions" value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected}" styleClass="commonSelect">
<f:selectItems value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.validValues}" itemLabelEscaped="true" />
<f:ajax event="valueChange" listener="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelectedChange}" onerror="handleAjaxError" render="rulesGroup" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="rulesGroup">
<a4j:repeat value="#{currentRuleItem.ruleParams.Action.properties}" var="RuleParamProperty" id="budgetRuleIterator">
<h:panelGrid columns="4" cellspacing="5" columnClasses="ruleParamCheckbox, ruleParamAction, ruleParamActionFrequency, ruleParamActionInput">
<h:selectBooleanCheckbox value="#{RuleParamProperty.selected}" immediate="true">
<a4j:ajax event="click" listener="#{RuleParamProperty.selectedChange}" onerror="handleAjaxError" />
</h:selectBooleanCheckbox>
<h:outputText value="#{msg[RuleParamProperty.name]}" />
<h:panelGrid columns="3">
<h:outputText value="#{msg.Action_1}" />
<h:outputText value="#{msg[currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected]}" class="italic-text" />
<h:outputText value="#{msg.Action_3}" />
</h:panelGrid>
<h:inputText value="#{RuleParamProperty.inputValue}" />
</h:panelGrid>
</a4j:repeat>
</h:panelGroup>
</h:column>
</h:dataTable>
<!--******* Link here to generate row with exact same format as all code above ***-->
<h:panelGrid columns="2">
<img id="AddIcon" src="#{facesContext.externalContext.requestContextPath}/images/icons/add.png" alt="#{msg.addControl}" />
<h:commandLink value="#{msg.addControl}" action="#{myBean.addRule}" />
</h:panelGrid>
</a4j:repeat>
<h:panelGrid columns="2" cellspacing="5">
<h:commandButton value="#{msg.sc_cancel}" immediate="true" action="#{myBean.cancel}" />
<h:commandButton value="#{msg.ua_save}" action="#{myBean.saveRules}" />
</h:panelGrid>
// my bean method
public void addRule()
{
iRuleSet.get("RuleControl1").add(createRule());
}
I have not include my backing bean code as it's extremely complicated, I can edit and show snippets if required.
Thanks in advance
Upvotes: 0
Views: 1308
Reputation: 6056
Ok so after many frustrating hours reading all sorts of articles about different tag handlers (c:forEach, ui:include, etc) and components (ui:repeat, h:datatable, etc..), the differences between them, the problems that can arise from mixing and mashing them, etc.........
It's fixed (I think!)
I removed all my ui:repeat and replaced them with Richfaces a4j:repeat which provides the additional attribute keepSaved. I also removed my h:dataTable and replaced it with aj4:repeat.
Now for the life of me, I cannot find anywhere that explains what keepSaved does!!
The Richfaces 4 API Docs are as per usual, dreadful!
The description beside it reads just like most attributes....No Description!
Could anyone shed some like on what this component attribute does?
Thanks
Solution:
<a4j:repeat value="#{myBean.ruleSet}" var="rule" id="ruleIterator">
<a4j:repeat value="#{rule}" var="currentRuleItem">
<h:column>
<h:panelGrid columns="2" cellspacing="5">
<h:outputLabel value="#{msg.FrequencyOfSpending}" />
<h:selectOneMenu id="ruleFrequencyOptions" value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected}" styleClass="commonSelect">
<f:selectItems value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.validValues}" itemLabelEscaped="true" />
<f:ajax event="valueChange" listener="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelectedChange}" onerror="handleAjaxError" render="rulesGroup" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="rulesGroup">
<a4j:repeat value="#{currentRuleItem.ruleParams.Action.properties}" var="RuleParamProperty" id="budgetRuleIterator" keepSaved="true">
<h:panelGrid columns="4" cellspacing="5" columnClasses="ruleParamCheckbox, ruleParamAction, ruleParamActionFrequency, ruleParamActionInput">
<h:selectBooleanCheckbox value="#{RuleParamProperty.selected}" immediate="true">
<a4j:ajax event="click" listener="#{RuleParamProperty.selectedChange}" onerror="handleAjaxError" />
</h:selectBooleanCheckbox>
<h:outputText value="#{msg[RuleParamProperty.name]}" />
<h:panelGrid columns="3">
<h:outputText value="#{msg.Action_1}" />
<h:outputText value="#{msg[currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected]}" class="italic-text" />
<h:outputText value="#{msg.Action_3}" />
</h:panelGrid>
<h:inputText value="#{RuleParamProperty.inputValue}" />
</h:panelGrid>
</a4j:repeat>
</h:panelGroup>
</h:column>
</a4j:repeat>
<!--******* Link here to generate row with exact same format as all code above ***-->
<h:panelGrid columns="2">
<img id="AddIcon" src="#{facesContext.externalContext.requestContextPath}/images/icons/add.png" alt="#{msg.addControl}" />
<a4j:commandLink value="#{msg.addControl}" action="#{myBean.addRule}">
<f:param name="ruleType" value="BudgetRule" />
</a4j:commandLink>
</h:panelGrid>
</a4j:repeat>
<h:panelGrid columns="2" cellspacing="5">
<h:commandButton value="#{msg.sc_cancel}" immediate="true" action="#{myBean.cancel}" />
<h:commandButton value="#{msg.ua_save}" action="#{myBean.saveRules}" />
</h:panelGrid>
// my bean method
public void addRule()
{
iRuleSet.get("RuleControl1").add(createRule());
}
Upvotes: 1