Multiple Uploads using jQuery-File-Upload: Javascript/CSS Conflict?

1,003 views
Skip to first unread message

Brando

unread,
Jan 8, 2014, 10:14:56 AM1/8/14
to web...@googlegroups.com
I'm trying to use jQuery-File-Upload to implement multiple file uploads.  I'm using this tutorial as well as this sample app HERE.  

Is there something in the standard web2py build that would be preventing the proper javascript or CSS from running?  The sample app should work right out of the box; however, no buttons are displayed. 

Has anyone successfully implemented this on web2py before?





Calvin Morrison

unread,
Jan 8, 2014, 10:18:28 AM1/8/14
to web...@googlegroups.com
I  just wrote my own way to do it yesterday which worked great. I would love it to go upstream.

It's just a standard file upload with the multiple attribute.

here's the entire thing: it spits out a form.

my db looks like this:

db.define_table('uploads',
    Field('username', 'string'),
    Field('filename', represent = lambda x, row: "None" if x == None else x[:45]),
    Field('up_file', 'upload', uploadseparate=True, requires=IS_NOT_EMPTY()),
    Field('up_date', 'datetime'), 
    Field('up_size', 'integer', represent= lambda x, row: quikr_utils.sizeof_fmt(x) ), 
    Field('notes', 'text'))


my contorller

def submit():
  import datetime

  form = FORM(LABEL("File(s):"), INPUT(_name='up_files', _type='file', _multiple=''), BR(), LABEL("Notes:"), TEXTAREA(_name='notes'), BR(),INPUT(_type='submit'))

  if form.accepts(request.vars, formname="form"):

    if hasattr(request.vars, 'up_files'):
      if len(request.vars.up_files) > 0:

        files = request.vars['up_files']
        if not isinstance(files, list):
          files = [files]

        for f in files:
          print f.filename
          up_file = db.uploads.up_file.store(f, f.filename)
          i = db.uploads.insert(notes=request.vars.notes, up_file=up_file,filename=f.filename, username = auth.user.email, up_date= datetime.datetime.now())
          db.commit()

        redirect(URL('data', 'index'))
      else:
        form.errors.up_files = "No files selected"

  return dict(form=form)



--
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/groups/opt_out.

Brando

unread,
Jan 8, 2014, 10:40:32 AM1/8/14
to web...@googlegroups.com
Calvin, you are awesome.  I will try this on my end and report back.

Calvin Morrison

unread,
Jan 8, 2014, 10:43:24 AM1/8/14
to web...@googlegroups.com
:-) I was having a hell of a time trying to get all the AJAX examples to work and well, none of it f***ing would. Yesterday I brewed an extra strong pot of coffee and cranked this out.

Some of the code i would like review on, I am not sure how to properly check for if there was an uploaded file or not, i have that weird "is in" then "len() < 0" but i don't think it's the best.

Whoever is a maintainer/developer of web2py - could we integrate this somehow?

Calvin

Brando

unread,
Jan 8, 2014, 10:44:12 AM1/8/14
to web...@googlegroups.com
Also, should it be possible to adapt this so that I could use SQLFORM.factory instead of FORM?  I notice this uploads the files to the db.  What would need to change so that I'm just pulling it to the local disk?







On Wednesday, January 8, 2014 7:18:28 AM UTC-8, Calvin Morrison wrote:

Calvin Morrison

unread,
Jan 8, 2014, 10:52:26 AM1/8/14
to web...@googlegroups.com
instead of inserting it, you could write the file stream out to whereever you want.

It's really just a python cgi module object. so you can use all corresponding documentation to help

look at this SO answer

Brando

unread,
Jan 8, 2014, 11:10:41 AM1/8/14
to web...@googlegroups.com
Calvin, i stripped out a variable or two, but it appears to work great.  I'm getting a crazy twitch trying to figure out a javascript/ajax solution for this.  I second the idea of building this into Web2py, I would be more than happy to contribute, but I'm just starting out with web2py and I would probably make something burst into flames.  

Thanks for your help, I'll be sure to post my end code I use.

Brando

unread,
Jan 8, 2014, 2:03:06 PM1/8/14
to web...@googlegroups.com
Calvin, I'm getting this error when I select only 1 file to upload:



