Suggestions for multiple files upload in form

2,937 views
Skip to first unread message

Paolo Caruccio

unread,
Oct 27, 2011, 8:40:12 PM10/27/11
to web...@googlegroups.com
I wasn't able to find in the web, even in this group, a multiple files upload system with the followings requirements:

- upload the files together with form submit
- no frame, no flash, no ajax form submit but only jquery and python
- give a title to the uploading files
- simple to integrate and control in web2py 

It's minimalist and the code isn't optimized (I'm not a programmer), but it works for my purposes.

If you would like to test it in default welcome web2py app:
 - put jquery.multiuploads.js in static/js folder
 - put multiuploads.css in static/css folder
 - append the functions to default.py in controllers folder
 - append the table definition to db.py in models folder
 - put upload_documents.html in views folder

You'll find some comments in the code and also many errors.

I look forward to your suggestions and opinions.

Ciao.

Paolo
jquery.multiuploads.js
multiuploads.css
functions.py
table_definition.py
upload_documents.html
result.png

Bruno Rocha

unread,
Oct 27, 2011, 8:49:50 PM10/27/11
to web...@googlegroups.com


Thanks for this, I am using another jquery library for upload and I am going o test this.

Can you provide a packed .w2p web2py application?
--

Ovidio Marinho

unread,
Oct 27, 2011, 11:06:48 PM10/27/11
to web...@googlegroups.com

      I got was this, it seems not to be carrying it. js

http://www.diigo.com/item/image/1iw09/9pki


       Ovidio Marinho Falcao Neto
                Web Developer
             ovid...@gmail.com 
          ovidio...@itjp.net.br
                 ITJP - itjp.net.br
               83   8826 9088 - Oi
               83   9334 0266 - Claro
                        Brasil



2011/10/27 Bruno Rocha <rocha...@gmail.com>

Ovidio Marinho

unread,
Oct 28, 2011, 8:49:31 AM10/28/11
to web...@googlegroups.com

      I managed to implement this test, the input files is interesting, but the display would be better to use PowerGrid.

Input Files:

save image



       Ovidio Marinho Falcao Neto
                Web Developer
             ovid...@gmail.com 
          ovidio...@itjp.net.br
                 ITJP - itjp.net.br
               83   8826 9088 - Oi
               83   9334 0266 - Claro
                        Brasil



2011/10/27 Paolo Caruccio <paolo.ca...@gmail.com>

Paolo Caruccio

unread,
Oct 28, 2011, 9:56:58 AM10/28/11
to web...@googlegroups.com
Ovidio thank you for your consideration.

In fact, I have not given much attention to the results grid because the goal of my work was to create a control for uploading multiple files.
In addition, the visual aspect is only demonstration. The essential css rules are on the top of multiuploads.css (before /* CUSTOMIZATION */ comment).
However, I am preparing a packed .w2p web2py small application as required by Bruno.
Maybe, there you will see something nicer.

Ciao.

Paolo

Paolo Caruccio

unread,
Oct 29, 2011, 5:20:19 PM10/29/11
to web...@googlegroups.com
Bruno,

I'm sorry for late reply.

I look forward to your opinion.

Thank you.

Ciao.

Paolo
web2py.app.multiuploads.w2p

Bruno Rocha

unread,
Oct 29, 2011, 5:48:52 PM10/29/11
to web...@googlegroups.com
Thank you Paolo, very nice app.

Paolo Caruccio

unread,
Oct 29, 2011, 6:21:27 PM10/29/11
to web...@googlegroups.com
Bruno,

thanks.

What do you think about the upload mechanism? Can it be translate in a web2py widget? or is it better to use a different javascript/jquery library?

Regards.

Paolo

Richard Vézina

unread,
May 30, 2012, 10:15:09 AM5/30/12
to web...@googlegroups.com
Hello Paolo,

Pretty nice!

Did you implement the update of the records also?

Is it a straight and easy task or it becomes trickier to implement than the rest of the app??

Richard

Paolo Caruccio

unread,
May 30, 2012, 6:23:29 PM5/30/12
to web...@googlegroups.com
Richard,

I saw your email in the discussion regarding bootswatch, but I want to answer here for competence.

Multiupload is a my old project. The object of the toy app was demonstrate the usage of multiupload control. It wasn't a complete application.

Your intentions, however, are interesting. I will take a look at your code and I will try to find a solution.

Richard Vézina

unread,
May 31, 2012, 12:09:20 PM5/31/12
to web...@googlegroups.com
Hello Paolo,

Here some fresher code :

def trip_update():
    # only SQLFORM.factory tested
    form=SQLFORM.factory(db.t_trip, db.t_photos)
    for row in db(db.t_trip.id == request.args(0)).select(db.t_trip.ALL):
        for f in db.t_trip.fields:
            form.vars[f]=row[f]
    photos_files = []
    for row in db(db.t_photos.f_trip_ref == request.args(0)).select(db.t_photos.ALL):
        #for f in db.t_photos.fields:
        #f_photo_0:CONTENT_OF_f_title
        #form.vars['f_photo_'+str(i)+':'+row.f_title]=row
        #LI(_title='couleurs (1).png', A('x', _href='javascript:void(0);', _class='mw_delItem', _title='remove this file'), I(B(EM(_class='mw_file-ext-png'))), SPAN('test1'))
        photos_files.append(XML(LI(A('x', _href='javascript:void(0);', _class='mw_delItem', _title='remove this file'), EM(_class='mw_file-ext-png'), SPAN(row.f_title), _title=row.f_photo)))
    response.js="""var photos_files_list = "{{=photos_files}}"
    $(document).ready( function () {
        if(photos_files_list != 'None') {
            $.each(photos_files_list, function(i, val) {
                $('ul.mw_list').append(photos_files_list[i]);
            });
        };
    });"""
        #A(T('Access'),_href=URL(r=request,f='read',args=(request.args(0),str(id))))

        #<li title="couleurs (1).png"><a class="mw_delItem" href="javascript:void(0);" title="remove this file">x</a><i><b><em class="mw_file-ext-png"></em></b></i><span>test1</span></li>
    if form.accepts(request, session, onvalidation=lambda form:check(form)): # Is it possible to use onvalidation with form.process() syntax ?
        trip_id = db.t_trip.update_record(**db.t_trip._filter_fields(form.vars))
        nfiles = 0
        for var in request.vars:
            if var.startswith('f_photo') and request.vars[var] != '':
                uploaded = request.vars[var]
                if isinstance(uploaded,list):
                    # files uploaded through input with "multiple" attribute set on true
                    counter=0
                    for element in uploaded:
                        counter += 1
                        nfiles += 1
                        file_title = element.name.split(":")[-1] # TODO: could this be made better?
                                                                 # I mean, the title must be appended to element's name
                                                                 # or is there another way?
                        db.t_photos.insert(
                            f_trip_ref=trip_id,
                            f_title=file_title+" ("+str(counter)+")" if file_title!="" else file_title,
                            f_photo=db.t_photos.f_photo.store(element.file,element.filename))
                else:
                    # only one file uploaded
                    element = request.vars[var]
                    nfiles += 1
                    db.t_photos.insert(
                        f_trip_ref=trip_id,
                        f_title=element.name.split(":")[-1],
                        f_photo=db.t_photos.f_photo.store(element.file,element.filename))

        session.flash = T('%s photo%s uploaded'%(nfiles, 's' if nfiles>1 else ''))
        redirect(URL('trip_read'))

    if isinstance(form,FORM):
        # hide f_title form's row. Is there a better way to accomplish it?
        del form[0][3]

    return dict(form=form)

Richard Vézina

unread,
May 31, 2012, 12:25:14 PM5/31/12
to web...@googlegroups.com
response.js will not works, it only works on response and for component as says the book.

Putting the js code into the view seems to work if I pass the photos_files var to the view...

Now I think I just have to find the way to expose the HTML, XML() not seems to work.

Richard

Richard Vézina

unread,
May 31, 2012, 1:35:02 PM5/31/12
to web...@googlegroups.com
Here where I get as now :

Controler :
def trip_update():
    # only SQLFORM.factory tested
    form=SQLFORM.factory(db.t_trip, db.t_photos)
    for row in db(db.t_trip.id == request.args(0)).select(db.t_trip.ALL):
        for f in db.t_trip.fields:
            form.vars[f]=row[f]
    photos_files = []
    for row in db(db.t_photos.f_trip_ref == request.args(0)).select(db.t_photos.ALL):
        #for f in db.t_photos.fields:
        #f_photo_0:CONTENT_OF_f_title
        #form.vars['f_photo_'+str(i)+':'+row.f_title]=row
        #LI(_title='couleurs (1).png', A('x', _href='javascript:void(0);', _class='mw_delItem', _title='remove this file'), I(B(EM(_class='mw_file-ext-png'))), SPAN('test1'))
        photos_files.append(XML(LI(A('x', _href='javascript:void(0);', _class='mw_delItem', _title='remove this file'), EM(_class='mw_file-ext-png'), SPAN(row.f_title), _title=row.f_photo)).xml())
#    response.js="""var photos_files_list = "{{=photos_files}}"
#    $(document).ready( function () {
#        if(photos_files_list != 'None') {
#            $.each(photos_files_list, function(i, val) {
#                $('ul.mw_list').append(photos_files_list[i]);
#            });
#        };
#    });"""
    #response.js="""var photos_files_list = "{{=photos_files}}" $(document).ready( function () {if(photos_files_list != 'None') {$.each(photos_files_list, function(i, val) {$('ul.mw_list').append(photos_files_list[i]);});};});"""
        #A(T('Access'),_href=URL(r=request,f='read',args=(request.args(0),str(id))))

        #<li title="couleurs (1).png"><a class="mw_delItem" href="javascript:void(0);" title="remove this file">x</a><i><b><em class="mw_file-ext-png"></em></b></i><span>test1</span></li>
    if form.accepts(request, session, onvalidation=lambda form:check(form)): # Is it possible to use onvalidation with form.process() syntax ?
        trip_id = request.args(0)
        db(db.t_trip.id == trip_id).update(**db.t_trip._filter_fields(form.vars))
    return dict(form=form, photos_files=photos_files)

View :

{{response.files.extend([URL('static','css/multiupload.css'),URL('static','js/jquery.multiupload.js')])}}
{{left_sidebar_enabled=right_sidebar_enabled=False}}
{{extend 'layout.html'}}
<div>
{{=form}}
<ul>{{=photos_files[0]}}</ul>
<script type="text/javascript" charset="utf-8">
//<!--
jQuery('input[name="f_photo"]:not(.processed)').multiUpload({
    mw_placeholder:"{{=T('insert a title')}}",
    mw_text_addBtn:"+",
    mw_tooltip_addBtn:"{{=T('add a file')}}",
    mw_text_clearBtn:"x",
    mw_tooltip_clearBtn:"{{=T('remove all')}}",
    mw_tooltip_removeFileBtn:"{{=T('remove this file')}}",
    mw_tooltip_removeGroupBtn:"{{=T('remove this file group')}}",
    mw_group_title:"{{=T('FILE GROUP')}}",
    mw_fileNumber:false,
    mw_maxElementAllowed:5
});
//-->
</script>
</div>

<script type="text/javascript" charset="utf-8">
    var photos_files_list = {{=photos_files}}
    $(document).ready( function () {
        if(photos_files_list != 'None') {
            $.each(photos_files_list, function(i, val) {
                $('ul.mw_list').append(val); //photos_files_list[i]
            });
        };
    });
</script>

{{if request.is_local:}}
{{=response.toolbar()}}
{{pass}}


Problem : the items are not showing up in the UL box, because a conversion between python and javascript text format I think (I know the get into the box as plain text), Second thing, the destruction of the items is not working not sure why. Also there is code refactoring to do since the rest of the function only manage adding stuff I change a bit for updating stuff, for the first table (maybe for nothing), but it needs to destruct records in the referenced table so I need to code that.

Richard

Paolo Caruccio

unread,
Jun 1, 2012, 3:24:26 PM6/1/12
to web...@googlegroups.com
Richard,

I made some reflections on what you want to do and it's not easy, since the use of control for simultaneous upload of multiple files was aimed to replace the standard control. As an example of use, you can see http://ochiba77.blogspot.it/2012/01/web2py-slices-sending-email-from-form.html
However, we can use a different approach to getting what you want through the use of a smartgrid. I'll post soon a demo application (in this days I'm very busy in personal matters). 

