run python code from onclick event

1,399 views
Skip to first unread message

murray3

unread,
Aug 24, 2009, 7:31:21 AM8/24/09
to web2py-users
is there a way to run some python db.update code in a view by using
the onclick event from the checkbox.
At present the python code just runs, I put the "checker" in there to
try and toggle it off until the onclick event obviously does not run
the python code as is.
help appreciated
chrism

<table width="100%" cellpadding="1" cellspacing="0" border="0"
class="display" id="example">
<thead>
<tr>
<th>Part Name</th><th>Content</th><th>Number</th><th>Created On</
th>
</tr>
</thead>
<tfoot>
<tr>
<th>Part Name</th><th>Content</th><th>Number</th><th>Created On</
th>
</tr>
</tfoot>
<tbody>
{{for part in parts:}}
{{checker=0}}
<tr>
<td>{{=part.part_name}}</td>
<td>{{=part.part_content}}</td>
<td>{{=part.part_number}}</td>
<td>{{=part.timestamp.year}}</td>
<td class="center"><input type="checkbox" name="check_"
value="{{part.id}}" onclick="{{if not checker==0:}}
{{=db.prodj_refs.insert(prodj_id=prodj.id,part_id=part.id)}}
{{pass}}"></td>
</tr>
{{pass}}
{{checker=1}}
{{pass}}
</tbody>
</table>

Iceberg

unread,
Aug 24, 2009, 7:48:18 AM8/24/09
to web2py-users
No, you can't do this. All the {{python code}} are executed BEFORE the
final pure html page is served to the browser. In other words, you
need to feed pure javascript for the onclick event.

Tips: Use "View->Source" of your browser to know what is actually fed
to the browser. Then you will get the idea.

Yours,
Iceberg

mdipierro

unread,
Aug 24, 2009, 8:01:17 AM8/24/09
to web2py-users
You can but not this way.

You need the onlick to perform an ajax request.

This requires a new controller action:

def check():
part_id=request.args(1)
if not db((db.prodj_refs.prodj_id=request.args(0))& \
(db.prodj_refs.part_id=part_id)).delete()
return 'jQuery('#selector%i' % part_id).html('not
selected')
else:
db.prodj_refs.insert(prodj_id=request.args
(0),part_id=part_id)
return 'jQuery('#selector%i' % part_id).html('selected')

and a view that calls the action via onclick and gets a response that
modified the page accordingly:

<table width="100%" cellpadding="1" cellspacing="0" border="0"
class="display" id="example">
<thead>
<tr>
<th>Part Name</th><th>Content</th><th>Number</
th><th>Created On</
th>
</tr>
</thead>
<tfoot>
<tr>
<th>Part Name</th><th>Content</th><th>Number</
th><th>Created On</
th>
</tr>
</tfoot>
<tbody>
{{for part in parts:}}
<tr>
<td>{{=part.part_name}}</td>
<td>{{=part.part_content}}</td>
<td>{{=part.part_number}}</td>
<td>{{=part.timestamp.year}}</td>
<td>
<button id="selector{{=part.id}}"
onclick="{{=URL(r=request,f='check',args=
[prodj.id,part.id])}}">
{{if db((db.prodj_refs.prodj_id=request.args
(0))&(db.prodj_refs.part_id=part_id)).count():}}selected{{else:}}not
selected{{pass}}
</button>
</td>
</tr>
{{pass}}
</tbody>
</table>

murray3

unread,
Aug 25, 2009, 8:17:49 AM8/25/09
to web2py-users
Guy's thanks for your help yesterday.
Massimo, I am developing for app engine so the "&" selects do not work
and I had to modify '=' to '==' in a couple of places to get the view
to load without GAE errors.
It is still not quite working, I nested 'if's' for GAE selects perhaps
you will see what needs amending?
thanks chrism

in contoller I have:

def check():
part_id=request.args(1)
prodj_parts_list=db(db.prodj_refs.prodj_id==request.args(0)).select
()
for p in prodj_parts_list:
if not db(db.prodj_parts.id==p.part_id).delete():
return 'jQuery('#selector%i' % part_id).html('not selected')
else:
db.prodj_refs.insert(prodj_id=request.args(0),part_id=part_id)
return 'jQuery('#selector%i' % part_id).html('selected')