Traceback (most recent call last):
 
File "/Volumes/BrandonsData/Google Drive/web2py/web2py.app/Contents/Resources/gluon/restricted.py", line 217, in restricted
 
File "/Volumes/BrandonsData/Google Drive/web2py/web2py.app/Contents/Resources/applications/calvinsmultiuploadfromgooggroup/controllers/default.py", line 158, in <module>
 
File "/Volumes/BrandonsData/Google Drive/web2py/web2py.app/Contents/Resources/gluon/globals.py", line 372, in <lambda>
 
File "/Volumes/BrandonsData/Google Drive/web2py/web2py.app/Contents/Resources/applications/calvinsmultiuploadfromgooggroup/controllers/default.py", line 116, in submit
 
File "cgi.pyc", line 591, in __len__
 
File "cgi.pyc", line 574, in keys
TypeError: not indexable

Which is coming from the highlighted line:
def submit():
 
import datetime

  form
= FORM(LABEL("File(s):"), INPUT(_name='up_files', _type='file', _multiple=''), INPUT(_type='submit'))


 
if form.accepts(request.vars, formname="form"):

   
if hasattr(request.vars, 'up_files'):
     
if len(request.vars.up_files) > 0:

        files
= request.vars['up_files']
       
if not isinstance(files, list):
          files
= [files]

       
for f in files:
         
print f.filename
          up_file
= db.uploads.up_file.store(f, f.filename)
          i
= db.uploads.insert(notes=request.vars.notes, up_file=up_file,filename=f.filename, username = auth.user.email, up_date= datetime.datetime.now())
          db
.commit()


       
return "form submitted" #redirect(URL('data', 'index'))

     
else:
        form
.errors.up_files = "No files selected"

 
return dict(form=form)





Did you see that during your testing? Any thoughts on this?

Calvin Morrison

unread,
Jan 8, 2014, 2:04:44 PM1/8/14
to web...@googlegroups.com
Yes I am getting that same problem here.

Like I said, I don't really know how to properly test if the variable has been set.

Any input from more wise web2pyers would be great

Calvin


--

Brando

unread,
Jan 8, 2014, 2:07:03 PM1/8/14
to web...@googlegroups.com
I removed that if loop completely and it works fine now:
def submit():
  import datetime

  form = FORM(LABEL("File(s):"), INPUT(_name='up_files', _type='file', _multiple=''),  BR(),INPUT(_type='submit'))
  
  # if hasattr(request.vars, 'up_files'):
  #   form.process()
  if form.accepts(request.vars, formname="form"):

    # if hasattr(request.vars, 'up_files'):
      # if len(request.vars.up_files) > 0:
      # if request.vars.up_files:

    files = request.vars['up_files']
    if not isinstance(files, list):
      files = [files]
    for f in files:
      print f.filename
      up_file = db.uploads.up_file.store(f, f.filename)
      i = db.uploads.insert(notes=request.vars.notes, up_file=up_file, filename=f.filename, up_date= datetime.datetime.now())
      db.commit()
    return "form submitted" #redirect(URL('data', 'index'))
      # else:
      #   form.errors.up_files = "No files selected"

  return dict(form=form)


Dave S

unread,
Jan 8, 2014, 2:23:21 PM1/8/14
to web...@googlegroups.com
On Wednesday, January 8, 2014 11:07:03 AM UTC-8, Brando wrote:
I removed that if loop completely and it works fine now:
 
The next obvious question:  did you test with no files?  To deal with those of us who click too fast?

/dps


Brando

unread,
Jan 8, 2014, 2:25:21 PM1/8/14
to web...@googlegroups.com
I'm working on that now.

if anyone beats me to it please post the solution.

Brando

unread,
Jan 8, 2014, 2:35:44 PM1/8/14
to web...@googlegroups.com
This works, added the requires statement for form validation:

