GET form in Scala templates - scala

I'm attempting to create a form using GET to search given some input:
<form class="form-inline" role="form" method="get" action="#routes.Index.search">
<div class="form-group">
<label for="search-field">Search:</label>
<input id="search-field" class="form-control" type="text" name="q" placeholder="Sun"/> </div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
Where the Index controller has the following method:
def search(q: String) = Action.async {
...
}
And my routes file has the following route:
GET /search controllers.Index.search(q: String)
I was expecting that this should work as I expect, which is that a GET request should be made to http://foo.bar/search?q=hello if the value in search-field was hello. Instead I get the following compilation error:
/index.scala.html:8: missing arguments for method search in class ReverseIndex;
follow this method with `_' if you want to treat it as a partially applied function
<form class="form-inline" role="form" method="get" action="#routes.Index.search">
Any help with why this is wrong would be much appreciated.

The problem was that I was not providing default values for the query parameters in the routes file:
GET /search controllers.Index.search(q: String ?= "")
fixed the problem.

Related

Nested Angular Form Groups - Form must reflect HTML structure

Say I have the following formGroup structure:
userGroup = {
name,
surname,
address: {
firstLine,
secondLine
}
}
This forces me to write HTML similar to the following:
<form [formGroup]="userGroup">
<input formControlName="name">
<input formControlName="surname">
<div formGroupName="address">
<input formControlName="firstLine">
<input formControlName="secondLine">
</div>
</form>
Let's say, just for the sake of the example, that you are constrained to write HTML that looks like this:
<form [formGroup]="userGroup">
<input formControlName="name">
<input formControlName="surname">
<div formGroupName="address">
<input formControlName="firstLine">
</div>
<hr>
<div formGroupName="someOtherGroup">
<input id="problemSecondLine" formControlName="???.secondLine">
</div>
</form>
Is there a way, to force the field with id=problemSecondLine to be under userGroup -> address -> secondLine, even though, visually, I have no option but to place it under this particular DIV?
I guess I can manually update via ngModel - but I'm trying to find the cleanest way possible.
You can use formControl directive instead of formControlName
<input id="problemSecondLine" [formControl]="userGroup.get('address.secondLine')">
Plunker Example

Declare variable to use inside #helper.repeat - PlayFramework

I want to use helper.repeat to create several input elements. But I want to declare the input tags as html instead of using #helper.input methods. But to do that I have to use a #index inside this loop. I am unable to instantiate and increase this variable. I tried something like the code below but I this output appear in html page:
BaseScalaTemplate(play.twirl.api.HtmlFormat$#5a8a0ced) = {0}
is output in html.
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
#index = {0}
#helper.repeat(questionForm("answer.alternatives"), min = 7) { (alternative) =>
<div class="checkbox">
<input type="checkbox" value="#alternative("correct") ">
<input type="text" id="answer_alternatives_(#index)_text" name="answer.alternatives[#index].text" value="">
</div>
}
</div>
</div>
Is there another maybe cleaner way to do what I want? Maybe with #for?
I use playframework 2.4.6 with Java8.
Playframework will let you do what you need, but you will have to do it in another way.
1) Your form definition will have a Seq[String] to save the results that come from the template.
2) Your form definition will need to include this change. In your case:
"answer_alternatives" -> seq(nonEmptyText)
3) Change the name and id from the template to #{alternative.name} so Playframework can link your input text to the sequence of String.
<input type="text" id="#{alternative.name}" name="#{alternative.name}" value="">

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).

serialize array returning an empty array

I'm trying to grab some form data in my function but for some reason my fom returns an empty array when i try and run the function .serializeArray() on it. I've checked that to make sure it input element has a name I just can't figure out why this is happening
this is my form
<form id="uploadForm" name="form" action="{{nodeSocketUrl}}/upload?tenant=qa&envelope=true" method="POST" enctype="multipart/form-data" class="forms" style="left:15px">
<fieldset class="units-row">
<h3>Upload A Presentation</h3>
<label for="presentationFileUpload">Select a .ppt, .pptx, .pdf</label>
<input type="file" id="presentationFileUpload" name="presentationFile" onchange="angular.element(this).scope().onFileSelect(this)"/>
<hr>
<input type="submit" id="fileUploadBtn" class="btn btn-primary disabled" value="Upload" ng-click="uploadFile($event)" name="upload">
</fieldset>
</form>
This is my function which I'm hopping to get the form data from
$scope.uploadFile = function(e) {
e.preventDefault();
//$scope.form.preventDefault();
var dCheck = $('input[type="file"]').val();
console.log(e.currentTarget);
var form = $('#uploadForm').serializeArray();
console.log(form);
}
form returns an empty array any help with this would be appreacited
Why not think in pure angular way?
use can use
<input type="file" ng-model="filePath">
And next, get the file name in $scope.filePath

Text form that follows link

I have to create a form with a submit bottom following a link
<form action="http://domain/**(((MY TEXT INPUT VALUE)))**.htm">
<input type="text" name="verb">
<input type="submit" value="Conjugate">
</form>
something like this.
please note that every link should be different.
I also want that the new page be opened in a new tab/window
could you please help me, and also make changes to the form code if there is sth under newer standards. Thank you!
You need to use javascript to get the TEXTBOX value and then place it into the form action.
You can create the submit button with an onclickevent.
Or you can use jQuery
$('#btnSubmit').click(function(){
var sTextValue = $("#MyText").val();
$('#MyForm').attr('action', 'htttp://domain/' + sTextValue + '.htm');
$('#MyForm').submit();
});
And the HTML
<form id="MyForm" action="">
<input id="MyText" type="text" name="verb">
<input id="btnSubmit" type="button" value="Conjugate">
</form>
There are many ways to accomplish this. That's just one of them.
<form action="http://domain/**(((MY TEXT INPUT VALUE)))**.htm" id="btnForm">
<input type="text" name="verb" onchange='javascript:document.getElementById("btnForm").action = "http://domain/"+ this.value +".htm"'>
<input type="submit" value="Conjugate" >
</form
This would update as soon you type the text. It wouldn't require jquery. it makes use of onchange event handler of input type text
<form action="http://domain/**(((MY TEXT INPUT VALUE)))**.htm" id="btnForm">
<input type="text" name="verb" onchange='updateFormAction(this.value)'>
<input type="submit" value="Conjugate" >
</form>
<script type="text/javascript">
function updateFormAction(value){
var btnForm = document.getElementById("btnForm");
btnForm.action = "http://domain/"+ value +".htm";
}
</script>
This is more explanatory form. Its based on onchange event handler for text types.