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