Steve Bergman schrieb:
> I'm trying to find the most straightforward way to accomplish this task
> and I'm not sure what it is.
> 
> I have a form with a bunch of fields.  But in particular, I have a
> SingleSelectField 'Client', and the 'options'  for SingleSelectField
> 'Projects' depends upon what is selected in 'Client'.
> 
> The best I have come up with is to make an asynchronous request
> "onchange" when the client is selected, the results of which (the html
> of the Projects widget) then gets put into a <div></div> target by
> innerHTML.
> 
> This means that I have to define the whole form using
> display_field_for() rather than using the more convenient TableForm,
> since I don't know how to embed my <div></div> target within a
> TableForm.
> 
> I'd like to use AjaxForm, but it requires that you specify the "action"
> to be the asynchronous request, and I want the form to submit, in the
> normal, synchrounous way,  to its "save" method, and for the
> asynchronous request to occur only when 'Client' changes.
> 
> I imagine I'm missing something simple, and any hints would be
> appreciated.

I'm not sure what you want to do with <div>s here - from what I 
understand, you want to change one selects options based upon the change 
of another one. So you need to create option-tags here, not divs. Render 
the projects select as part of the form

I'm not aware that TG offers such a thing out of the box - and given the 
bazillion possibilities to realize it, I don't consider that a major 
flaw. After all, we're programming here :)

Here is what I'd do:

  - create a controller that will return projects for a given client-id.


@expose(format='json')
@validate(validators={
      'client_id' : validators.Int(not_empty)
})
def get_projects(self, client_id=None, tg_errors=None):
     return dict(projects=model.Client.get(client_id).projects)


  - create a form, with both client and projects field

myform = widgets.TableForm('myform',
       fields=[widgets.SingleSelectField('client_id', 
options=[(client.id, client.name) for client in model.Client.select()],
default=Client.byName('TheClientToStartWith').id
),
widgets.SingleSelectField('projects', options=[(p.id, p.name) for p in 
Client.byName('TheClientToStartWith').projects])]

)



  - connect the 'onchange' event of the client_id select to a piece of 
javascript by putting this in your template. Make sure you have mochikit 
available!

<script>
var conn = MochiKit.Signal.connect;

function init_client_selector(event) {
     var client_id = event.target().value;
     var def = doSimpleXMLHttpRequest('/path/to/get_projects', 
{client_id : client_id});
     def.addCallback(function(req) {
         var projects = evalJSONRequest(req).projects;
         var projects_select = 
currentDocument().forms['myform'].elements['projects'];
        replaceChildNodes(projects_select,
                  map(function(project) {
                       return OPTION({value : project.id}, project.name);
                  }, projects));
         });
}



function init_client_selector() {
     conn(currentDocument().forms['myform'].elements['client_id'], 
'onchange', client_id_changed);
};
conn(window, 'onload', init_client_selector);

</script>


This is all untested and most probably contains several errors  - but it 
will hopefully give you the right idea!

Diez

--~--~---------~--~----~------------~-------~--~----~
 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to