[Grok-dev] Simple AJAX question

Martijn Faassen faassen at startifact.com
Wed Jan 6 19:08:35 EST 2010


Hey,

I had a bit more time looking things up.

Hannes wrote:
> I'm beginner with Zope and Grok and I've the following problems:

First a general bit of advice:

complex forms with lots of javascript interactions and autogenerated 
forms don't always play well together. You can always consider creating 
the form by hand.

I'm only give clues about the following two, as solving the complete 
problem would take me some time. I think it would be very useful if 
someone (you?) wrote a tutorial about this describing a complete 
solution that we can place on grok.zope.org. Feel free to ask more 
questions if you get stuck.

> 1.) I've two schema.Choice fields that somehow depend on each other. The 
> list of values that should be displayed in field2 depends on the entry 
> selected in field1. As far as I understand AJAX, I've to send a request 
> back to the server to load the list for field2, when the user selected a 
> item from field1. Is that right? How do I do it?

With Javascript you'd need to hook up to the event for field1 that gets 
sent when you alter field1. You can do this externally in a script tag 
on the page or in javascript page that gets loaded with the page (use 
the ready pattern below to make sure the event only gets hooked up when 
the page with the form is ready). With JQuery, I think something like this:

$(document).ready(function() {
    $('#form.field1').change(function(e) {
      ...
    });
});

Inside the event handler you could modify the second field and fill it 
with options:

   var field2 = $('#form.field2')
   field2.options.length = 0
   field2.options[0] = new Option("Seen", "submitted")
   field2.options[1] = ..

a library like this might make this easier: 
http://www.texotela.co.uk/code/jquery/select/

for more help and snippets google for "jquery select" or something like 
that.

We need to also retrieve the option values from the server. You could do 
that with JSON. On the server:

class MyJSON(grok.JSON):
     grok.context(TheContextOfTheForm)

     def field2_options(self):
           return [
              dict(title="The Title", value="The value"),
           ]

(you could fill this using the source. see below)

then in your javascript you could retrieve the options from the server 
like this (assuming jquery again):

   $.getJSON('field2_options'), function(data) {
     $(data).each(function(i, entry) {
        // fill options with entry.title and entry.value here
     });
   });

Choices are populated from sources. For sources it's useful to consider 
the zc.sourcefactory library:

http://pypi.python.org/pypi/zc.sourcefactory

Of course that library is complete but also totally overwhelming. I 
think you need to look in the area of a contextual source in this case. 
This doesn't help you on the server side, but you do need to explain to 
the server side to only accept "foo" in field2 if field1 contains "bar", 
otherwise you will get a validation error, and you can do that with 
contextual sources.

> 2.) Even simpler: Again, I've a schema.Choice field and a "normal" text 
> field. Now I just want to display the selected item from the Choice 
> field in the text field. How do I do that?

You'd again hook up to the 'change' event in Javascript as indicated 
above. You'd then write something like:

   $('#form.textfield').val($('#form.field1.').val());

jquery is a library that makes this stuff really compact and easy. I 
just learned a few tricks looking this up. I might of course get some of 
this wrong, but hopefully this will get you started.

Good luck!

Regards,

Martijn



More information about the Grok-dev mailing list