def submit():
    import datetime
    form = FORM(LABEL("File(s):"), INPUT(_name='up_files', _type='file', _multiple='', requires=IS_NOT_EMPTY()),  BR(),INPUT(_type='submit'))
    if form.accepts(request.vars, formname="form"):
        files = request.vars['up_files']
        if not isinstance(files, list):
            files = [files]
        for f in files:
            print f.filename
            up_file = db.uploads.up_file.store(f, f.filename)
            i = db.uploads.insert(notes=request.vars.notes, up_file=up_file, filename=f.filename, up_date= datetime.datetime.now())
            db.commit()
        return "form submitted" #redirect(URL('data', 'index'))
    return dict(form=form)



Brando

unread,
Jan 8, 2014, 2:36:54 PM1/8/14
to web...@googlegroups.com
Question, how could I make it so I don't have to click the submit button.  How could i make it to where they choose the files and it auto submits it?

Calvin Morrison

unread,
Jan 8, 2014, 2:41:41 PM1/8/14
to web...@googlegroups.com
that'd be a Jquery thing.

jQuery("input#fileid").change(function () {
    alert(jQuery(this).val())
});



Alan Etkin

unread,
Jan 8, 2014, 4:48:34 PM1/8/14
to web...@googlegroups.com
I'm trying to use jQuery-File-Upload to implement multiple file uploads.  I'm using this tutorial as well as this sample app HERE.  

I made a multiple upload demo for storing imap drafts here (using SQLFORM.factory and form customization)

http://www.web2pyslices.com/slice/show/1706/how-to-compose-a-multi-attachment-draftnormal-email-with-imapsmtp

I suppose it is possible to use it for any other app modifying the controller so it stores or processes the input however needed.

Calvin Morrison

unread,
Jan 9, 2014, 1:10:04 PM1/9/14
to web...@googlegroups.com
Brando,

Thanks for working this out!

it would be good to make a web2py slice or add it to the documentation/ examples

Calvin

Brando

unread,
Jan 9, 2014, 5:29:13 PM1/9/14
to web...@googlegroups.com
Calvin, I have a few other things I want to work out, but I'm going to start a new thread with a more relevant title.  

Sujata Aghor

unread,
Jun 10, 2015, 3:00:54 AM6/10/15
to web...@googlegroups.com, mutant...@gmail.com
Hello Calvin,
Does this mentioned solution any way related with - jQuery-File-Upload ???
When I implemented it, it is not allowing me to upload multiple files via the browse button.
Am I missing something?

Thanks in advance!!!

Sujata Aghor

unread,
Jul 2, 2015, 2:56:09 AM7/2/15
to web...@googlegroups.com

My code( based on your mentioned solution) looks like this-

            if form.accepts(request.vars):
                if hasattr(request.vars, 'txn_doc'):
                    #if len(request.vars.txn_doc) > 0:
                    files = request.vars['txn_doc']

                    if not isinstance(files, list):
                        files = [files]
                  
                    for f in files:
                        print f.filename
                        txn_doc = db.uploaded_docs.txn_doc.store(f, f.filename)
                        db.uploaded_docs.insert(
                            portfolio_company=request.vars.portfolio_company,
                            txn_area=request.vars.txn_area,
                            document_name=request.vars.doc_name,
                            txn_doc=f.filename,
                           document_date=request.vars.document_date)
                        db.commit()
                        print "DEBUG: [%s] successfully uploaded" % f.filename
                    redirect(URL('upload', 'upload'))


This is inserting +1 record to db. Not getting why it is so?
Means if I upload 2 files it should insert 2 records in db; BUT it inserts 3 (and the extra without file)
Please help me!!!!

Sujata Aghor

unread,
Jul 2, 2015, 3:10:31 AM7/2/15
to web...@googlegroups.com
Here is what works for me -

I used -  if form.validate():
instead of  -  if form.accepts(request.vars):

This resolves the problem of inserting 1 extra record.

form.accepts:- filters the request.vars according to the declared requirements (expressed by validators). accepts stores those variables that pass validation into form.vars. The accepts function returns True if the form is accepted. And inserts a record in db.

Where as form.validate only validates the variables whether they passed the validation.

Phillip

unread,
Aug 4, 2015, 1:22:15 PM8/4/15
to web2py-users
Has anyone had the 404 error (where server/php is called)? I do not know where to trace this to. 
Reply all
Reply to author
Forward
0 new messages