On Apr 16, 2007, at 5:25 PM, George Sakkis wrote:
>
> On Apr 16, 7:29 am, Alberto Valverde <[EMAIL PROTECTED]> wrote:
>> On Apr 16, 2007, at 6:44 AM, George Sakkis wrote:
>>> On Apr 15, 8:11 pm, Alberto Valverde <[EMAIL PROTECTED]> wrote:
>>
>>>> On Apr 15, 2007, at 11:50 PM, George Sakkis wrote:
>>>>> On Apr 15, 5:19 pm, Alberto Valverde <[EMAIL PROTECTED]> wrote:
>>>>>> On Apr 15, 2007, at 10:06 PM, George Sakkis wrote:
>>
>>>>>>> That's an old unanswered post but it seems nothing changed in
>>>>>>> the
>>>>>>> meantime; I wasted half a day to realize I got beaten by the
>>>>>>> same
>>>>>>> bug
>>>>>>> (or "feature"). Apart from being practically undocumented, in my
>>>>>>> case
>>>>>>> the raw value is validated and transformed to a python value
>>>>>>> that
>>>>>>> doesn't even make sense to display. Why on earth does the
>>>>>>> displayed
>>>>>>> form shows the validated (python) values instead of the raw user
>>>>>>> provided values ?
>>
>>>>>> That's a feature. The validate decorator places validated and
>>>>>> coerced
>>>>>> values there. For the raw params as they arrived check out
>>>>>> request.params.
>>
>>>>> If this is the role of input_values, then what's problematic is
>>>>> InputWidget.adjust_value that uses it:
>>
>>>>> def adjust_value(self, value, **params):
>>>>> if hasattr(request, "input_values") and self.is_validated:
>>>>> input_submitted = True
>>>>> iv = retrieve_value_by_path(request.input_values,
>>>>> self.name_path)
>>
>>>>> By definition adjust_value() should return a value to display
>>>>> in the
>>>>> template, not the validated python value. I can't imagine how
>>>>> or why
>>>>> the template is supposed to render arbitrary python values, or
>>>>> even if
>>>>> it can, it doesn't make sense to do so in general. For example, I
>>>>> take
>>>>> as input from the form a dict {"key1": "value1", "key2":
>>>>> "value2", ...} and transform it to a string "value1|value2|...|
>>>>> valueN". The application knows how to process this, however it
>>>>> doesn't
>>>>> make sense to send this internal value to the form.
>>
>>>> Exatcly, adjust_value should adjust the value before sending it to
>>>> the template. I think you haven't read the whole function's body
>>>> [1],
>>>> the widget's validator is called at line 232 to convert the value
>>>> before sending it to the template.
>>
>>> I did read all of it; perhaps you missed line 226. If 'iv' is not
>>> None, the validator's from_python is never called and the python
>>> value
>>> is returned instead. At least that's what happens in my case.
>>
>> "iv" is not None when the form is being redisplayed (this scenario is
>> detected because hasattr(request, "input_values") == True). In that
>> case the values should be strings already because formencode's Schema
>> does not coerce them if validation failed, from_python shouldn't be
>> called in that case.
>
> Wait a sec; do you mean that TG assumes that whenever a form is
> redisplayed it is because validation failed ?
Not exactly. Maybe I should have chosen my wording better, I'll try
again: whenever there is something at request.input_values the form
assumes it is being redisplayed *because of* validation errors.
> That's not what happens
> in this case. What happens is that I have an onChange event handler on
> some select list, and when a user selects an element from it, it
> redirects to the same page/form but with some other elements filled
> in.
> So essentially the form is redisplayed (any values entered
> manually by the user should be preserved) but no validation has
> failed, up to this point at least.
I see, so, how are you sending the values that are already in the
form? Is it being submitted? In that case the proper way to do it
given the way it is designed should be:
do validate partial values
if fail:
redisplay form without passing any value since the uncoerced
input value will be left at req.input_values
by the validate decorator
if success:
redisplay form passing value to display since it is a coerced
python value
something like:
@validate(my_form)
def provide_intermediary_values(self, tg_errors=None, **data):
if not tg_errors:
value = data
value.update(some_other_data)
else:
value = None
return (form=my_form, value=value)
> Initially I was doing it all in
> Javascript, without any redirect, but it was messy and it essentially
> replicated the way TG fills in automatically a form given a model. Is
> there a better pattern for incrementally filling a form ?
I would do it client-side with javascript. In what sense was it messy?
Alberto
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---