1

So I'm trying to create a simple registration form for users to enter their info, and submit for processing. I'm having trouble with grabbing the form data. The way the site is setup, I've got the "/register" form that then sends an ajax request to the url "/postregister". From there, enters the class that gets the data from web.input(), and then references the data for whatever I need to. Or at least that's the intention...

The problem that I have lies in the very first step: Grabbing the form data from "/register" page. Nothing is actually passed along.

Here is the register.html

<div class="container">
    <h2>Register Account</h2>
    <br /><br />
    <form id="register-form">
        <div class="form-group label-static is-empty>
        <label for="username" class="control-label">Username</label>
        <input id="username" class="form-control" type="text" placeholder="Choose a username..."/>
    </div>
    <button type="submit" class="btn btn-info">Submit </button>
    </form>
</div>

The main controller.py:

import web

urls = (
    '/', 'Home',
    '/register', 'Register',
    '/postregistration', 'PostRegistration'
)

render = web.template.render("Views/Templates", base="MainLayout")
app = web.application(urls, globals())

class Home:
    def GET(self):
        return render.Home()

class Register:
    def GET(self):
        return self.Register()

class PostRegistration:
    def POST(self):
        data = web.input()
        print "data:   " + str(data) # This line is for debugging
        return data.username

if __name__ == "__main__":
    app.run()

plus the js:

$(document).ready(function() {
    console.log("loaded");

    $(document).on("submit", "#register-form", function(e) {
        e.preventDefault();

        var form = $("#register-form").serialize();
        console.log(form); //This is just for debugging
    $.ajax({
        url: '/postregistration',
        type: 'POST',
        data: form,
        success: function(response){
        console.log(response);
        }
    });
    });
});

When I run the controller.py, and navigate to localhost:8080/register, I'm prompted with the form to fill out. Success! Now I enter the information and click submit. Problem!! When checking the console log, the form is not actually being captured. An "AttributeError" is raised, with AttributeError: 'username'. And sure enough, the controller.py prints:

data:   <storage {}>

So I see that web.input() grabs no data. Going back a little further, in the web console, I can see that "loaded" is written, then when I click submit, I can see that something (but actually nothing) is written to the console. Again, all signs point to me not grabbing the form data. Any ideas where I've gone wrong?

j3private
  • 13
  • 5

3 Answers3

1

I think your jQuery selector here is wrong:

var form = $("register-form").serialize();

Ought to be

var form = $("#register-form").serialize();

Source

This would possibly result in no element being selected for .serialize() to serialize.

Frish
  • 1,371
  • 10
  • 20
  • The change had no effect. I see from your Source where I went wrong, but it did not fix things. – j3private Sep 06 '17 at 23:48
  • I'm less of an expert on Python, however could your issue arise from the indentation of "return data.username" in class PostRegistration? From what I know of Python it looks like you're calling the return outside of the POST(self) function. – Frish Sep 07 '17 at 00:16
  • Thanks for the feedback. The indentation of "return data.username is actually correct. It may look strange due to the print statement above, but I believe that the issue is somewhere wayyyy before the final return statement in the main python controller. – j3private Sep 07 '17 at 01:29
  • I apologize. I did not quite see the error that you pointed out. You are correct about the indentation error. Aside from that, it still does not work as desired. – j3private Sep 08 '17 at 21:27
1

it looks like the serialize method is omitting all of the fields because they dont include a name attribute. if you add it to the register entries like this:

<div class="form-group label-static is-empty">
        <label for="username" class="control-label">Username</label>
        <input id="username" class="form-control" type="text" name="username" placeholder="Choose a username" />
</div>

then the form variable will populate. this still returns a 500 error when trying to access a field with the line data.username....

sources: JavaScript - Getting HTML form values https://api.jquery.com/serialize/

FolksyBeer
  • 26
  • 3
  • 1
    Thank you very much for this post. This did the trick. I guess next time I'll look harder for the answer to my question. Thanks!! – j3private Sep 10 '17 at 02:14
  • were you able to fix the 500 error from the data.username line? im still stuck on that – FolksyBeer Sep 10 '17 at 07:11
  • yes. By adding the name="username" attribute in the HTML file it worked perfectly. I can now take the user input and send it to my MongoDB. – j3private Sep 13 '17 at 20:19
0

Indentation error:

class PostRegistration:
    def POST(self):
        data = web.input()
    print "data:   " + str(data) # This line is for debugging
    return data.username

Needs to be:

class PostRegistration:
    def POST(self):
       data = web.input()
       print "data:   " + str(data) # This line is for debugging
       return data.username

On the jquery side, .serialize() will ignore all inputs which do not have a name attribute. That's why you're not getting anything sent across the wire.

Solution is add name='username' to your input.

pbuck
  • 4,291
  • 2
  • 24
  • 36
  • You are correct. Rather than copy and paste the code, I typed it so that I could review each line individually. The correction you've made to my syntax does not change the fact that data still captures no information from the form. – j3private Sep 08 '17 at 21:25