Updating SELECTs with AJAX?

224 views
Skip to first unread message

scratchresistor

unread,
Jul 28, 2008, 3:44:49 PM7/28/08
to web2py Web Framework
HI All,

Got a bit of an AJAX problem that I've been wrestling with - could
anyone let me know a solution or at least that I'm heading in the
right direction?

I have two tables 'table_genus' and 'table_species' with
table_species.genus.requires = IS_IN_DB(db, table_genus).

What I want to do is display two SELECT dropdown boxes in a form and
have the second display the appropriate species automatically when the
user selects a genus in the first.

I'm working with fpp's YAAE (Yet Another Ajax Example) as the basis,
and have a simple controller like this:

def index():
genera = db().select(db.genus.ALL)
return dict(genera = genera)

def getspecies():
genus = request.vars.values()[0]
species = db(db.species.genus == genus).select()
return dict(species = species)

and a view like this:

{{extend 'layout.html'}}

<script type="text/javascript"><!--
function myajax(u,s,t) {
var query="";
for(i=0; i<s.length; i++) { if(i>0) query=query+"&";
query=query+encodeURIComponent(s[i])
+"="+encodeURIComponent(document.getElementById(s[i]).value);
}
$.ajax({type: "POST", url: u, data: query, success: function(msg)
{ document.getElementById(t).value=msg; } });
}

//--></script>

<table>
<tr>
{{=SELECT(_onChange="myajax({{=URL(r=request,f='getspecies')\}\},
['species'],'species');",*[OPTION(genera[i].name,
_value=str(genera[i].id)) for i in range(len(genera))])}}
</tr>
<tr>
{{try:}}
{{=SELECT(_id='species',*[OPTION(species[i].name,
_value=str(species[i].id)) for i in range(len(species))])}}
{{except:}}
{{=P('Failed')}}
{{pass}}
</tr>
</table>

Obviously there's some weirdness going on here already (having to
escape the curly brackets in the myajax call?!).

Somebody help!!

Thanks,

scratchresistor

Stuart Rackham

unread,
Jul 28, 2008, 5:50:11 PM7/28/08
to web...@googlegroups.com
scratchresistor wrote:
> HI All,
>
> Got a bit of an AJAX problem that I've been wrestling with - could
> anyone let me know a solution or at least that I'm heading in the
> right direction?
>
> I have two tables 'table_genus' and 'table_species' with
> table_species.genus.requires = IS_IN_DB(db, table_genus).
>
> What I want to do is display two SELECT dropdown boxes in a form and
> have the second display the appropriate species automatically when the
> user selects a genus in the first.
>
> I'm working with fpp's YAAE (Yet Another Ajax Example) as the basis,
> and have a simple controller like this:
>
> def index():
> genera = db().select(db.genus.ALL)
> return dict(genera = genera)
>
> def getspecies():
> genus = request.vars.values()[0]
> species = db(db.species.genus == genus).select()
> return dict(species = species)

You are returning a dictionary here which web2py renders as an HTML
table, you need to return a SELECT.

>
> and a view like this:
>
> {{extend 'layout.html'}}
>
> <script type="text/javascript"><!--
> function myajax(u,s,t) {
> var query="";
> for(i=0; i<s.length; i++) { if(i>0) query=query+"&";
> query=query+encodeURIComponent(s[i])
> +"="+encodeURIComponent(document.getElementById(s[i]).value);
> }
> $.ajax({type: "POST", url: u, data: query, success: function(msg)
> { document.getElementById(t).value=msg; } });

Should be:

{ document.getElementById(t).innerHTML=msg; } });


> }
>
> //--></script>
>
> <table>
> <tr>
> {{=SELECT(_onChange="myajax({{=URL(r=request,f='getspecies')\}\},
> ['species'],'species');",*[OPTION(genera[i].name,

Should be:

{{=SELECT(_onChange="myajax('"+URL(r=request,f='getspecies')+"',


> _value=str(genera[i].id)) for i in range(len(genera))])}}
> </tr>
> <tr>


Your myajax call is trying to inject the select into itself, you need to
inject into the parent element:

<div id="target">

> {{try:}}
> {{=SELECT(_id='species',*[OPTION(species[i].name,
> _value=str(species[i].id)) for i in range(len(species))])}}
> {{except:}}
> {{=P('Failed')}}
> {{pass}}

<div>


Cheers, Stuart

scratchresistor

unread,
Jul 29, 2008, 4:14:26 AM7/29/08
to web2py Web Framework
Many thanks Stuart, I'll have a go at this...

scratchresistor

unread,
Jul 29, 2008, 3:21:50 PM7/29/08
to web2py Web Framework
Just for anyone else interested in doing this, here's my final code...

<< default.py >>

def index():
genera = db().select(db.table_genus.ALL)
return dict(genera = genera)

def getspecies():
genus = request.vars.values()[0]
species = db(db.table_species.genus == genus).select()
return SELECT(_id='species',*[OPTION(species[i].name,
_value=str(species[i].id)) for i in range(len(species))])

<<index.html>>

{{=SELECT( _id='genus',
_onChange="ajax('"+URL(r=request,f='getspecies')+"',
['genus'], 'target');",
*[OPTION(genera[i].name,_value=str(genera[i].id)) for i in
range(len(genera))]
)}}

<div id="target"></div>

Tito Garrido

unread,
Jul 29, 2008, 3:55:30 PM7/29/08
to web...@googlegroups.com
Thanks!
--
Linux User #387870
.........____
.... _/_õ|__|
..º[ .-.___.-._| . . . .
.__( o)__( o).:_______
Reply all
Reply to author
Forward
0 new messages