Play framework: empty body in post request - scala

Helo! I have a following code:
def foo = Action { request =>
Ok(request.body.asText.getOrElse("no body"))
}
In frontend have a form like this:
<form action="#controllers.routes.Application.foo()" method="POST">
<input name="name" type="text">
<input name="surname" type="text">
<button type="submit">
</form>
If I fill the form and click submit, they gives me result: no body.
But if I add brakepoint in debugger to Ok(..), they shows me, that body is not emty.
AnyContentAsFormUrlEncoded(Map(name -> ArrayBuffer(123), surname -> ArrayBuffer(123)))
Why, that doesn't give me body as text, or as anything else, and how I can get them?

Given your form and your debugging output, you should be using asFormUrlEncoded.

You'll need the following as well:
<form ... enctype="text/plain">
to specify that the payload is plain text. Then the .asText will work.

Your content type probably is something other than text/plain. The BodyParser will only return a result, when the content type is the expected.
edit: Instead of asText try asRaw.

Related

How can I stop default submission of form using Vanilla JavaScript

I would like to stop default submission using Vanilla JavaScript. I created a sample of little form. But it gets refreshed when I submit the form even though I call the preventDefault() method. When I use input type="button" it works. But not works with input type="submit".
What will be the reason? Can anyone explain me what is the right method and what's wrong with the code?
My code is as follows:
let validation = () => {
let form = document.querySelector(".form");
form.addEventListener("submit", (event) => {
event.preventDefault();
});
}
<form action="" class="form" method="post" onsubmit="return validation()">
<input type="text">
<input type="submit" value="submit">
</form>
Optional Help: Can anyone give me a proper method or any good references on creating forms. Because when I search, I got lots of tutorials where all are says different methods and I really struggle to find out which method is the standard one.
Try the following changes to your code:
HTML
<form action="" class="form" method="post" onsubmit="validation(event)">
<input type="text">
<input type="submit" value="submit">
</form>
Try removing the return keyword and add event parameter.
JavaScript
const validation = event => {
event.preventDefault();
}
Using the preventDefault() method of event, the form is hopefully not submitted! Hopefully it works for you.

Insert data in H2 using HTML form

I'm using Play! Framework 2.4. I can make a table and insert data via the evolution .sql scripts but how do I setup my Appication.scala, routes etc to make a form insert data?
PS I'm quite new to Play
The best way play fromework recommends is using helper and template system.
https://www.playframework.com/documentation/2.4.x/ScalaForms
But if you want to try with plain html and handler request in the controller by your own so you can try this:
Application.scala
def save = Action { implicit request =>
//here handle params from html form,
//this will return Option[Map[String,ArrayBuffer]]
val optionMap = request.body.asFormUrlEncoded
println(optionMap)
//saving things here
Ok("saved")
}
in plain html form
<form action="/savedata" method="post" accept-charset="UTF-8" enctype="application/x-www-form-urlencoded">
<input type="text" name="name" />
<input type="text" name="lastName" />
<input type="submit" />
</form>
conf/routes
POST /savedata controllers.Application.save
hope this helps.
regards

Play Framework Multiple QueryStrings

I can get one queryString from the template however, never managed to get two.
This is my controller
def get = Action { implicit request =>
val requestedProviderName = request getQueryString "providerName"
val requestedReleaseId = request getQueryString "releaseId"
}
Like that my router produces
Here is my router.conf : http://localhost:9000/fail?providerName=oneProviderName
this is all correct but I want to pass more than one option.
GET /fail #controllers.mycontroller.get
What I have as a view is so basic,
#helper.form(routes.mycontroller.get) {
<select name="providerName" class="selectpicker" data-live-search="true">
#for((providerName, failedReleasesNumber) <- providers){
<option id="selectedvalue" value="#providerName" selected="selected">
#providerName, #failedReleasesNumber
</option>
}
</select>
<div class="row-fluid">
<div class="span6">
<label>Start Date: <input type="date" id="startDate"></label>
<label>End Date: <input type="date" id="endDate"></label>
<label>Release Id: <input type="number" id="releaseId"></label>
<label>Results Start?!: <input type="number" id="resultStart"></label>
<label>Max Results: <input type="number" id="maxResults"></label>
<input type="submit" class="btn btn-primary" value="Get Failed Releases" style="margin-top:-10px">
</div>
</div>
}
My question is more, how I can define these inputs as I want them to be in the QueryPath.
I have searched the web however, couldn't find a solution. Everyone written stuff about router but how to define them in template is unanswered or I am missing something completely. I am using Play Framework 2.1.1 with Scala
For question 1:
To use url like http://localhost:9000/fail?providerName="xyz"&secondQueryString="abc" define like this in routes file
GET /fail controllers.mycontroller.get(providerName: String, secondQueryString: String)
and modify get method signature like get(providerName: String, secondQueryString: String)
For question 2:
When the form action is defined for GET method then by default all the input fields will be passed in query string. Just ensure using same query string names defined for url path (in routes file) and the name used in the html file.
Well I have found my answer, as it is answered before the operation should be GET
However, e.g.
<input type="number" name="maxResults" id="maxResults">
Just id of input field is not enough thus, there should be name field as well and after everything is okay. Even there is no need for input variables to the functions. You can get the variables like
val requestedProviderName = request getQueryString "providerName"
Which returns an optional value of input variable in the template(view).