Richard Vézina

unread,
Jun 1, 2012, 4:08:06 PM6/1/12
to web...@googlegroups.com
No problem, I don't have time neither maybe for a couples of days too :)

Richard

Paolo Caruccio

unread,
Jun 22, 2012, 2:46:51 PM6/22/12
to web...@googlegroups.com
Richard,

I'm sorry for late answer. I spent a bit of time playing with bootstrap 2.0.4 and rewriting the code to follow frequent web2py changes. 

In attached app, you'll find a rewieved version of multiuploads control and some bootstrap features (carousel, web2py flash messages replaced with bootstrap alert, form and form errors).

I don't know if the approach  - that you'll see in app - is enough to satisfy your request, but It represents the way I would use.

The app is a toy. I mean, you could find many bugs, not optimized code, and so on. Its scope is only to demonstrate multiuploads control  usage in an web2py application.
web2py.app.multiuploads .w2p

Michael Freitas

unread,
Jun 22, 2012, 4:10:56 PM6/22/12
to web...@googlegroups.com
I have been struggling with multi file upload for a while.  I finally adapted the HTML5 example by Craig Buckler over at sitepoint.com (http://blogs.sitepointstatic.com/examples/tech/filedrag/3/index.html).  Attached is an basic application.  The problem I am having is that I am a novice with web2py and Html5 and javascript.  I could not figure out an elegant way to properly format the form with html5's formdata and JS so I had to kludge together an ajax service to read and store the files.  Maybe someone with more skill can look over and see if this could be improved upon.

Paolo Caruccio

unread,
Jun 22, 2012, 6:16:46 PM6/22/12
to web...@googlegroups.com
Michael,

please attach again your basic application, I would like take a look at it.

Michael Freitas

unread,
Jun 22, 2012, 7:13:57 PM6/22/12
to
Here you go.  Works in FF and Chrome.  Safari does not support drag and drop. Please let me know what you think.
web2py.app.test.w2p
Message has been deleted

Ruud Schroen

unread,
Dec 2, 2013, 6:01:21 PM12/2/13
to web...@googlegroups.com
Hi,

I know this is an old thread, but I have a question.

The upload and everything is working fine, but for some reason it doesn't work when bootstrap.min.css (the default one by web2py) is NOT included. This is kinda stupid because i'm using Foundation. Any idea what's going on?

Paolo Caruccio

unread,
Dec 4, 2013, 3:54:49 PM12/4/13
to web...@googlegroups.com
There are several  compatibility problems between foundation css and multiupload. You'll find here attached the patched files. Now it should work also with foundation (I tested the code with foundation 5.0.2) and also with jquery > 1.9
multiuploads.css
jquery.multiuploads.js

Ruud Schroen

unread,
Dec 4, 2013, 5:55:00 PM12/4/13
to web...@googlegroups.com
Thanks alot! I'll check it out tommorow :) i'll let you know if it worked


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/XpnUb2_MaRc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Ruud Schroen

unread,
Dec 5, 2013, 5:23:24 PM12/5/13
to web...@googlegroups.com
Works like a charm! Thanks alot :)

