Note that there are some explanatory texts on larger screens.

plurals
  1. POChanges to backing object in actionListener not reflected in bound UI elements
    primarykey
    data
    text
    <p>I have a JSF page which has a variable number inputText elements containing numeric weights. These are all bound to Weight objects in my backing bean. I'd like to create a single actionListener button which will re-distribute the weights across all the input texts. </p> <p>I can call the method in the backing bean which distributes the values contained in the weight objects within the backing bean, but for some reason those updated values are not reflected in the InputText elements.</p> <p>It is my assumption that the values are being put back in the UI elements before I update the values. Just shows my lack of understanding of the JSF lifecycle. </p> <p>Can someone tell me how I could accomplish this?</p> <p>Here is the relevant part of the xhtml file. For each child I reference the "newWeight" object key'd by the child object. The newWeight objects are created in the loadFamily method which is bound to the preRenderView event: </p> <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:h="http://java.sun.com/jsf/html"&gt; &lt;ui:composition template="/templates/layout.xhtml"&gt; &lt;f:metadata&gt; &lt;f:viewParam name="familyId" required="true" requiredMessage="familyId is required" value="#{weighFamilyBacking.familyId}"&gt;&lt;/f:viewParam&gt; &lt;f:event type="preRenderView" listener="#{weighFamilyBacking.loadFamily}" /&gt; &lt;/f:metadata&gt; &lt;ui:define name="title"&gt;Weigh Family&lt;/ui:define&gt; &lt;ui:define name="content"&gt; &lt;h:form&gt; &lt;h2&gt;Previous Weights&lt;/h2&gt; &lt;rich:dataTable value="#{weighFamilyBacking.allWeights}" var="weight" id="table"&gt; &lt;rich:column&gt; &lt;f:facet name="header"&gt; &lt;h:outputText value="Child" /&gt; &lt;/f:facet&gt; &lt;h:outputText value="#{weight.child.firstName} #{weight.child.lastName}" /&gt; &lt;/rich:column&gt; &lt;rich:column&gt; &lt;f:facet name="header"&gt; &lt;h:outputText value="Weight" /&gt; &lt;/f:facet&gt; &lt;h:outputText value="#{weight.weight}" /&gt; &lt;/rich:column&gt; &lt;rich:column&gt; &lt;f:facet name="header"&gt; &lt;h:outputText value="Weigh Time" /&gt; &lt;/f:facet&gt; &lt;h:outputText value="#{weight.weighTime}" /&gt; &lt;/rich:column&gt; &lt;rich:column&gt; &lt;f:facet name="header"&gt; &lt;h:outputText value="Payout Time" /&gt; &lt;/f:facet&gt; &lt;h:outputText value="#{weight.payoutTime}" /&gt; &lt;/rich:column&gt; &lt;rich:column&gt; &lt;f:facet name="header"&gt; &lt;h:outputText value="Payout Status" /&gt; &lt;/f:facet&gt; &lt;h:outputText value="#{weight.status}" /&gt; &lt;/rich:column&gt; &lt;/rich:dataTable&gt; &lt;h2&gt;New Weights&lt;/h2&gt; &lt;h:panelGroup id="newWeights"&gt; &lt;ul&gt; &lt;ui:repeat var="child" value="#{weighFamilyBacking.children}"&gt; &lt;li&gt;&lt;h:panelGroup layout="block"&gt; &lt;h:outputText value="#{child.firstName}" /&gt; &lt;h:outputLabel value="Lbs" for="lbs"&gt; &lt;h:inputText size="3" id="lbs" value="#{weighFamilyBacking.newWeights[child].lbs}" /&gt; &lt;/h:outputLabel&gt; &lt;h:outputLabel value="Oz" for="oz"&gt; &lt;h:inputText id="oz" size="3" value="#{weighFamilyBacking.newWeights[child].oz}" /&gt; &lt;/h:outputLabel&gt; &lt;/h:panelGroup&gt;&lt;/li&gt; &lt;/ui:repeat&gt; &lt;h:outputLabel value="Donate Only" for="donate"&gt; &lt;h:selectBooleanCheckbox id="donate" value="#{weighFamilyBacking.donateOnly}" /&gt; &lt;/h:outputLabel&gt; &lt;/ul&gt; &lt;/h:panelGroup&gt; &lt;h:commandButton actionListener="#{weighFamilyBacking.distributeWeights}" immediate="true" value="Redistribute" /&gt; &lt;h:commandButton action="cancel" value="Cancel" /&gt; &lt;h:commandButton action="#{weighFamilyBacking.save}" value="Save" /&gt; &lt;/h:form&gt; &lt;/ui:define&gt; &lt;/ui:composition&gt; &lt;/html&gt; </code></pre> <p>Here is the backing bean:</p> <pre><code>@ViewScoped @ManagedBean public class WeighFamilyBacking extends BaseForm implements Serializable { private static final long serialVersionUID = 3710213437377609887L; private Integer familyId; private Boolean donateOnly; public Boolean getDonateOnly() { return donateOnly; } public void distributeWeights(ActionEvent event) { Integer oz = 0; Integer count = 0; for (WebWeight ww : newWeights.values()) { System.out.println(ww); oz += ww.getLbs() * 16; oz += ww.getOz(); ww.setLbs(123); // Set the values to something to simulate re-distribution for now. ww.setOz(456); count++; } donateOnly = true; } public void setDonateOnly(Boolean donateOnly) { this.donateOnly = donateOnly; } private Family family; private HashMap&lt;Child, WebWeight&gt; newWeights; public HashMap&lt;Child, WebWeight&gt; getNewWeights() { return newWeights; } public void setNewWeights(HashMap&lt;Child, WebWeight&gt; newWeights) { this.newWeights = newWeights; } public WeighFamilyBacking() { newWeights = new HashMap&lt;Child, WebWeight&gt;(); } public List&lt;Weight&gt; getAllWeights() { List&lt;Weight&gt; weights = new ArrayList&lt;Weight&gt;(); for (Child c : getFamily().getChildrenAsList()) { for (Weight w : c.getWeightsAsList()) weights.add(w); } Collections.sort(weights, new Comparator&lt;Weight&gt;() { @Override public int compare(Weight arg0, Weight arg1) { if (arg0.getWeighTime() == null) return -1; Integer date = arg0.getWeighTime().compareTo( arg1.getWeighTime()); if (date == 0) return arg0.getChild().getFirstName() .compareTo(arg1.getChild().getFirstName()); return date; } }); return weights; } @PostConstruct public void init() { } public void loadFamily() { if (family == null) { setFamily(hcbbService.findFamilyById(getFamilyId())); for (Child c : family.getChildrenAsList()) { WebWeight w = new WebWeight(); newWeights.put(c, w); } } } public void setFamilyId(Integer id) { this.familyId = id; } public Integer getFamilyId() { return this.familyId; } public Family getFamily() { return family; } public void setFamily(Family f) { this.family = f; } public List&lt;Child&gt; getChildren() { List&lt;Child&gt; children = getFamily().getChildrenAsList(); Collections.sort(children); return children; } public String cancel() { return "cancel"; } public String save() { for (Child c : newWeights.keySet()) { WebWeight ww = newWeights.get(c); Weight w = new Weight(); w.setWeighTime(new Date()); Double weight = (ww.getLbs() * 16.0 + ww.getOz()) / 16.0; w.setWeight(weight); w.setStatus(WeightStatus.AWAITING_PAYOUT); c.getWeights().add(w); } hcbbService.updateRegistration(family); return "success"; } } </code></pre> <p>The goal is to allow us to put weights in a single child and then have it evenly distribute the values across all "newWeight" objects. Right now I would expect that all my UI elements linked to the NewWeight objects would be zero after I click redistribute (since that method is getting called, and the values are being reset), but they aren't. </p> <p><strong>Additional Info</strong></p> <p>My adjustment of the WebWeight objects is happening at the INVOKE_APPLICATION phase as expected. The objects have the correct values before Render response.. but not in the rendered components? </p> <p>From Log:</p> <pre><code>BEFORE INVOKE_APPLICATION 5 net.halo3.hcbb.registration.WebWeight@2f6cd09f net.halo3.hcbb.registration.WebWeight@10f48f0c net.halo3.hcbb.registration.WebWeight@27db6586 AFTER INVOKE_APPLICATION 5 BEFORE RENDER_RESPONSE 6 oz=456 lbs=123 object=net.halo3.hcbb.registration.WebWeight@2f6cd09f oz=456 lbs=123 object=net.halo3.hcbb.registration.WebWeight@10f48f0c oz=456 lbs=123 object=net.halo3.hcbb.registration.WebWeight@27db6586 AFTER RENDER_RESPONSE 6 </code></pre> <p><strong>More Info</strong></p> <p>Here is the dump from logs, where I log getLbs and getOz.. You can see that getLbs or getOz on the WebWeight object is not called during the Render phase?</p> <pre><code> - BEFORE INVOKE_APPLICATION 5 net.halo3.hcbb.registration.WebWeight@12d58dfe net.halo3.hcbb.registration.WebWeight@12d58dfe getLbz: 0 net.halo3.hcbb.registration.WebWeight@12d58dfe getOz:0 net.halo3.hcbb.registration.WebWeight@25d285b net.halo3.hcbb.registration.WebWeight@25d285b getLbz: 0 net.halo3.hcbb.registration.WebWeight@25d285b getOz:0 net.halo3.hcbb.registration.WebWeight@6c317dc9 net.halo3.hcbb.registration.WebWeight@6c317dc9 getLbz: 0 net.halo3.hcbb.registration.WebWeight@6c317dc9 getOz:0 - AFTER INVOKE_APPLICATION 5 - BEFORE RENDER_RESPONSE 6 - AFTER RENDER_RESPONSE 6 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload