Form values are null in post request in play framework
Asked Answered
Q

3

2

I have html to post back a form, like this:

@(message: String)

@main("Contact") {
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/contact.css")">
<div id="pageContainer">
    <div id="form">
        <div id="topText">
            <p>Have a question or need some assistance? Let us know and we'll get back to you ASAP.</p>
        </div>
        <br/>
        <form method="POST" action="@routes.Home.contact()">

            <div id="contactInfo">
                <label class="contactLabel">First Name:</label><input type="text" name="firstName" id="firstName" class="contactInput" /> <br />
                <label class="contactLabel">Last Name:</label><input type="text" name="lastName" id="lastName" class="contactInput" /> <br />
                <label class="contactLabel">Email:</label><input type="text" name="email" id="email" firstName" class="contactInput" /> <br />
                <label class="contactLabel">Company:</label><input type="text" id="company" name="company" class="contactInput" /> <br />
                <input type="hidden" id="hidden" name = "hidden"></input>
                <p id="crap">@message</p>
            </div>
            <br/>
            <div id="message">
                <label class="contactLabel">Message:</label><textarea cols="50" rows="10"></textarea>
            </div>
            <input type="submit" name="submit" id="submit" value="Submit"></input>
            </form>
    </div>

</div>

}

Back in the controller, it looks like this:

public static Result contact()
{

    //Map<String,String[]> values = request().body();
    DynamicForm form = form().bindFromRequest();
    String first = "";
    if(form.data().get("firstName") != null)
    first = form.data().get("firstName").toString();

    return ok(views.html.contact.render(first));
}

But when I look through the result of form().bindFromRequest(), it is always empty. Am I missing something?

Quid answered 3/12, 2012 at 17:35 Comment(6)
Why don't you pass directly the parameters String hello, String hello1, String hello2 to your Home.contact method instead of retrieving them with bindFromRequest?Harelda
Besides, are you sure you are correctly using firstName both in controller and view?Harelda
@Harelda apparently not.. is there anything special and specific to play that I need to do? Even when I tried passing them directly, it isn't sending them correctly. I get a "not enough arguments" error.Quid
Can you show the real html/scala template and not something that looks like having input text with name=hello. Please show the real one, and the code of the Home.contact method including definition.Harelda
@alex edited with actual codeQuid
@alex if you can figure out what's going wrong with this by today, I'll put a 100 rep bounty on the question and give it to you when it's eligibleQuid
H
8

Here is how I would do that:

template

@(message: String, contactForm: Form[Contact])

@import helper._

@main("Contact") {
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/contact.css")">
<div id="pageContainer">
    <div id="form">
        <div id="topText">
            <p>Have a question or need some assistance? Let us know and we'll get back to you ASAP.</p>
        </div>
        <br/>
        @form(routes.Home.contact()) {
            <div id="contactInfo">
                <label class="contactLabel">First Name:</label> @inputText(contactForm("firstName"), 'class -> "contactInput"') <br />
                <label class="contactLabel">Last Name:</label> @inputText(contactForm("lastName"), 'class -> "contactInput"') <br />
                <label class="contactLabel">Email:</label> @inputText(contactForm("email"), 'class -> "contactInput"') <br />
                <label class="contactLabel">Company:</label> @inputText(contactForm("company"), 'class -> "contactInput"') <br />
                <input type="hidden" id="hidden" name="hidden"></input>
                <p id="crap">@message</p>
            </div>
            <br/>
            <div id="message">
                <label class="contactLabel">Message:</label><textarea cols="50" rows="10"></textarea>
            </div>
            <input type="submit" value="Submit" />
        }
    </div>
</div>
}

Class Contact

public class Contact {
    public String firstName;
    public String lastName;
    public String email;
    public String company;
    // other stuff
}

Controller

public static Result contact() {
    Form<Contact> contactForm = form(Contact.class).bindFromRequest();
    if (contactForm.hasErrors()) {
        // process
    } else {
        // contactForm.get().firstName should be filled with the correct data
        return ok(views.html.contact.render("message", contactForm)); 
    }
}

Does it work for you ? You should take a look at the Play2 documentation about these topics:

  1. JavaForms
  2. JavaForm Helpers

Edit

if you can explain why the way I was doing it previously didn't work

I'm not sure about that, but I can see one problem in your code, you don't have to call data() on the dynamic form, using directly DynamicForm.get() is sufficient, so first = form.get("firstName") is sufficient.

Besides as you can see from the DynamicForm Javadoc

get(java.lang.String key)

Gets the concrete value if the submission was a success.

The internal map behind DynamicForm has values if there is no errors, so you may check with hasErrors before actually getting concrete values from field.

From my point of view, it is better and easier to use the form(Contact.class).bindFromRequest() style that will fill an instance of class Contact, this without saying that fields can be validated using Java annotations.

Harelda answered 3/12, 2012 at 21:24 Comment(2)
It worked. Bonus points if you can explain why the way I was doing it previously didn't workQuid
taking away your accepted status so that I can give you your bounty later onQuid
P
0

You must provide a Request to bindFromRequest() method. For example

 DynamicForm form = form().bindFromRequest(request());

The request function provides the current Request for the current action. Seems like bindFromRequest doesn't bind automatically the current Request

I was having the same problem and google brought me here, hope it helps.

Polychasium answered 26/3, 2016 at 18:17 Comment(0)
C
0

Maybe not exactly the same problem but on my Windows developing Play 2.6 app I had similar issue. Binding did not work. I mean the Form's data field had proper values, but the values of model were empty. That was causing No such element exception: No value present. I've spent quite a while looking into this. What fixed the issue was cleaning project, recompiling and running it again. Ehh.

City answered 15/3, 2018 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.