Uploading Files With Ajax
Download the jQuery plugin from jquery.form.js into static folder
put this above at the very beginning, first line, of your .html file or in the header of layout.html
{{response.files.append(URL(r=request,c='static',f='jquery.form.v2.43.js'))}}
Create forms as usual (see: web2py book) and just add the following somewhere:
<script type='text/javascript'>
//<!--
jQuery('document').ready(function() {
jQuery('form').ajaxForm({dataType: 'script', // <-- like the ':eval' target in ajax() function
url: "{{=URL('user_picture_form')}}" // <-- put form controller action here
});
});
//-->
</script>
Read documentation: jQuery.form home page
Example Application
This application allows users (without authentication) associate images to registered users. And updates the list by ajax without reloading the entire page after each submission.
The model:
db.define_table('user_pictures',
Field('user', db.auth_user, unique=True, represent=lambda id: '%s %s ' %( db.auth_user(id).first_name, db.auth_user(id).last_name)),
Field('picture', 'upload', requires=IS_IMAGE()))
db.user_pictures.user.requires=IS_IN_DB(db,'auth_user.id', '%(first_name)s %(last_name)s', zero=T('choose one'))
Add 2 action to default.py controller:
def user_picture_list():
rows = db(db.user_pictures.id>0).select()
return dict(rows=rows)
def user_picture_form():
form = SQLFORM(db.user_pictures)
if form.accepts(request.vars):
response.flash='Thanks for filling the form'
return XML('ajax("%s",[],"pic_list");' % URL('user_picture_list.load'))
elif form.errors:
response.flash='Fill the form correctly'
else:
response.flash='Please, fill the form'
return dict(form=form)
The full index.html:
{{response.files.append(URL(r=request,c='static',f='jquery.form.v2.43.js'))}}
{{extend 'layout.html'}}
<h1>{{=T("Change the user's image!")}}</h1>
<div class='ez-wr'>
<p>
This is the list: it will be updated when you submit a new image.
</p>
<div class='ez-box' id='pic_list'>
{{=LOAD('default', 'user_picture_list.load', ajax=False)}}
</div>
</div>
<div class='ez-wr'>
<p>
Upload a new image below!
</p>
<div class='ez-box'>
{{=LOAD('default','user_picture_form.load', ajax=False)}}
</div>
</div>
user_picture_list.load:
<div class='ez-wr'>
{{for r in rows:}}
<div class="ez-wr">
<div class="ez-fl ez-negmr ez-50">
{{user = db.auth_user(r.user)}}
{{="%s %s" % (user.first_name,user.last_name)}}
</div>
<div class="ez-last ez-oh">
{{=IMG(_src=URL(f='download',args=[r.picture]))}}
</div>
</div>
{{pass}}
</div>
user_picture_form.load:
{{=form}}
<script type='text/javascript'>
//<!--
jQuery('document').ready(function() {
jQuery('form').ajaxForm({dataType: 'script',
url: "{{=URL('user_picture_form')}}"
});
});
//-->
</script>
Comments (7)
- Login to post
order by: newest oldest upvoted downvoted
Good example....
Very tasty slice, Michele. Thanks. However, two issues came up. First, after submitting the form, the component isn't getting updated so I still see the input. This leads to multiple submission problems. The other issue is more of a question -- why did you use return XML('ajax...') instead of providing a success function to the ajaxForm function?
I'm also curious about the jQuery('form').ajaxForm(...) statement. Shouldn't it be jQuery('#form').ajaxForm(...)?
OK, I think I got it: the jQuery('form').ajaxForm(...) should probably look like this:
The target will update the input form after submission.
First of all this is a nice slice. Got it to work but the response.flash or even session.flash doesn.t work upon upload.
show more comments0
ariel 13 years ago
0
richard 13 years ago
0
richard 13 years ago
0
richard 13 years ago
0
ranjeevhs 13 years ago