How to pass parameter to a java function in JSP scriptlet? - scriptlet

I want to pass the value of assembler.area.id, sent by controller to the java function getIsAreaWaitTimeActiveByAreaId(), inside scriptlet. I am not sure how to do so. getIsAreaWaitTimeActiveByAreaId() takes in Long.
<c:set var="isWaitTimeActive" value="${assembler.area.id}" scope="page"/>
<%#page import="com.ihc.wtrack.service.impl.ReportServiceImpl"%>
<%
ReportServiceImpl reportController = new ReportServiceImpl();
boolean isActive = reportController.getIsAreaWaitTimeActiveByAreaId(isWaitTimeActive);
%>
Thanks.

Related

Is there a method to write a response in an EJS template?

With classic ASP you can do a response.write('foo') inside <% ... %>. Is this possible with EJS?
The current workaround is to use 2 tags, one for logic, one for output:
<%
let someString = generateSomeStringHere()
%>
<%- someString %>
I do understand that some will recommend generating someString outside of the template but let's say for the sake of argument that is not desirable.
We would like to do:
<%
let someString = generateSomeStringHere()
ejs.write(someString);
%>

Working aroung passing an Implicit parameter to every single template

I'm doing some work with PlayFramework templates, but I have encountered a problem. We're using play's helpers which requires Messages (imported from play.api.i18n). Everything was ok until our Designer wanted to have login form in form of Modal... Because it'll be appended to every single template, we'll need to add that messages parameter everywhere - which is ugly IMHO.
Is there a way to work that around? Passing it everywhere would mean that I have to Inject() it everywhere, even if it's needed only to be passed to shut the typechecker.
Sample Page:
#(project: model.Project)(implicit request: Request[AnyContent], messages: Messages)
#main(project.name){
<h1>#project.name</h1>
<ul>
#for(member <- project.members) {
<li>#member</li>
}
</ul>
}{}
Fragment of Main template:
#(title: String)(content: Html)(additionalImport: Any)(implicit req: Request[AnyContent], messages: Messages)
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
#* this call actually needs that param. *#
#header.navbar()
<div class="container">
#req.flash.get("error").map { error =>
<div class="flash-error">#error</div>
}
#content
</div>
</body>
</html>
The Form:
#import model.UserLoginData
#(loginForm: Form[UserLoginData])(implicit req: Request[AnyContent], messages: Messages)
#helper.form(action = routes.AuthenticationController.login()) {
#loginForm.globalErrors.map { error =>
<div class="error">#error.message</div>
}
#helper.inputText(loginForm("login"))
#helper.inputPassword(loginForm("password"))
<input type="submit" value="Zaloguj"/>
}
Zapomniałem hasła
Here I see two work arounds. Unfortunately, I am not able to test them now, but I believe they will both work.
Get rid of the messages parameter from the form template. Use Play.current.injector.instanceOf[MessagesApi] to get MessagesApi implementation just inside the template (here is a question about accessing injector without an #Inject annotation). Then you may call the method preferred(Http.RequestHeader request):Messages to get a Messages instance, and then you need to explicitly pass this to a helper method.
If you just want to get rid of injection and you don't mind passing an implicit messages parameter to every single template, you may implement your own version of the I18nSupport trait. Here I mean that you usually write the controller in the following way:
class SomeController #Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport. The messagesApi val overrides the same value of the I18nSupport trait. You may extend this trait with your own MyI18Support trait, and inject MessagesApi inside it (UPD: you may either #Iinject or use Play.current.injector). Then you will only need to write the controller as follows: class SomeController extends Controller with MyI18nSupport.

How to access controller variable without passing to Play html

Is it possible to access Play Framework scala contoller variables wihout passing to scala.html template?
For example my controller code as below,
def index = Action { request =>
val orgId = '12132132'
Ok(views.html.index(request))
}
My index.scala.html as below,
#(implicit request: RequestHeader)
#main("Test") {
I want to access controller "orgId" variable here wihtout passing here.
}
Here is my main.scala.html,
#(title: String)(content: Html)
<html lang="en">
<head>
<title>#title</title>
</head>
<body>
#content <!-- index.html placed here -->
</body>
<div>
Here I have bootstrap side menu and I want to display controller variable here without passing to main.scala.html templete.
</div>
</html>
Thanks.
You cannot do it since it private for the function. No other function can access it (even not in the same class).
If you are using object as instance of the controller (instead of class) and you use value of the object itself then you can do it, but It HIGHLY NOT recommended.
e.g.
object MyController extends controller {
val orgId = '12132132'
def index = Action { request =>
Ok(views.html.index(request))
}
...
}
#(implicit request: RequestHeader)
#main("Test") {
I want to access controller "#{MyController.orgId}" variable here without passing here.
}
If you need to pass some data that isn't depend on the request, meaning it can be value of the object, then it also may be outside the controller. So you can create an object that will hold those values, and access them.
Technically it the same as use the controller, but logically it better separation.

