You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Jose Luis Sanchez <jo...@m-centric.com> on 2010/02/17 18:16:14 UTC
Validating forms inside a loop
Hi all.
I have a multiple form problem .. and after having search and thought
many on this, can't find a solution.
<table t:type="loop" t:source="receivedMessages" t:value="message" >
<tbody>
<tr style="horizontal-align: middle">
<td style="vertical-align: top; horizontal-align: middle width: 323px;">
<form t:type="form" t:id="edit" context="${message.id}"
clientValidation="false">
</t:errors>
<input t:type="textfield" t:id="phone" />
<input value="Save" t:id="save" t:type="submit" />
<input value="Reject" t:id="reject" t:type="submit" />
</form>
</td>
</tr>
</tbody>
</table>
Well, that's a sample of what i have.
I'll tell my usage :
When the user clicks Reject, no clientValidation is done. That's why
i disabled clientvalidation.
When the user clicks Accept, serverside validation is done against
real required fields, but as the form id
is inside a loop, i can't get the validation to show the errors in
it's own form.
private Form edit;
@OnEvent(value=EventConstants.VALIDATE_FORM)
void validateForm() {
edit.clearErrors();
if (phone==null) edit.recordError("Sorry, phone is mandatory");
}
While this works, it shows errors on every form ( currently 3 form
), so i see the famous red-banner thrice.
I can't add edit_0 nor edit_1, because while they are real names in
rendered tml, they are not before, so tapestry gives me an error.
Is there any way i can fix this ?
Thanks.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: Validating forms inside a loop
Posted by Steve Eynon <st...@googlemail.com>.
Hi,
I've put the above into a Mixin, which works fine, but the
implementation is a little "leaky" i.e. the containing component needs
to define it as an Implementation Mixin and set the tracker name /
context in the onPrepareForSubmit event.
I've been trying to change it so that the mixin can be applied to the
form itself and be all containing, such as,
<t:form t:mixins="multitrackerz" ...
Only I need to join, or pipe together the form's tracker parameter
with a parameter (or property) of the mixin, sort of like,
<t:form t:mixins="multitrackerz" t:tracker="multitrackerz.tracker" ...
only that's not possible. Is there another way to accomplish this?
I tried injecting the Form with @InjectContainer in the mixin, but I
can't set parameters there and there is no get / set Tracker on the
Form.
Anyone any ideas?
Steve.
On 18 February 2010 06:19, jose luis sanchez
<jo...@m-centric.com> wrote:
> Wow, you really saved my day !
> Thanks !
> El 17/02/2010, a las 23:09, Josh Canfield escribió:
>
>> The problem is that you really only have one instance of the Form
>> component, and so only one instance of the ValidationTracker. I poked
>> around and wasn't able to find an easier way to do this.
>>
>> Don't use ${} when passing the context.
>> <t:form t:id="edit" clientValidation="false" context="message.id">
>>
>> I used the index of the loop for the context. You can modify to use
>> the message.id
>>
>> @Component(parameters = {"tracker=tracker"})
>> private Form _edit;
>>
>> @Persist(PersistenceConstants.FLASH)
>> private Map<Integer, ValidationTracker> _indexedTrackers;
>>
>> /**
>> * Holds the tracker created when the form is posted and we don't
>> know which form is being processed
>> */
>> private ValidationTracker _tmpTracker;
>>
>> @OnEvent(EventConstants.PREPARE_FOR_SUBMIT)
>> void onPrepareForSubmitFromEdit(int index) {
>> _formIndex = index;
>> }
>>
>> @OnEvent(value = EventConstants.VALIDATE_FORM)
>> void validateForm() {
>> // don't clear the errors here. Clear them after render, otherwise you
>> lose edited value tracking
>> if (name == null) {
>> _edit.recordError("Sorry, name is mandatory");
>> }
>> }
>>
>> public ValidationTracker getTracker() {
>> if (_indexedTrackers == null) _indexedTrackers = new
>> HashMap<Integer, ValidationTracker>();
>> if (_formIndex == null) {
>> // it's a post and we haven't gotten to the part of the
>> action where the fields are processed
>> if (_tmpTracker == null) _tmpTracker = new ValidationTrackerImpl();
>> return _tmpTracker;
>> }
>> if (_tmpTracker != null) {
>> // We have a temp tracker and a form index so we have now
>> processed the input fields
>> // so we can store the temp in the map and clear it.
>> _indexedTrackers.put(_formIndex, _tmpTracker);
>> _tmpTracker = null;
>> }
>>
>> // Make sure we have a tracker for all the forms
>> if (_indexedTrackers.get(_formIndex) == null)
>> _indexedTrackers.put(_formIndex, new ValidationTrackerImpl());
>>
>> return _indexedTrackers.get(_formIndex);
>> }
>>
>> public void setTracker(ValidationTracker tracker) {
>> if (_indexedTrackers == null) _indexedTrackers = new
>> HashMap<Integer, ValidationTracker>();
>> if (_formIndex == null) {
>> // We don't know which form this is for. This gets called
>> at the very end of the action
>> // so you probably have a bug if this is getting called
>> throw new RuntimeException("This shouldn't happen");
>> }
>> _indexedTrackers.put(_formIndex, tracker);
>> // Remember the trackers for the render.
>> setIndexedTrackers(_indexedTrackers);
>> }
>>
>> public void setIndexedTrackers(Map<Integer, ValidationTracker>
>> indexedTrackers) {
>> _indexedTrackers = indexedTrackers;
>> }
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: Validating forms inside a loop
Posted by jose luis sanchez <jo...@m-centric.com>.
Wow, you really saved my day !
Thanks !
El 17/02/2010, a las 23:09, Josh Canfield escribió:
> The problem is that you really only have one instance of the Form
> component, and so only one instance of the ValidationTracker. I poked
> around and wasn't able to find an easier way to do this.
>
> Don't use ${} when passing the context.
> <t:form t:id="edit" clientValidation="false" context="message.id">
>
> I used the index of the loop for the context. You can modify to use
> the message.id
>
> @Component(parameters = {"tracker=tracker"})
> private Form _edit;
>
> @Persist(PersistenceConstants.FLASH)
> private Map<Integer, ValidationTracker> _indexedTrackers;
>
> /**
> * Holds the tracker created when the form is posted and we don't
> know which form is being processed
> */
> private ValidationTracker _tmpTracker;
>
> @OnEvent(EventConstants.PREPARE_FOR_SUBMIT)
> void onPrepareForSubmitFromEdit(int index) {
> _formIndex = index;
> }
>
> @OnEvent(value = EventConstants.VALIDATE_FORM)
> void validateForm() {
> // don't clear the errors here. Clear them after render, otherwise you
> lose edited value tracking
> if (name == null) {
> _edit.recordError("Sorry, name is mandatory");
> }
> }
>
> public ValidationTracker getTracker() {
> if (_indexedTrackers == null) _indexedTrackers = new
> HashMap<Integer, ValidationTracker>();
> if (_formIndex == null) {
> // it's a post and we haven't gotten to the part of the
> action where the fields are processed
> if (_tmpTracker == null) _tmpTracker = new ValidationTrackerImpl();
> return _tmpTracker;
> }
> if (_tmpTracker != null) {
> // We have a temp tracker and a form index so we have now
> processed the input fields
> // so we can store the temp in the map and clear it.
> _indexedTrackers.put(_formIndex, _tmpTracker);
> _tmpTracker = null;
> }
>
> // Make sure we have a tracker for all the forms
> if (_indexedTrackers.get(_formIndex) == null)
> _indexedTrackers.put(_formIndex, new ValidationTrackerImpl());
>
> return _indexedTrackers.get(_formIndex);
> }
>
> public void setTracker(ValidationTracker tracker) {
> if (_indexedTrackers == null) _indexedTrackers = new
> HashMap<Integer, ValidationTracker>();
> if (_formIndex == null) {
> // We don't know which form this is for. This gets called
> at the very end of the action
> // so you probably have a bug if this is getting called
> throw new RuntimeException("This shouldn't happen");
> }
> _indexedTrackers.put(_formIndex, tracker);
> // Remember the trackers for the render.
> setIndexedTrackers(_indexedTrackers);
> }
>
> public void setIndexedTrackers(Map<Integer, ValidationTracker>
> indexedTrackers) {
> _indexedTrackers = indexedTrackers;
> }
>
>
>
> On Wed, Feb 17, 2010 at 9:16 AM, Jose Luis Sanchez
> <jo...@m-centric.com> wrote:
>> Hi all.
>>
>> I have a multiple form problem .. and after having search and thought many
>> on this, can't find a solution.
>>
>>
>> <table t:type="loop" t:source="receivedMessages" t:value="message" >
>> <tbody>
>> <tr style="horizontal-align: middle">
>> <td style="vertical-align: top; horizontal-align: middle width: 323px;">
>> <form t:type="form" t:id="edit" context="${message.id}"
>> clientValidation="false">
>> </t:errors>
>> <input t:type="textfield" t:id="phone" />
>> <input value="Save" t:id="save" t:type="submit" />
>> <input value="Reject" t:id="reject" t:type="submit" />
>> </form>
>> </td>
>> </tr>
>> </tbody>
>> </table>
>>
>>
>> Well, that's a sample of what i have.
>>
>> I'll tell my usage :
>> When the user clicks Reject, no clientValidation is done. That's why i
>> disabled clientvalidation.
>> When the user clicks Accept, serverside validation is done against real
>> required fields, but as the form id
>> is inside a loop, i can't get the validation to show the errors in it's own
>> form.
>>
>>
>> private Form edit;
>>
>> @OnEvent(value=EventConstants.VALIDATE_FORM)
>> void validateForm() {
>> edit.clearErrors();
>> if (phone==null) edit.recordError("Sorry, phone is mandatory");
>> }
>>
>> While this works, it shows errors on every form ( currently 3 form ), so
>> i see the famous red-banner thrice.
>>
>>
>>
>>
>> I can't add edit_0 nor edit_1, because while they are real names in rendered
>> tml, they are not before, so tapestry gives me an error.
>>
>> Is there any way i can fix this ?
>>
>> Thanks.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
>
> --
> --
> http://www.bodylabgym.com - a private, by appointment only, one-on-one
> health and fitness facility.
> --
> http://www.ectransition.com - Quality Electronic Cigarettes at a
> reasonable price!
> --
> TheDailyTube.com. Sign up and get the best new videos on the internet
> delivered fresh to your inbox.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: Validating forms inside a loop
Posted by Josh Canfield <jo...@gmail.com>.
The problem is that you really only have one instance of the Form
component, and so only one instance of the ValidationTracker. I poked
around and wasn't able to find an easier way to do this.
Don't use ${} when passing the context.
<t:form t:id="edit" clientValidation="false" context="message.id">
I used the index of the loop for the context. You can modify to use
the message.id
@Component(parameters = {"tracker=tracker"})
private Form _edit;
@Persist(PersistenceConstants.FLASH)
private Map<Integer, ValidationTracker> _indexedTrackers;
/**
* Holds the tracker created when the form is posted and we don't
know which form is being processed
*/
private ValidationTracker _tmpTracker;
@OnEvent(EventConstants.PREPARE_FOR_SUBMIT)
void onPrepareForSubmitFromEdit(int index) {
_formIndex = index;
}
@OnEvent(value = EventConstants.VALIDATE_FORM)
void validateForm() {
// don't clear the errors here. Clear them after render, otherwise you
lose edited value tracking
if (name == null) {
_edit.recordError("Sorry, name is mandatory");
}
}
public ValidationTracker getTracker() {
if (_indexedTrackers == null) _indexedTrackers = new
HashMap<Integer, ValidationTracker>();
if (_formIndex == null) {
// it's a post and we haven't gotten to the part of the
action where the fields are processed
if (_tmpTracker == null) _tmpTracker = new ValidationTrackerImpl();
return _tmpTracker;
}
if (_tmpTracker != null) {
// We have a temp tracker and a form index so we have now
processed the input fields
// so we can store the temp in the map and clear it.
_indexedTrackers.put(_formIndex, _tmpTracker);
_tmpTracker = null;
}
// Make sure we have a tracker for all the forms
if (_indexedTrackers.get(_formIndex) == null)
_indexedTrackers.put(_formIndex, new ValidationTrackerImpl());
return _indexedTrackers.get(_formIndex);
}
public void setTracker(ValidationTracker tracker) {
if (_indexedTrackers == null) _indexedTrackers = new
HashMap<Integer, ValidationTracker>();
if (_formIndex == null) {
// We don't know which form this is for. This gets called
at the very end of the action
// so you probably have a bug if this is getting called
throw new RuntimeException("This shouldn't happen");
}
_indexedTrackers.put(_formIndex, tracker);
// Remember the trackers for the render.
setIndexedTrackers(_indexedTrackers);
}
public void setIndexedTrackers(Map<Integer, ValidationTracker>
indexedTrackers) {
_indexedTrackers = indexedTrackers;
}
On Wed, Feb 17, 2010 at 9:16 AM, Jose Luis Sanchez
<jo...@m-centric.com> wrote:
> Hi all.
>
> I have a multiple form problem .. and after having search and thought many
> on this, can't find a solution.
>
>
> <table t:type="loop" t:source="receivedMessages" t:value="message" >
> <tbody>
> <tr style="horizontal-align: middle">
> <td style="vertical-align: top; horizontal-align: middle width: 323px;">
> <form t:type="form" t:id="edit" context="${message.id}"
> clientValidation="false">
> </t:errors>
> <input t:type="textfield" t:id="phone" />
> <input value="Save" t:id="save" t:type="submit" />
> <input value="Reject" t:id="reject" t:type="submit" />
> </form>
> </td>
> </tr>
> </tbody>
> </table>
>
>
> Well, that's a sample of what i have.
>
> I'll tell my usage :
> When the user clicks Reject, no clientValidation is done. That's why i
> disabled clientvalidation.
> When the user clicks Accept, serverside validation is done against real
> required fields, but as the form id
> is inside a loop, i can't get the validation to show the errors in it's own
> form.
>
>
> private Form edit;
>
> @OnEvent(value=EventConstants.VALIDATE_FORM)
> void validateForm() {
> edit.clearErrors();
> if (phone==null) edit.recordError("Sorry, phone is mandatory");
> }
>
> While this works, it shows errors on every form ( currently 3 form ), so
> i see the famous red-banner thrice.
>
>
>
>
> I can't add edit_0 nor edit_1, because while they are real names in rendered
> tml, they are not before, so tapestry gives me an error.
>
> Is there any way i can fix this ?
>
> Thanks.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
--
http://www.bodylabgym.com - a private, by appointment only, one-on-one
health and fitness facility.
--
http://www.ectransition.com - Quality Electronic Cigarettes at a
reasonable price!
--
TheDailyTube.com. Sign up and get the best new videos on the internet
delivered fresh to your inbox.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org