Chaitu P

unread,
Jun 26, 2015, 4:36:55 PM6/26/15
to web...@googlegroups.com
Hi Paolo,

I have installed your application and it is working perfectly.
I want have same multiimage upload functionality in my application. So I changed one of the table names.
But unfortunately it is not working. Iam not sure what Iam missing I have copied the css and js files as well.  Is there a way that you can help me.

my controller:
def new():
# only SQLFORM.factory tested
form=SQLFORM.factory(db.submission,db.t_photos)

if form.accepts(request, session, onvalidation=lambda form:check(form)): # Is it possible to use onvalidation with form.process() syntax ?
submission_id = db.submission.insert(**db.submission._filter_fields(form.vars))
redirect(URL('teacher'))

if isinstance(form,FORM):
# hide f_title form's row. Is there a better way to accomplish it?
del form[0][3]

return dict(form=form)

view:
{{response.files.extend([URL('static','css/multiupload.css'),URL('static','js/jquery.multiupload.js')])}}
{{left_sidebar_enabled=right_sidebar_enabled=False}}
{{extend 'layout.html'}}
<div>
{{=form}}
<script type="text/javascript" charset="utf-8">
//<!--
jQuery('input[name="f_photo"]:not(.processed)').multiUpload({
mw_placeholder:"{{=T('insert a title')}}",
mw_text_addBtn:"+",
mw_tooltip_addBtn:"{{=T('add a file')}}",
mw_text_clearBtn:"x",
mw_tooltip_clearBtn:"{{=T('remove all')}}",
mw_tooltip_removeFileBtn:"{{=T('remove this file')}}",
mw_tooltip_removeGroupBtn:"{{=T('remove this file group')}}",
mw_group_title:"{{=T('FILE GROUP')}}",
mw_fileNumber:false,
mw_maxElementAllowed:5
});
//-->
</script>
</div>