Binding an html form action to a controller method that takes some parameters

In my Find controller I have a method like:
public Result findLatest(String repoStr) {
............
}
Which is linked through a route:
GET /latest controllers.Find.findLatest(repo: String)
Then, I have a form in a view like:
<form action="#routes.Find.findLatest()" method="get">
....
<select name="repo">....</select>
</form>
But obviously that is failing, because it is expecting some parameters that I do not fulfill in the action. What is the correct way to do this without having to end up leaving the findLatest method taking no parameters in my controller?
You could change the routes to accept an empty string:
GET /latest/:repo controllers.Find.findLatest(repo: String = "")
Then configure your controller function to handle empty string.
That way,
<form action="#routes.Find.findLatest()" method="get">
....
<select name="repo">....</select>
will evaluate repo as an empty string at the controller level.
Edit: Support for this implementation was dropped in Play v 2.1
You may be interested in Play's Optional parameters e.g. play.libs.F.Option[String]
Example: How to handle optional query parameters in Play framework
GET /latest/:repo/:artifact controllers.Find.findLatestArtifact(repo: play.libs.F.Option[String], artifact: play.libs.F.Option[String])
This will allow you flexibility in which arguments need to be provided.
Not sure which language you're using but the link above contains an example for scala and the method declaration in java would look something like:
import play.libs.F.Option;
public static Result findLatestArtifact(Option<String> repo, Option<String> artifact){ ... }
and updated implementation 2.1
Routes with optional parameter - Play 2.1 Scala
EDIT: play 2.1+ Support : Props to #RobertUdah below
Initializing to null:
GET /latest/ controllers.Find.findLatest(repo: String = null)
GET /latest/:repo controllers.Find.findLatest(repo: String)
<form action="#routes.Find.findLatest()" method="get">
Normally all form data go in the body and you can retrieve them in your action method with bindFromRequest() (see docs).
If you really want to pass one form element as a part of the URL then you have to dynamically compose your URL in JavaScript and change your route.
Your route could look like:
GET /latest/:repo controllers.Find.findLatest(repo: String)
And the JavaScript part like (I didn't actually test the code):
<form name="myform" action="javascript:composeUrl();" method="get">
....
<select name="repo">....</select>
</form>
<script>
function submitform() {
var formElement = document.getElementsByName("myform");
var repo = formElement.options[e.selectedIndex].text;
formElement.action = "/lastest/" + repo;
formElement.submit();
}
</script>
Cavice suggested something close to what I consider the best solution for this (since F.Option are not supported anymore with the default binders in Play 2.1 ).
I ended up leaving the route like:
GET /latest controllers.Find.findLatest(repo=null)
and the view like:
<form action="#routes.Find.findLatest(null)" method="get">
<select name="repo"> .... </select>
....
</form>
and in the controller:
public Result findLatest(String repoStr) {
if(repoStr==null) {
repoStr=Form.form().bindFromRequest().get("repo");
.....
This allows me to have a second route like:
GET /latest/:repo controllers.Find.findLatest(repo: String)

mvc2 dropdownlist dynamic parameters

<% string disabled="new {disabled='disabled'}"; %>
<%= Html.DropDownList("clientId", someObject, disabled)%>
In the above code I want the text disabled to be replaced by what ever value I set that string to. When I check the HTML source on the page, I see that new {disabled='disabled'} has been added as a new item in the dropdown list instead of a property. How do I fix this?
The third parameter of DropDownList helper must be an object that contains the HTML attributes or object of type IDictionary<string, object>.
This is the proper solution:
<% var disabled = new { disabled = "disabled" }; %>