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
@dalf
I need more info to help.
Check if you don't have some javascript conflicting packages. The order of javascript loading is important. Start to test with only the minimal requirements then try to add the remaining.
doesn't work for me
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.
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(...)?
show more comments0
michelecomitini 12 years ago
0
aleksdj 12 years ago
0
ranjeevhs 13 years ago
0
richard 13 years ago
0
richard 13 years ago