Web2py [Ajax File Upload]

All about creating websites!
Post Reply
User avatar
maboroshi
Dr. Mab
Dr. Mab
Posts: 1624
Joined: 28 Aug 2005, 16:00
18

Web2py [Ajax File Upload]

Post by maboroshi »

This example provides a simple approach to a jquery ajax file upload with progress bar. After struggling with many different plugins for a couple days I finally found an approach that worked, this recipe is the result of that.

Image

First things first we need a database table

Code: Select all

db.define_table('music2',
    Field('song', 'upload'))
Next we need to add to our template the following

Code: Select all

<style>
<!--
form {display: block; background: #333; padding: 15px}

.progress {margin-left:auto; margin-right: auto; position:relative; width:400px; border: 1px solid #ddd; padding: 1px; border-radius: 3px;}
.bar {margin-left:auto; margin-right: auto;background-color: #B4F5B4; width:0%; height:20px; border-radius: 3px; }
.percent {position:absolute; display:inline-block; top:3px; left:48%;}
-->
</style>
 
{{include "web2py_ajax.html"}}

<script type="text/javascript" src="{{=URL('static', 'jquery.form.js')}}"></script> 
the style sheet code is for our progress bar feel free to tweak it as you like, remember this goes in to your web site template head section. We also include jquery (by including web2py_ajax) and our jquery.forms script

We now need to set up our controllers in default.py add the following

Code: Select all

@auth.requires_login()
def index():
    return dict()
    
@auth.requires_login()
def user_song_list():
    rows = db(db.music2.id>0).select()
    return dict(rows=rows)

@auth.requires_login()
def user_song_form():
    form = SQLFORM(db.music2)
    if form.accepts(request.vars):
       response.flash='Thanks for filling the form'
       #"%s",[],"song_list" is a reference to a div that gets called and updated 
       return XML('ajax("%s",[],"song_list");' % URL('default', 'user_song_list.load'))
    elif form.errors:
        response.flash='Fill the form correctly'
    else:
        response.flash='Please, fill the form'

    return dict(form=form)
Pretty common stuff that you see in most web2py the only thing I am going to mention is the return XML line in in the user_song_form function (read the comments and look at the index.html view to see what is meant by this

Now we will create our user_song_form.load file this is where the jquery code resides as well as our form.

Code: Select all

{{=form}}

    <div class="progress">
        <div class="bar"></div >
        <div class="percent">0%</div >
    </div>
    <div id="status"></div>


<script type='text/javascript'>
<!--  
jQuery('document').ready(function() {
    (function() {    
    var bar = $('.bar');
    var percent = $('.percent');
    var status = $('#status');   
        $('form').ajaxForm({
                dataType: 'script',
                url: "{{=URL('default', 'user_song_form')}}", 

             beforeSend: function() {
                status.empty();
                var percentVal = '0%';
                bar.width(percentVal)
                percent.html(percentVal);
            },
            uploadProgress: function(event, position, total, percentComplete) {
                var percentVal = percentComplete + '%';
                bar.width(percentVal)
                percent.html(percentVal);
            },
            complete: function(xhr) {
                status.html('Thank You Upload Complete!');
            }      
        });         
   })();
});      
-->
</script>
This next code is our user_song_list.load file

Code: Select all

{{for song in rows:}}

{{filename, file = db.music2.song.retrieve(song.song)}}
<a href="{{=URL('download', args=song.song)}}">  {{=filename}}</a>
<br /><br /> 
{{pass}}
Remember load files are created in the views section of web2py and you do not need to use extend "template.html" in them as they are being included by the LOAD function

Here is our index.html view look at this code in particular the 'song_list' div (remember it from our controller)

We also extend our template here

Code: Select all

{{extend "template.html"}}

<div id="song_list">
 {{=LOAD('default', 'user_song_list.load', ajax=False)}}
</div>


  <p>
    Upload a new song below!
  </p>
    {{=LOAD('default','user_song_form.load', ajax=False)}}
And that about sums up this example hope that explained a few things and I also hope it was easy to follow *cheers

Post Reply