Note that there are some explanatory texts on larger screens.

plurals
  1. POGWT Editors - select an item from a list using a valuelistbox
    text
    copied!<p>I have a ValueAwareEditor that contains a couple of sub editors:</p> <p>Essentially, an OfferDto is composed of a TariffDto and a Commission. The Commission can be one of 4 sub-types, but there is only ever one. Usually this list of possible commissions inside the TariffDto will only contain one element, but it can sometimes contain two.</p> <pre><code>public class OfferDto { private TariffDto tariff; // selected from the list in the tariff private Commission commission; } public class TariffDto extends EntityDto { // omitted for brevity... protected List&lt;Commission&gt; commissions = new ArrayList&lt;Commission&gt;(); } </code></pre> <p>When commissions contains more than one item, I want to display a dropdown with the two optiions, and add allow the user to choose between them, each time resetting the commission in the OfferDto and the CommissionEditor.</p> <p>The problem is that, when call commission.setValue() for the second time, the editor does not change. What should I be doing here?</p> <pre><code>public class OfferEditor extends Composite implements ValueAwareEditor&lt;OfferDto&gt; { @UiField TariffRenderer tariff; @Ignore @UiField HTMLPanel panel; @UiField CommissionEditor commission; @Override public void setValue(final OfferDto value) { panel.clear(); List&lt;Commission&gt; commissions = value.getTariff().getCommissions(); if(commissions.size() == 1) { value.setCommission(commissions.get(0)); } else { // multiple commissions ValueListBox&lt;Commission&gt; dropdown = new ValueListBox&lt;Commission&gt;(new Renderer&lt;Commission&gt;() { @Override public String render(Commission object) { return object == null ? "" : object.getName(); } @Override public void render(Commission object, Appendable appendable) throws IOException { appendable.append(render(object)); } }); dropdown.setValue(value.getCommission()); dropdown.setAcceptableValues(commissions); dropdown.addValueChangeHandler(new ValueChangeHandler&lt;Commission&gt;() { @Override public void onValueChange(ValueChangeEvent&lt;Commission&gt; event) { Commission selected = event.getValue(); // this works, but the CommissionEditor that was first rendered remains value.setCommission(selected); } }); panel.add(dropdown); } } } </code></pre> <p>Currently, I am rendering the list of commissions in a ValueListBox, then when the value changes I am pushing that value to the OfferDto. The Commission seems to get set right, but the subEditor does not change.</p> <p>Any help greatly appreciated.</p> <p><strong>EDIT:</strong></p> <p>CommissionEditor shows the relevant sub-editor depending on the type.</p> <pre><code>public class CommissionEditor extends Composite implements Editor&lt;Commission&gt; { private static CommissionEditorUiBinder uiBinder = GWT.create(CommissionEditorUiBinder.class); interface CommissionEditorUiBinder extends UiBinder&lt;Widget, CommissionEditor&gt; { } @UiField Panel subEditorPanel; public CommissionEditor() { initWidget(uiBinder.createAndBindUi(this)); } @Ignore final UnitRateCommissionEditor unitRateCommissionEditor = new UnitRateCommissionEditor(); @Path("") final AbstractSubTypeEditor&lt;Commission, UnitRateCommission, UnitRateCommissionEditor&gt; unitRateCommissionEditorWrapper = new AbstractSubTypeEditor&lt;Commission, UnitRateCommission, UnitRateCommissionEditor&gt;( unitRateCommissionEditor) { @Override public void setValue(final Commission value) { if(value instanceof UnitRateCommission) { setValue(value, value instanceof UnitRateCommission); System.out.println("UnitRateCommission setValue"); subEditorPanel.clear(); subEditorPanel.add(unitRateCommissionEditor); } } }; @Ignore final StandingChargeCommissionEditor standingChargeCommissionEditor = new StandingChargeCommissionEditor(); @Path("") final AbstractSubTypeEditor&lt;Commission, StandingChargeCommission, StandingChargeCommissionEditor&gt; standingChargeCommissionEditorWrapper = new AbstractSubTypeEditor&lt;Commission, StandingChargeCommission, StandingChargeCommissionEditor&gt;( standingChargeCommissionEditor) { @Override public void setValue(final Commission value) { if(value instanceof StandingChargeCommission) { setValue(value, value instanceof StandingChargeCommission); System.out.println("StandingChargeCommission setValue"); subEditorPanel.clear(); subEditorPanel.add(standingChargeCommissionEditor); } } }; @Ignore final PerMwhCommissionEditor perMwhCommissionEditor = new PerMwhCommissionEditor(); @Path("") final AbstractSubTypeEditor&lt;Commission, PerMwhCommission, PerMwhCommissionEditor&gt; perMwhCommissionEditorWrapper = new AbstractSubTypeEditor&lt;Commission, PerMwhCommission, PerMwhCommissionEditor&gt;( perMwhCommissionEditor) { @Override public void setValue(final Commission value) { if(value instanceof PerMwhCommission) { setValue(value, value instanceof PerMwhCommission); System.out.println("PerMwhCommission setValue"); subEditorPanel.clear(); subEditorPanel.add(perMwhCommissionEditor); } } }; } </code></pre> <p><strong>Possible Solution:</strong></p> <p>I changed <code>OfferEditor</code> as so:</p> <pre><code>public class OfferEditor extends Composite implements Editor&lt;OfferDto&gt; { @UiField TariffRenderer tariff; @Path("tariff.commissions") @UiField CommissionsEditor commission; } </code></pre> <p>New editor <code>CommissionsEditor</code> is a CompositeEditor. It needs to take List tariff.commissions and set the chosen Commission into offer.commission:</p> <pre><code>public class CommissionsEditor extends Composite implements CompositeEditor&lt;List&lt;Commission&gt;, Commission, CommissionEditor&gt; { private static CommissionsEditorUiBinder uiBinder = GWT.create(CommissionsEditorUiBinder.class); interface CommissionsEditorUiBinder extends UiBinder&lt;Widget, CommissionsEditor&gt; { } private EditorChain&lt;Commission, CommissionEditor&gt; chain; @UiField FlowPanel dropdownPanel, subEditorPanel; @Ignore CommissionEditor subEditor; public CommissionsEditor() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void setValue(List&lt;Commission&gt; valueList) { // clear both panels dropdownPanel.clear(); subEditorPanel.clear(); if(valueList.size() == 1) { // set the commission to the first in the list Commission selected = valueList.get(0); subEditor = new CommissionEditor(); subEditorPanel.add(subEditor); chain.attach(selected, subEditor); } else if(valueList.size() &gt; 1) { ValueListBox&lt;Commission&gt; dropdown = new ValueListBox&lt;Commission&gt;(new Renderer&lt;Commission&gt;() { @Override public String render(Commission object) { return object == null ? "" : object.getName(); } @Override public void render(Commission object, Appendable appendable) throws IOException { appendable.append(render(object)); } }); dropdownPanel.add(dropdown); dropdown.setValue(valueList.get(0)); dropdown.setAcceptableValues(valueList); dropdown.addValueChangeHandler(new ValueChangeHandler&lt;Commission&gt;() { @Override public void onValueChange(ValueChangeEvent&lt;Commission&gt; event) { Commission selected = event.getValue(); subEditorPanel.clear(); CommissionEditor subEditor = new CommissionEditor(); subEditorPanel.add(subEditor); chain.attach(selected, subEditor); } }); } } @Override public void flush() { } @Override public void onPropertyChange(String... paths) { // TODO Auto-generated method stub } @Override public void setDelegate(EditorDelegate&lt;List&lt;Commission&gt;&gt; delegate) { // TODO Auto-generated method stub } @Override public CommissionEditor createEditorForTraversal() { return new CommissionEditor(); } @Override public String getPathElement(CommissionEditor subEditor) { return null; } @Override public void setEditorChain(EditorChain&lt;Commission, CommissionEditor&gt; chain) { this.chain = chain; } } </code></pre> <p>When the <code>CommissionsEditor</code> renders the dropdown and <code>onValueChange()</code> is called, the new editor gets created, but the value for the commission never seems to get set.</p> <p>For some reason the selected subEditor's value is not pushed into <code>offer.setCommission()</code>. I thought <code>chain.attach()</code> would perform this for me?</p>
 

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