0

I am trying to upload a file to a cherrypy server, but without changing the displayed page. A simple alert will be enough for my needs to tell the user that the upload is done.

I am trying this with a simple file input type and a button:

<div>
    <label>Upload Sound:</label>
    <input id="pathSound" style="width: 80%" type="file" accept=".mp3"/><br>
    <button id="uploadSound">Upload</button>
</div>

and a script for the button click:

$("#uploadSound").click(function(e) {
    if (document.getElementById("pathSound").value=='') {
        alert("No file selected!");
        e.preventDefault();
        return;
    }
    var cardID = $('#tagID').html();
    var file = document.getElementById("pathSound").files[0];
    alert( "Tag: " + cardID + " File: " + file);

    $.post("/uploadSound", {"cardID": cardID, "myFile": file})
    .done(function(res) {
        alert("File Saved!");
    });
});

on the server side i have this function so far, but it is never called:

import os, os.path
import cherrypy
from cherrypy.process import  plugins

class MagicBoxInterface(object):

    @cherrypy.expose
    def index(self):
        return file('index.html')

    @cherrypy.expose
    def uploadSound(self,  cardID='', myFile=None):
        print 'uploadSound : ',  cardID
        print 'uploadSound : ',  myFile
        return ''

if __name__ == '__main__':
    conf = {
        '/': {
            'tools.sessions.on': True,
            'tools.staticdir.root': os.path.abspath(os.getcwd())
        },
        '/static': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': './public'
        }
    }
    interface = MagicBoxInterface()
    cherrypy.quickstart(interface, '/', conf)

All the examples i find use normal post and show a result page after the upload, but this is not what i want to do! The displayed page must not change.

On a side note, i don't need to consider large files, because it will only handle files below 1-2 MB.

I have found some examples using frames, but i am not that familiar with html/javascript to fully understand how i can apply those to my needs.

And help on a simple solution is greatly appreciated.

Ryu Kajiya
  • 255
  • 1
  • 3
  • 16
  • I think you're having an issue with your JS. The control of the browser is out of the hands of the server side code. Add a `e.preventDefault();` at the end of the click handler. ` – cyraxjoe Jan 05 '15 at 06:24
  • I used the preventDefault allready, but took it out to see what happens. The primary problem is that the server function is never called. Somehow cherrypy can't make the connection. – Ryu Kajiya Jan 05 '15 at 10:48
  • is /uploadSound exposed {@cherrypy.expose}? – Andrew Kloos Jan 05 '15 at 12:56
  • As you can see in the given code: Yes – Ryu Kajiya Jan 05 '15 at 13:00
  • Show the whole py file that uploadSound is in. – Andrew Kloos Jan 05 '15 at 22:29
  • Edited to show all relevant parts of the file, altho the exposed tag was in it before allready. I solved the issue by switching to bottle, works like a charm there. It seems all examples given for cherrypy won't work with newest version. The Javascript part was a bit wrong too, but i doubt that cherrypy would have worked if i would have fixed it there. – Ryu Kajiya Jan 05 '15 at 22:50
  • Duplicate of http://stackoverflow.com/q/26876695. – saaj Jan 06 '15 at 11:29

1 Answers1

0

Ok do this...

$("#uploadSound").click(function(e) {
    if (document.getElementById("pathSound").value=='') {
        alert("No file selected!");
        e.preventDefault();
        return;
    }
    var cardID = $('#tagID').html();
    var file = document.getElementById("pathSound").files[0];
    alert( "Tag: " + cardID + " File: " + file);

    $.post("/MagicBoxInterface/uploadSound", {"cardID": cardID, "myFile": file})
    .done(function(res) {
        alert("File Saved!");
    });
});

You just need to include the class in your post request path. hope this helps!

Andrew Kloos
  • 4,189
  • 4
  • 28
  • 36
  • Since the MagicBoxInterface is exposed as '/' it is not needed to include the class. Including class name would be wrong anyways, because classes can get a completely different route anyways. On a sidenote the class has 15 other methods exposed and every one of those work finr with '/'. – Ryu Kajiya Jan 06 '15 at 20:15
  • Have you checked out firebug to see if the ajax request is being sent? Getting a 404... or not matching your handler parameters? – Andrew Kloos Jan 07 '15 at 20:53