How to pass raw html to Play framework view? - java

I'm trying to pass a simple URL to a view within a play framework app, however when passed as a string, the & in the url is changed to & which causes the URL to not work.
If I change the argument to Html, i.e #(url: Srting) to #(url: Html), then I get an error when I try to pass the url as string to view.render() method.
How can I convert the url into Html and pass it as that?

To prevent the default escaping that happens for dynamic content on views you need to wrap the String with #Html(String) function:
View:
#(url: String)
<div class="myLink">
Go to: #Html(url) <br>
not to: #url
</div>
Controller:
public static Result displayLink(){
return ok(view.render("<a href='http://stackoverflow.com/'>Stack Overflow</a>"));
}
See The template engine page on the documentation for more info (specifically the "Escaping" section at the very bottom).

If you want to render HTML content instead of displaying it as raw text, return the content .as("text/html"). Example:
WS.url("http://www.stackoverflow.com").get().map(resp => Ok(resp.body).as("text/html"))

Related

Thymeleaf: Unencode or Encode URL on client

I am using Thymeleaf as the front end.
I have some menu categories in natural language that I display on a web page and pass to the server.
For example, I have a category of "My favourite cats"
The category is in a variable ${category.key}
This category has a link;
<a th:href="|http://myserver?selectedCategory=${category.key}|><span th:text=${category.key}></span></a>
If I do not URLEncode ${category.key} on the server, then when a
user clicks the link, the selectedCategory parameter is null if there
is a whitespace in the category string.
If I encode the category string, the selectedCategory parameter
passes to the server fine BUT the link text appears as
My+favourite+cats
I don't want two variables, one encoded, one not encoded.
How do I either encode or unencode ${category.key} as part of the Thymeleaf HTML compilation process?
#symbol is Server Context path in Thymeleaf. you use #symbol.
<a href="#" th:href="#{/your server context path?selectedCategory=__${category.key}__}">
<span th:text="${category.key}"> </span></a>
Thymeleaf will url encode strings if you build them with url syntax (which was supplied in a comment above). For your example url, it should look like this -- using the # symbol instead of the $:
<a th:href="#{http://myserver(selectedCategory=${category.key})}" th:text="${category.key}" />
(Also, you don't need that extra span.)
Using the #symbol is definitely the primary alternative. But just to note another option that may be of use on occasions:
The answer is to use the lesser know #strings functions to replace the '+' with ' '
In the link text, use
th:text="${#strings.replace(category.key,'+',' ')}"

Grails get url of originating controller

I have a URL say abc.com/somecontroller?someparam=1 which renders a form. Form on submit sends the form params to /ajaxAction
Is there a way I could get this abc.com/somecontroller?someparam=1 (i.e. the form URL?)
I am more interested in getting the someparam value from the URL of the form.
PS: the above URL abc.com/somecontroller?someparam=1 is dynamically generated, so I can not access it otherwise.
And request.forwardURI will give me /ajaxAction (i.e. the URL of the action in form and not the url of the form itself).
EDIT:
I have no control over form as it is also dynamic and user has hundreds of templates to select from. Each template has different no. of fields.
So if I would prefer some other way to get the URL.
Why don't you use javascript in form and add to ajax request array with GET params? (or with the url of the action which generated form)
You can get them from original request f.e. by this script.
While rendering the GSP of your form, you can do like this:
myaction.gsp
<html>
<body>
<!-- Your content -->
<script>
var paramsString = '${params.collect { k, v-> "$k=$v" }.join​​​​​​​​​​​​​​​​​​​​​​("&")​​​ }';
</script>
</body>
</html>
So, when you GSP is rendered, the script tag will have something like this (for a URL abc.com/somecontroller?someparam=1&foo=2:
var paramsString = 'someparam=1&foo=2';
Now, in your AJAX code, you can pass that string as the query arguments:
$.ajax({
url: '/ajaxAction?' + paramsString
/* rest of the AJAX code */
});
Now, in your ajax controller action, you can simply do the params.someparam.
EDIT
Well, I just realized that you don't have to any GSP stuff I mentioned above. Simply do the AJAX call like this:
$.ajax({
url: '/ajaxAction' + location.search
/* rest of the AJAX code */
});
The location.search will give you the direct string: ?someparam=1&foo=2
I ended up using flash to store the someparam
In my controller which is being used to render the form at abc.com/somecontroller?someparam=1 I use flash as this:
flash.put("someparam", params.someparam)
This worked as a quick workaround to the issue. I feel this would work well in situations where I have no control over the gsp.
If anyone finds any issue, please comment otherwise I will mark this as the answer.

send HTML from servlet to JSP dynamically

Is there an easy way to send HTML from a servlet to a JSP, using AJAX.
I've already figured out how to make AJAX work with servlets dynamically, but now I want to press a button on a form and generate HTML based on text-input.
Is it possible, and if so, how, to send just pieces of HTML to an existing HTML page?
Example,
I have a basic form where you can input your age, and based on the age the text has a different size/color. So, you send for example, 25 as your age to the servlet, and it send back a piece of HTML like this <p STYLE="font-size: age;"> to the page.
Through ajax call you can get the output result either a string, html or a Json object that will be parsed and results can be displayed over JSP/HTML. So for sure you can send html code segment from servlet to jsp through ajax call.
For example you can use this approach--
1. Take a string variable in your servlet.
2. Put appropriate html string as per your conditions in this string variable
3. send this string as a response from servlet like:
response.setCharacterEncoding("UTF-8");
response.getWriter().write("your string variable here");
4. In your ajax call do like this:
success : function(dataString) {
document.getElementById("containerId").innerHTML=dataString;
},
where containerId is the id of html element (like div or span) where you want to display output html.
The easiest approach, without client-side javascript libraries, would be to point an HTML form to an iframe, just like
<iframe name="myIframe"...>
<form target="myIframe"...>
And submit your form as many times as necessary. The HTML returned by the servlet would load itself in the iframe element.
If you like AJAX and client-side javascript libraries, you can find very easy programmatical ways to do this in jQuery and similar libraries.
Basically your servlet can generate any kind of content, e.g. JSON, HTML etc.
You'd then send that content back to the client and integrate it into the page.
How that is done depends on the type of content.
Example:
You issue an AJX request (e.g. by using jQuery's ajax functionality) and your servlet generates plain html. When your JavaScript receives the anser you just replace the relevant part, e.g. by replacing the content of some defined element.
If you used JSON instead, your servlet might send data only instead, e.g. a font size based on the age as in your example. You'd then use JavaScript to access that JSON data and perform relevant operations, e.g. by changing the style of the paragraph.

Java custom tag with JS

I have custom tag which contains form with text input and submit. I want to validate this text input using JS, so my custom tag output should look like:
<script type="text/javascript">
function validate(form) {
var text = form.textInput;
// validation code
}
</script>
<form onsubmit='return validate(this);'>
<input type='text' name='textInput'/>
<input type='submit'/>
</form>
(Note, this code simplified!)
My problem appears when I want to use this tag twice or more times at page - I want to print form at page again, but not JS validation code! Validation code must be unique at the page. How can I archive that? My custom tag extends javax.servlet.jsp.tagext.TagSupport
I found the most suitable solution for me.
Class javax.servlet.jsp.tagext.TagSupport contains protected field pageContext which presents... page context! I can easily access context attributes of javax.servlet.jsp.PageContext. So, I put next code in my custom tag:
public int doStartTag() throws JspException {
if (pageContext.getAttribute("validated") == null) {
// validation code writing
pageContext.setAttribute("validated", true);
}
...
}
If condition would be reachable only once per page rendering.
Hope it would be useful for someone.
I suggest you to try to embed that JavaScript function in some .js file an import that file. If you don't want to do that, for some reason you should try to define that function dynamically, if it is not defined:
if (typeof window.validateMyForm === 'undefined') {
window.validateMyForm = function(form) {
var text = form.textInput;
// validation code
}
}
As you guess this should define function only if it is not already defined.
First answer is correct, but that means that programer must know where in code are already inserted custom tags and according to that this whether to set that parameter to true or false. And what about code changes, you will have to always go thought whole page and revise all used tags on a page.
Make the custom tag to accept a parameter that toggles the validation on or off, and of course have it generate different code depending on the value of the parameter.

How to pass a parameter to the template I'm extending, and use it inside a template?

I'm using a master template for all our emails. I would like this master template to use an ID field that is passed along from the concrete template:
some-email.html
#{set 'emailId'}1{/set}
#{extends 'app/views/Mails/mail-main.html' /}
...
mail-main.html (this is the master template)
// Here, I would like to use the emailId parameter inside another template.
// Specifically, a link I'm rendering
<a href="##{Foo.bar(emailId)}`>Link text</a>
But, if I understand correctly, that's not how the set and get template works - they only allow me to embed the object in the template text in the template that uses get, not to pass it along to other templates.
Is there a simple way to do what I seek?
You can just write the following, in mail-main.html:
Link text

Categories

Resources