Angular JS: sending form field data in a PUT request (like POST does)

I'm trying to write a client that does all four REST verbs (GET/POST/PUT/DELETE) and have gotten all but the PUT done. The REST/CRUD API I'm working from wants to update an entry by calling PUT /realmen/ID-string and including the key-value pairs as JSON. For a POST this seems to work "automatically", but not for a PUT.
My HTML looks like:
<div id="list">
<form novalidate class="edit-form">
<p>Title <input ng-model="realmen.title" type="text" value="{{realmen.title}}" /></p>
<p>Real Men <input ng-model="realmen.realmen" type="text" value="{{realmen.realmen}}" /> </p>
<p>Real Role-Players <input ng-model="realmen.realroleplayers" type="text" value="realmen.realroleplayers}}" /></p>
<p>Loonies <input ng-model="realmen.loonies" type="text" value="{{realmen.loonies}}" /></p>
<p>Munchkins <input ng-model="realmen.munchkins" type="text" value="{{realmen.munchkins}}" /></p>
<input ng-model="realmen.entryId" type="hidden" value="{{entryId}}"/>
<button ng-click="change()">UPDATE ({{entryId}})"</button></p>
</form>
</div>
My controller looks like:
$scope.realmen = RealMen.get({entryId: $routeParams.entryId}, function() {
$scope.master = angular.copy($scope.realmen); // For resetting the form
});
$scope.change = function() {
console.log($scope.realmen);
RealMen.update({entryId: $scope.entryId}, function() {
$location.path('/');
});
}
And finally, my services look like:
angular.module('realmenServices', ['ngResource']).
factory('RealMen', function($resource){
var RealMen = $resource(
'http://localhost\\:3000/realmen/:entryId',
{},
{
query: {method:'GET', params:{entryId:''}, isArray:true},
post: {method:'POST'},
update: {method: 'PUT', params:{entryId:'#entryId'}},
remove: {method:'DELETE'}
});
return RealMen;
});
The PUT is getting called with the correct id value in the URL, but the Request Payload only contains the entryId, so the backend API gets no expected keys and values and essentially blanks out the record in the database.
The console.log($scope.realmen) does show the form fields, along with a lot of extra data. I tried calling RealMen.update($scope.realmen, ...) (similarly to calling .save()), but all those extra fields are tacked on as query string parameters to the URL in a spectacularly ugly fashion.
Because your $scope.realmen is a resource instance, instead of using RealMen.update, you can just call $scope.realmen.$update() (note that there is a "$"). The instance action method will take care of sending the data for you.

Submit the value of a <p> element when an html form is submitted

I have this code: <p class = "foo">Text</p>
And I also have a form: <form action = "XXX.php" method = post></form>
However, how can I get the value of the <p> when I submit it, as the <p> element can be changed.
So what I mean is to be able to post the value of the <p> when the user submits the form, and to be able to access it from that php file with: $_POST['foo'];
Thanks, I have tried to be as clear as possible.
You have to use Javascript for that
A jQuery function that will work
$("form").submit(function(){
var value = $("p").html();
// If foo already exists
if( $("[name=foo]").length > 0 )
{
$("[name=foo]").val(value);
}
else
{
var input = $("<input />", { name : "foo",
value : value ,
type : "hidden" });
$(this).append(input);
}
});
Use
<input type="hidden" value="something" name="something" id="something" />
and when you change inner html of <p> change the value of hidden input.
I think your best bet is to make it an input with readonly enabled, and style to to look like a <p>. It's better then trying to add it to the POST parameters with JavaScript.
Here's a quick example. I bet it could still be improved with a few extra CSS quirks, experiment a bit.
The easiest thing to do is set the value of a hidden form field when you change the contents of your <p>.
Alternatively, you can get its contents and post with JavaScript.
For text you need to use input field:
<input type="text"/>
Form fields should must have an id:
<input type="text" id="pewpew" class="foo"/>
I would go with:
<input type="text" id="pewpew" class="foo" value="default text goes here"/>
OR
Go with different workarounds, like setting form's hidden elements on the fly, etc.
You can create hidden field on the fly and set its value on form submit. Like this:
<form id="form" action="/somewhere" method="post">
<p>Some text</p>
<input type="submit" value="Submit"/>
</form>
<script type="text/javascript">
var form = document.getElementById('form');
form.onsubmit = function()
{
var p = this.getElementsByTagName('p')[0];
if (!document.getElementById('pval'))
{
var pinput = document.createElement('input');
pinput.setAttribute('type', 'hidden');
pinput.setAttribute('id', 'pval');
pinput.setAttribute('name', 'p');
this.appendChild(pinput);
}
document.getElementById('pval').value = p.innerHTML;
return true;
}
</script>
Works, i've tested.