Thanks Thiago for your patience, That was just a typo in my last question
when changing my variable back to OTHER from NEW_FUNDING for the question.
The problem had to do with the value encoder creating a new object when
converting the client ID back to an object. I changed the way I handled the
onValueChanged to look for a new Object like we did in the encoder instead
of the object label and it solved the issue. So anyhow, I successfully got
this working. I do think it would be a nice addition to be able to input an
other option directly as a component parameter similar to blankLabel rather
than having to go through all the troubles of coding this up. With the use
of ajax, this is a very handy feature and can be used in many areas such as
payment, shipping addresses, etc. 

Anyhow, I'd like to share the code to all who maybe struggling with this. (I
simplified my code for easier understanding and has not been tested for
compiling errors)


<t:Select t:id="funding" model="fundingModel" zone="fundingZone"
encoder="encoder"/>

    @Property
    private Funding funding;

    @Property
    @Persist
    private SelectModel fundingModel;

    @InjectComponent
    private Zone fundingZone;

    final private static Funding NEW_FUNDING = new Funding();
    final private static String NEW_FUNDING_ID = "-1";

    void onPrepare() {
        fundings = session.createCriteria(Funding.class).list();
        NEW_FUNDING.setName("+ Other");
        fundings.add(NEW_FUNDING);

        fundingModel = selectModelFactory.create(fundings, "label");

    }

    @CommitAfter
    void onSuccess() {
        //you would want to add some sort of logic to prevent the "Other"
object from being commited.
    }

    public ValueEncoder<Funding> getEncoder() {
        final ValueEncoder<Funding> encoder =
valueEncoderSource.getValueEncoder(Funding.class);
        return new FundingValueEncoder(encoder);
    }

    final private static class FundingValueEncoder implements
ValueEncoder<Funding> {
        final private ValueEncoder<Funding> delegate;

        public FundingValueEncoder(ValueEncoder<Funding> delegate) {
            this.delegate = delegate;
        }

        public String toClient(Funding value) {
            if (value == NEW_FUNDING) {
                return NEW_FUNDING_ID;
            } else {
                return delegate.toClient(value);
            }
        }

        public Funding toValue(String clientValue) {
            if (NEW_FUNDING_ID.equals(clientValue))  {
                return NEW_FUNDING;
            } else {
                return delegate.toValue(clientValue);
            }
        }
    }

    public Object onValueChanged(Funding funding) {
        if(funding == NEW_FUNDING) {
            return fundingZone.getBody();
        }
        return null;
    }




--
View this message in context: 
http://tapestry.1045711.n5.nabble.com/T5-Select-Menu-with-Other-Option-tp4520881p4529383.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to