model:

db.define_table('submission', 
Field('name', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()]), 
Field('email', requires=[IS_NOT_EMPTY(), IS_EMAIL()]),
#Field('file','upload', requires=IS_NOT_EMPTY()),
Field('status', readable=False,writable=False),
Field('posted_on', 'date', default=request.now, readable=False, writable=False),
Field('problem_id','reference problem',readable=False, writable=False))

db.define_table('t_photos',
Field('f_trip_ref', type='reference submission', notnull=True, writable=False, readable=False),
Field('f_title', type='string', label=T('Title'), notnull=False), # notnull=False is required
Field('f_photo', type='upload', uploadfolder=request.folder+'static/pictures', notnull=False, # notnull=False is required
label=T('Photos'),
represent=lambda x, row:x and A('%s'%(db.t_photos.f_photo.retrieve(x)[0]),
_href=URL('default','viewer.html',args=x),
_target="_blank",
_title=T("open photo"),
_class='file-reference')
or ''
),
)

Chaitu P

unread,
Jun 28, 2015, 4:32:00 AM6/28/15
to web...@googlegroups.com
can anyone help.
I have copied all the files. But still not working.
When i clicked on the + button it is not showing popup window to choose files.

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Chaitanya Pochampally
Reply all
Reply to author
Forward
0 new messages