Re: T5 Select Menu with Other Option
After playing with the value encoder, I found this method to be slightly better since it will handle newly created session objects / existing objects and other. @SuppressWarnings(unchecked) public ValueEncoder getSelectEncoder() { return new ValueEncoderFunding() { public String toClient(Funding value) { if (value == NEW_FUNDING) { return NEW_FUNDING_ID; } else { Long key = value.getTempId(); return key.toString(); } } public Funding toValue(String clientValue) { if (NEW_FUNDING_ID.equals(clientValue)) { return NEW_FUNDING; } else { for (Funding _funding : getPurchaseRequest().getFundings()) { if (_funding.getTempId() == Long.parseLong(clientValue)) { return _funding; } } } return null; } }; } -- View this message in context: http://tapestry.1045711.n5.nabble.com/T5-Select-Menu-with-Other-Option-tp4520881p4539330.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
Re: T5 Select Menu with Other Option
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 ValueEncoderFunding getEncoder() { final ValueEncoderFunding encoder = valueEncoderSource.getValueEncoder(Funding.class); return new FundingValueEncoder(encoder); } final private static class FundingValueEncoder implements ValueEncoderFunding { final private ValueEncoderFunding delegate; public FundingValueEncoder(ValueEncoderFunding 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
Re: T5 Select Menu with Other Option
Hi! On Fri, 24 Jun 2011 09:44:42 -0300, gchristman gchrist...@cardaddy.com wrote: Hello, I'm trying to add an other option to my select menu and have the other option trigger a zone reload when selected. I get the following error [ERROR]entities.Funding Unable to convert client value '-1' into an entity instance. This is probably done by the ValueEncoder tapestry-hibernate automatically uses. I almost feel the Select component should have an other parameter option with the ability to provide it with any custom text that can be picked up by the onValueChanged in order to easily return a zone and further enrich our interfaces. Take a look at the blankOption and blankLabel parameters of the Select component. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Select Menu with Other Option
Hi Thiago, You are correct with it being done by the ValueEncoder tapestry-hibernate automatically which is why I'm receiving that error. Not entirely sure how to get around it. I'm using the blankOption=always, blankLabel=Funding Source parameters already. I guess I'm not clear with what your suggesting. When the other option is present and selected, I need to return a zone in order to create a new entry, but not be able to commit the other option to the db. Blanklabel still needs to be present with the other option. Any other thoughts? Cheers, George -- View this message in context: http://tapestry.1045711.n5.nabble.com/T5-Select-Menu-with-Other-Option-tp4520881p4520995.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
Re: T5 Select Menu with Other Option
On Fri, 24 Jun 2011 10:23:53 -0300, George Christman gchrist...@cardaddy.com wrote: Hi Thiago, Hi! You are correct with it being done by the ValueEncoder tapestry-hibernate automatically which is why I'm receiving that error. Not entirely sure how to get around it. I'd get the Funding ValueEncoder from ValueEncoder source, create a wrapper a wrapper around it that checks for -1 id's and returning a special Funding object. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Select Menu with Other Option
Would you mind elaborating a bit on getting the Funding ValueEncoder from ValueEncoder source, or point me to an example? I'm not very familiar with the ValueEncoder and not finding much doc on your method. Thanks Thiago. -- View this message in context: http://tapestry.1045711.n5.nabble.com/T5-Select-Menu-with-Other-Option-tp4520881p4521089.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
Re: T5 Select Menu with Other Option
On Fri, 24 Jun 2011 10:57:43 -0300, George Christman gchrist...@cardaddy.com wrote: Would you mind elaborating a bit on getting the Funding ValueEncoder from ValueEncoder source, or point me to an example? I'm not very familiar with the ValueEncoder and not finding much doc on your method. Something like this (not tested): select t:type=Select ... t:encoder=fundingEncoder/ final private static Funding OTHER = new Funding(); final private static String OTHER_ID = -1; @Inject private ValueEncoderSource valueEncoderSource; public ValueEncoderFunding getFundingEncoder() { final ValueEndcoderFunding encoder = valueEncoderSource.getValueEncoder(Funding.class); return new FundingValueEncoder(encoder); } final private static FundingValueEncoder implements ValueEncoderFunding { final private ValueEncoderFunding delegate; public FundingValueEncoder(ValueEncoderFunding delegate) { this.delegate = delegate; } public String toClient(Funding value) { if (value == OTHER) { return OTHER_ID; } else { return delegate.toClient(value); } } public Funding toValue(String clientValue) { if (OTHER_ID.equals(clientValue) { return OTHER; } else { return delegate.toValue(clientValue); } } } -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Select Menu with Other Option
Other than a few typos, code compiled and worked, however doesn't seem to be solving the issue. I'll show you exactly what I'm doing, maybe I'm missing something small. The value never seems to equal OTHER in your method. I really appreciate everything thus far. Thanks ! tml t:AjaxFormLoop t:id=lineItem source=purchaseRequest.lineItems value=lineItem encoder=encoderLineItem t:TextField value=lineItem.name/ t:AjaxFormLoop t:id=lineItemFunding context=lineItem.tempId source=lineItem.lineItemFundings value=lineItemFunding encoder=encoderLineItemFunding t:Select t:id=newFunding value=lineItemFunding.funding model=fundingModel zone=fundingZone encoder=selectEncoder blankOption=always blankLabel=Funding Source/ /t:AjaxFormLoop /t:AjaxFormLoop class @PageActivationContext private PurchaseRequest _purchaseRequest; @Property @Persist private PurchaseRequest purchaseRequest; @Property private LineItemFunding lineItemFunding; @Property private Funding funding; @Property @Persist private SelectModel fundingModel; @Inject private SelectModelFactory selectModelFactory; @Inject private ValueEncoderSource valueEncoderSource; final private static String NEW_FUNDING_NAME = + Add New Funding; final private static Funding OTHER = new Funding(); final private static String OTHER_ID = -1; void setupRender() { if(_purchaseRequest == null) { purchaseRequest = new PurchaseRequest(); } else { purchaseRequest = _purchaseRequest; } } void onPrepareFromPR() { ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); funding = new Funding(); funding.setName(NEW_FUNDING_NAME); funding.setId(OTHER_ID); _fundings.add(funding); fundingModel = selectModelFactory.create(_fundings, label); } public Object onValueChanged(Funding funding) { if(funding != null funding.getName().equals(NEW_FUNDING_NAME)) { return fundingZone.getBody(); } return null; } @CommitAfter void onSuccessFromPR() { session.saveOrUpdate(purchaseRequest); } //Select Menu OnChange public Object onValueChanged(Funding funding) { if(funding != null funding.getName().equals(NEW_FUNDING_NAME)) { return fundingZone.getBody(); } return null; } //Encoders @SuppressWarnings(unchecked) public ValueEncoder getEncoderLineItem() { return new ValueEncoderLineItem() { public String toClient(LineItem value) { Long key = value.getTempId(); return key.toString(); } public LineItem toValue(String keyAsString) { Long key = new Long(keyAsString); for (LineItem holder : purchaseRequest.getLineItems()) { if (holder.getTempId() == key) { return holder; } } return null; } }; } @SuppressWarnings(unchecked) public ValueEncoder getEncoderLineItemFunding() { return new ValueEncoderLineItemFunding() { public String toClient(LineItemFunding value) { Long key = value.getTempId(); return key.toString(); } public LineItemFunding toValue(String keyAsString) { Long key = new Long(keyAsString); for (LineItemFunding holder : lineItem.getLineItemFundings()) { if (holder.getTempId() == key) { return holder; } } return null; } }; } public ValueEncoderFunding getSelectEncoder() { final ValueEncoderFunding encoder = valueEncoderSource.getValueEncoder(Funding.class); return new FundingValueEncoder(encoder); } final private static class FundingValueEncoder implements ValueEncoderFunding { final private ValueEncoderFunding delegate; public FundingValueEncoder(ValueEncoderFunding delegate) { this.delegate = delegate; } public String toClient(Funding value) { if (value == OTHER) { System.out.println(OTHER_ID); return OTHER_ID; } else { return delegate.toClient(value); } } public Funding toValue(String clientValue) { if (OTHER_ID.equals(clientValue)) { return OTHER; } else { return delegate.toValue(clientValue); } } } //Add Row - TempID UUID LineItem onAddRowFromLineItem() { LineItem newLineItem = new LineItem(); purchaseRequest.getLineItems().add(newLineItem);
Re: T5 Select Menu with Other Option
On Fri, 24 Jun 2011 12:35:51 -0300, George Christman gchrist...@cardaddy.com wrote: void onPrepareFromPR() { ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); funding = new Funding(); funding.setName(NEW_FUNDING_NAME); funding.setId(OTHER_ID); _fundings.add(funding); fundingModel = selectModelFactory.create(_fundings, label); } Here's the problem: you should use OTHER instead of instantiating Funding, as the encoder is doing a == check. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Select Menu with Other Option
Seems like we are super close now. Hopefully I'm doing this correctly ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); _fundings.add(OTHER); ValueEncoder is returning -1 as expected and the onValueChanged(Funding funding) seems to be returning an object. Only two issues left to resolve is a null funding name / id within onValueChanged and no funding label exist within the select menu. If you could point me in the direction to resolving those two bugs, this issue should be completed. Once again, thanks so much! -- View this message in context: http://tapestry.1045711.n5.nabble.com/T5-Select-Menu-with-Other-Option-tp4520881p4521568.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
Re: T5 Select Menu with Other Option
On Fri, 24 Jun 2011 13:34:59 -0300, George Christman gchrist...@cardaddy.com wrote: Seems like we are super close now. Hopefully I'm doing this correctly ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); _fundings.add(OTHER); I guess so. :) ValueEncoder is returning -1 as expected and the onValueChanged(Funding funding) seems to be returning an object. Only two issues left to resolve is a null funding name / id within onValueChanged and no funding label exist within the select menu. If you could point me in the direction to resolving those two bugs, this issue should be completed. Once again, thanks so much! I guess both can be solved by setting the id and the property used as label in the OTHER object. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Select Menu with Other Option
Thiago, it looks like that did the trick. I'm running into a couple issues, sorry to keep bothering you :-/ I'm setting the funding id / name ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); NEW_FUNDING.setName(NEW_FUNDING_NAME); NEW_FUNDING.setId(OTHER_ID); _fundings.add(OTHER); value encoder works perfectly, and the onChanged method works perfectly for a short period before funding id / name goes null. The funding object still exist though. Any Ideas? public Object onValueChanged(Funding funding) { System.out.println(Change + funding.getId()); if(funding != null funding.getName().equals(NEW_FUNDING_NAME)) { return fundingZone.getBody(); } return null; } Also, I need to validate that the other object isn't being selected and committed to the db. I wrote this code within the onValidate method for (LineItem _lineItem : purchaseRequest.getLineItems()) { for(LineItemFunding _lineItemFunding : _lineItem.getLineItemFundings()) { if(lineItemFunding.getFunding().getId() == -1) { _lineItem.getLineItemFundings().remove(_lineItemFunding); } } } and I get the following error java.util.ConcurrentModificationException Hide uninteresting stack frames Stack trace * java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) * java.util.AbstractList$Itr.next(AbstractList.java:343) * org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:580) * com.mycompany.rolemanager.pages.Purchase_Request.onValidateFromPR(Purchase_Request.java:137) * com.mycompany.rolemanager.pages.Purchase_Request$MethodAccess_onValidateFromPR_130c294c1c0.invoke(Purchase_Request$MethodAccess_onValidateFromPR_130c294c1c0.java) * org.apache.tapestry5.internal.transform.BaseEventHandlerMethodInvoker.invokeEventHandlerMethod(BaseEventHandlerMethodInvoker.java:52) * org.apache.tapestry5.internal.transform.OnEventWorker$4.invokeEventHandlers(OnEventWorker.java:157) * org.apache.tapestry5.internal.transform.OnEventWorker$4.advise(OnEventWorker.java:136) * org.apache.tapestry5.internal.services.AbstractComponentMethodInvocation.proceed(AbstractComponentMethodInvocation.java:86) * com.mycompany.rolemanager.pages.Purchase_Request.dispatchComponentEvent(Purchase_Request.java) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:942) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.processEventTriggering(ComponentPageElementImpl.java:1132) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.access$3000(ComponentPageElementImpl.java:72) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl$7.invoke(ComponentPageElementImpl.java:1077) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl$7.invoke(ComponentPageElementImpl.java:1075) * org.apache.tapestry5.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:65) * org.apache.tapestry5.ioc.internal.PerThreadOperationTracker.invoke(PerThreadOperationTracker.java:68) * org.apache.tapestry5.ioc.internal.RegistryImpl.invoke(RegistryImpl.java:1063) * org.apache.tapestry5.internal.structure.ComponentPageElementResourcesImpl.invoke(ComponentPageElementResourcesImpl.java:141) * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1073) * org.apache.tapestry5.internal.structure.InternalComponentResourcesImpl.triggerContextEvent(InternalComponentResourcesImpl.java:287) * org.apache.tapestry5.corelib.components.Form.fireValidateEvent(Form.java:606) * org.apache.tapestry5.corelib.components.Form.fireValidateFormEvent(Form.java:594) * org.apache.tapestry5.corelib.components.Form._$advised$onAction(Form.java:548) * org.apache.tapestry5.corelib.components.Form$onAction$invocation_130c294d0e0.invokeAdvisedMethod(Form$onAction$invocation_130c294d0e0.java) * org.apache.tapestry5.internal.services.AbstractComponentMethodInvocation.proceed(AbstractComponentMethodInvocation.java:77) * org.apache.tapestry5.ioc.internal.services.LoggingAdvice.advise(LoggingAdvice.java:37) * org.apache.tapestry5.internal.transform.LogWorker$1.advise(LogWorker.java:54) * org.apache.tapestry5.internal.services.AbstractComponentMethodInvocation.proceed(AbstractComponentMethodInvocation.java:86) * org.apache.tapestry5.corelib.components.Form.onAction(Form.java) *
Re: T5 Select Menu with Other Option
On Fri, 24 Jun 2011 15:48:08 -0300, George Christman gchrist...@cardaddy.com wrote: ListFunding _fundings = session.createCriteria(Funding.class).add(Restrictions.eq(purchaseRequest.id, purchaseRequest.getId())).list(); NEW_FUNDING.setName(NEW_FUNDING_NAME); NEW_FUNDING.setId(OTHER_ID); _fundings.add(OTHER); You're setting the fields of NEW_FUNDING and using OTHER. ;) OTHER.setName(NEW_FUNDING_NAME); OTHER.setId(OTHER_ID); _fundings.add(OTHER); Also, I need to validate that the other object isn't being selected and committed to the db. I wrote this code within the onValidate method for (LineItem _lineItem : purchaseRequest.getLineItems()) { for(LineItemFunding _lineItemFunding : _lineItem.getLineItemFundings()) { if(lineItemFunding.getFunding().getId() == -1) { _lineItem.getLineItemFundings().remove(_lineItemFunding); } } } and I get the following error java.util.ConcurrentModificationException Copy the list to another list instance and work on the copy. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org