[TIP] dowloading attachments with AJAX

84 views
Skip to first unread message

Michele Comitini

unread,
Aug 15, 2011, 4:47:17 PM8/15/11
to web...@googlegroups.com
Suppose you want to make an AJAX call that starts a file download.
How can you do that?
1. form submission
2. a element href
3. iframe

Too complex!

of course *web2py* comes to rescue...
BIG NOTE: the following is based on 'data:' url type and was tested
only on FF and chrome. I do not have
IE but I suppose that is not compatible with the standard!


In your view put a web2py ajax call similar to the following wherever
you need it:

ajax('%s',[],':eval');" % URL('gen_pdf')

ex.

{{=A(T('be brave!'), _onclick="ajax('%s',[],':eval');" %
URL('gen_pdf'), _class='button')}}

in the controller use embed64.

def gen_pdf():
from gluon.contrib.pyfpdf import FPDF

pdf=FPDF()
pdf.add_page()
pdf.set_font('Arial','B',16)
pdf.cell(40,10,'Hello World at %s!' % request.now)
doc=pdf.output(dest='S')

doc64=embed64(data=doc,extension='application/pdf')


return 'window.location="%s";' % doc64


have fun!

mic

mart

unread,
Aug 16, 2011, 5:59:29 PM8/16/11
to web2py-users
Hi Mic!

This is very interesting! :) how does it work? you have
"URL('gen_pdf')", what is that referencing?

would you have a model/sample app that we could peek at? :)


Thanks,
Mart :)


On Aug 15, 4:47 pm, Michele Comitini <michele.comit...@gmail.com>
wrote:

Michele Comitini

unread,
Aug 17, 2011, 6:33:24 PM8/17/11
to web...@googlegroups.com
Hi Mart!

Copy sample code in my previous mail.

to test quicly you cat put the view code somewhere in
/welcome/views/default/index.html

{{=A(T('be brave!'), _onclick="ajax('%s',[],':eval');" %
URL('gen_pdf'), _class='button')}}

copy the function gen_pdf() in /welcome/controllers/default.py

def gen_pdf():
    from gluon.contrib.pyfpdf import FPDF

    pdf=FPDF()
    pdf.add_page()
    pdf.set_font('Arial','B',16)
    pdf.cell(40,10,'Hello World at %s!' % request.now)
    doc=pdf.output(dest='S')

    doc64=embed64(data=doc,extension='application/pdf')

    return 'window.location="%s";' % doc64

No need for other code. The trick is all in the use of 'data:' URI
that is created by embed64()

ok now URL('gen_pdf()') calls gen_pdf() in the controller that
generates the pdf on the fly and posts it back to the browser.
All in one pass, no session no temporary files around, no form, no GET...

;-)

mic


2011/8/16 mart <msene...@gmail.com>:

mart

unread,
Aug 17, 2011, 10:22:09 PM8/17/11
to web2py-users
HI Mic!

This is fantastic! Thanks for the info! :)

On Aug 17, 6:33 pm, Michele Comitini <michele.comit...@gmail.com>
wrote:
> Hi Mart!
>
> Copy sample code in my previous mail.
>
> to test quicly you cat put the view code somewhere in
> /welcome/views/default/index.html
>
> {{=A(T('be brave!'), _onclick="ajax('%s',[],':eval');" %
> URL('gen_pdf'), _class='button')}}
>
> copy the function gen_pdf() in /welcome/controllers/default.py
>
>  def gen_pdf():
>      from gluon.contrib.pyfpdf import FPDF
>
>      pdf=FPDF()
>      pdf.add_page()
>      pdf.set_font('Arial','B',16)
>      pdf.cell(40,10,'Hello World at %s!' % request.now)
>      doc=pdf.output(dest='S')
>
>      doc64=embed64(data=doc,extension='application/pdf')
>
>      return 'window.location="%s";' % doc64
>
> No need for other code. The trick is all in the use of 'data:' URI
> that is created by embed64()
>
> ok now URL('gen_pdf()') calls gen_pdf() in the controller that
> generates the pdf on the fly and posts it back to the browser.
> All in one pass, no session no temporary files around, no form, no GET...
>
> ;-)
>
> mic
>
> 2011/8/16 mart <msenecal...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages