Hi Matt,

Thanks for getting back. Things have changed somewhat (since I am now
computing options in the action and passing computed options to the
template). It seemed easier/cleaner to handle it that way.

In my actual scenario I have selection fields that depend on other
selection fields - sort of like in a hierarchical fashion.

i.e. C depends on B which in turn depends on A , etc.  So in this case
if the selection in A changes it will trigger an update to the
available selections in B which in turn requires C to be updated, etc.

However to facilitate this discussion, let me try to explain in simple
terms what is going on.

So say you have a simple form with 2 single select fields A and B and
text area C (whose validator requires an entry - i.e. not empty
option)

Select field A has 2 options as follows :-
<option value="1">1</option><option value="2">2</option>

Select field B's selection options are dependent on which option is
selected in A.

e.g.

when A is 1

B displays

<option value="3">3</option><option value="4">4</option>

when A is 2

B displays

<option value="5">5</option><option value="6">6</option>

Now lets assume for the purposes of this discussion that the form
displays with A having 1 selected and B having 3 selected (out of
optioins 3 and 4 initially displayed for B), C is empty.

Then the user does the following :-

1. changes A's selection to 2 (this triggers an ajax update to B's
options - changing the available options to 5 and 6)
2. Selects 6 on B
3. Makes no entry in text field C and attempts to submit the form.

This causes a validation failure and when @validate kicks in the form
will be redisplayed, however the proper context of the options should
be to show B's options based on B's current selections and available
options as at when validation failed. i.e.

B should display

<option value="5">5</option><option value="6">6</option>

with 6 selected.

Since B's options need to be computed dynamically this will only
happen if the edit action is passed the current available options for
B.

So the long and short of the whole story is that in order to compute
B's options the edit action calls a function passing it the current A
selection (which is 2).

So my original question was since the 2nd call to edit (which is made
in order to provide htmlfill with the html for filling current values
and error) is not an http get how can you access the current A
selection in the edit action in order to build B's select options
correctly.

I am probably going about it the wrong way since I dont know any
better currently. However, something like this is what I had to resort
to doing :-



def edit(self)
  def b_options(cur_a=1):
      if (cur_a == 1):
         return [(3,'3'),(4,'4')]
      else:
         return [(5,'5'),(6,'6')]
  ........
  if request.environ.has_key('webob._parsed_post_vars'): # there was a
validation error
    params = dict(request.environ.get('webob._parsed_post_vars')[0])
    cur_a=int(params.get('a'))
  else: # first time displaying the form
    cur_a = 1
.......
    c.b_options= boptions(cur_a)

  return htmlfill.render(render('edit.html'), values)

then somewhere in edit.html where the select field for b is
constructed

<td>${h.select('b', selected_values=[], options=c.boptions)}</td>

I hope my question is now clearer.

Please let me know if there are any further ambiguities.

I will respond to the other responses as soon as I read and understand
them.

thanks your answers are in fact very clear. I appreciate the effort
you have made to communicate your response in the light of the
apparent ambiguity in my questions.

PS: Yes. I dont know if that is exactly what you mean but I dont want
the save method to be called with a get request - there may be a lot
more data than can be handled by a get request - hence I am
restricting it to only posts. I will look into doing the restriction
in @validate as you have suggested.

PS2: I watched the HTTP requests using the firefox Live HTTP Headers
and discovered that the 2nd call to get does not appear to be a HTTP
request. However edit was indeed called a second time to generate the
form - I saw this in the logger messages generated for edit. Should
this indeed have been a full HTTP request.?

I will go over all this again and make sure that I have been doing
things right providing an update as required. I will also respond to
the other responses by Mike Orr. Thanks

On Jun 26, 1:23 pm, Matt Feifarek <[email protected]> wrote:
> On Wed, Jun 24, 2009 at 11:08 AM, afrotypa <[email protected]> wrote:
>
> > @restrict('POST')
> > @validate(schema=TestSchema(), form='edit', post_only=False,
> > on_get=True)
> > def save(self, id=None):
>
> I'm not following your full question, but right-off, I see a contradiction
> up there:
> If you restrict that action to only POST, then give on_get=True to validate,
> you'll never do a GET on save... maybe this is what you want? As you might
> expect, you can use @validate to already discriminate by HTTP method
> (post_only). At best, this is redundant. At worst, it might not be behaving
> as you had hoped.
>
> As far as your actual question goes, it seems like you want to change the
> displayed form as a result of how/whether the form was posted. A little
> weird, but sure, it's possible, if you go low-enough level. You may not be
> able to use stock @validate for that; you may have to write the logic
> yourself; you can still use htmlfill and TestSchema and so on, but the
> decision tree will have to be up to you so you can mess with the form while
> you process it. If you look at the code for @validate, you might be able to
> rip some of that off.
>
> Also, I don't think that FormEncode will mess with a form's option tags
> (other than to set which one is "selected"). Remember that the form itself
> is just text/string... Formencode eats the POST and modifies the
> string/template of 'edit' if there are errors. It doesn't generate the form,
> or otherwise see it as any kind of higher level structure... so it can't
> make new option tags for you. YOU could change the string before you send it
> into htmlfill, of course.
>
> The request parameters should be available in any case; it's still a
> request, even if @validate has chewed on it. Try running your request
> through a debugger, or throwing in an exception and poking around in the
> live error message thrown. You should still see params.
>
> I hope this helps; perhaps because I don't really understand your question,
> I am not giving comprehensible answer(s).
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" 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/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to