and in view:
<table width="100%" cellpadding="1" cellspacing="0" border="0"
class="display" id="example">
<thead>
<tr>
<th>Part Name</th><th>Content</th><th>Number</th><th>Created On</
th>
</tr>
</thead>
<tfoot>
<tr>
<th>Part Name</th><th>Content</th><th>Number</th><th>Created On</
th>
</tr>
</tfoot>
<tbody>
{{for part in parts:}}
<tr>
<td>{{=part.part_name}}</td>
<td>{{=part.part_content}}</td>
<td>{{=part.part_number}}</td>
<td>{{=part.timestamp.year}}</td>
<td><input type="checkbox" id="selector{{=part.id}}"
onclick="{{=URL(r=request,f='check',args=
[prodj.id,part.id])}}">
{{if db((db.prodj_refs.prodj_id==request.args
(0))&(db.prodj_refs.part_id==part.id)).count():}}selected{{else:}}not
selected{{pass}}
</input> </td>
</tr>
{{pass}}
</tbody>
</table>

mdipierro

unread,
Aug 25, 2009, 8:25:12 AM8/25/09
to web2py-users
1) you changed the check() action from my example. I do not understand
what it does anymore. I thought it would remove or add a single part
but now it has a loop. why?
2) did you try calling the check/[prod_id]/[part_id] action without
ajax? That will give you a ticket that helps debugging.
3) You my div with a input checkbox. Input does not have a </input>.
4) The code

{{if db((db.prodj_refs.prodj_id==request.args
(0))&(db.prodj_refs.part_id==part.id)).count():}}selected{{else:}}not
selected{{pass}}

does not belong there anymore (becase input has no content). I guess
you want

<input type="checkbox" id="selector{{=part.id}}"
onchange="{{=URL(r=request,f='check',args=
[prodj.id,part.id])}}"
{{if db((db.prodj_refs.prodj_id==request.args
(0))&(db.prodj_refs.part_id==part.id)).count():}}
checked="checked"{{else:}}not
selected{{pass}} />

7) When you change 6) you wil also need to change the jquery commands
returned by the check() action.

murray3

unread,
Aug 25, 2009, 9:43:24 AM8/25/09
to web2py-users
Hi,
I was trying to get it to work without the syntax errors, I changed
back to your controller code and get the following error:
INFO 2009-08-25 13:31:35,296 dev_appserver.py] "GET /fab3/default/
m230/8?keepThi
" 500 -
INFO 2009-08-25 13:32:09,000 dev_appserver.py] "GET /fab3/default/
g/action-close
00 -
ERROR 2009-08-25 13:32:09,250 restricted.py] In FILE: Framework

Traceback (most recent call last):
File "c:\apps\web2py\gluon\main.py", line 381, in wsgibase
serve_controller(request, response, session)
File "c:\apps\web2py\gluon\main.py", line 157, in serve_controller
run_controller_in(request.controller, request.function,
environment)
File "c:\apps\web2py\gluon\compileapp.py", line 277, in
run_controller_in
code = getcfs(layer, filename, lambda : \
File "c:\apps\web2py\gluon\compileapp.py", line 104, in getcfs
data = filter()
File "c:\apps\web2py\gluon\compileapp.py", line 279, in <lambda>
'exec'))
File "c:\apps\web2py\applications\fab3/controllers/default.py:m230",
line 218
(db.prodj_refs.part_id==part_id)).delete()

^
SyntaxError: invalid syntax

chrism

mdipierro

unread,
Aug 25, 2009, 11:10:42 AM8/25/09
to web2py-users
def check():
part_id=request.args(1)
if not db((db.prodj_refs.prodj_id==request.args(0))& \
(db.prodj_refs.part_id==part_id)).delete()
return 'jQuery('#selector%i' % part_id).html('not
selected')
else:
db.prodj_refs.insert(prodj_id=request.args
(0),part_id=part_id)
return 'jQuery('#selector%i' % part_id).html('selected')

murray3

unread,
Aug 25, 2009, 8:29:56 PM8/25/09
to web2py-users
Ok I have a better understanding (i read a jquery ajax tutorial) of
what you where trying to do in your first reply. I have amended "=" to
"==" and added ":" in the "if not" statement which where missing and
caused syntax errors.
The problem is that in the view: onclick="{{=URL
(r=request,f='check',args= [prodj.id,part.id])}}"
does not do anything? the GAE command line does not show output when I
click the buttons so the action is not working.
I am running this code through jpolite v1 not sure if that is causing
the problem? although this particular view is loaded through thickbox
so should be outside jpolite.
chrism

murray3

unread,
Aug 26, 2009, 6:13:12 PM8/26/09
to web2py-users

murray3

unread,
Aug 27, 2009, 7:58:17 AM8/27/09
to web2py-users
any further help appreciated with this, as I am stuck??

just need to get the contoller action running from an onclick event in
the view, at present nothing happens and I'm not sure if it is jpolite
or just using the wrong code?
regards chrism
Reply all
Reply to author
Forward
0 new messages