I have a freemarker macro like this.
<#assign xmlNode = parseXML("<field name='dropDown' type='select' valueName='COUNTRY'/>")>;
<#import "utilFields.ftl" as util />
<div>
<#util.createDropdown field=xmlNode/>
</div>
How would I call the same macro from Javascript?
Tried:
<#assign xmlNode = parseXML("<field name='dropDown' type='select' valueName='COUNTRY'/>")>;
<script type="text/javascript">
var dropdown = "${util.createDropdown(xmlNode)}";
alert(dropdown);
</script>
Error
FreeMarker template error:
A macro cannot be called in an expression.
I assume you want to insert the HTML generated by #util.createDropdown into the JavaScript string literal. (You can't literally call FreeMarker form JavaScript, since the two run at different times.) The naive approach is just:
<#-- Not safe! -->
var dropdown = "<#util.createDropdown field=xmlNode/>";
The problem is that util.createDropdown writes HTML to the output, and HTML not in general valid as is inside a JavaScript string literal, because you can have " in it and so on. You can do a trick like this though:
<#macro jsStr>
<#local captured><#nested></#local>
"${captured?js_string}"<#t>
</#macro>
...
var dropdown = <#jsStr><#util.createDropdown field=xmlNode/></#>;
The jsStr macro converts the content printed inside it (and it need not be a single macro call inside it, it can be anything) to a valid JavaScript string literal.
Related
I am wondering if how am i able to change the element data by .replace() if i use handlebar js to generate html elements.
For instance i have this role of p tag which display a row of data by handlebar js:
<p id="pre-region">{{region}}</p>
and the result of it is
1,44
and i 'd like to change it to
1+44
If you haven't had any experience of handlebar js then consider the tag be
<p id="pre-region">1,44</p>
how should i change from 1,44 to 1 +44?
UPDATE 1
Here should be an extersion for my question. I am passing the HTML element inside pre-region into an href in order to update my website by Ajax.
After i have converted all the comma in to "+" the API retrieve special character "&B2" which equal to the symbol "+" and the API goes error.
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all®ion=1%2B4
This is how may API looks like at the moment
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all®ion=1+4
should be the solution
I haven't had any experience of handlebars.js but from my point of view, you can just put the code just before the </body>:
<script>
var node = document.getElementById('pre-region');
node.innerHTML = node.innerHTML.replace(',', '+');
</script>
I'll check out the handlebars js in case it does not work.
Update:
As you mentioned in the comment, if you need to use it in the HTTP request/URL, you may handle the string using decodeURIComponent(yourstring):
decodeURIComponent('1%2B44'); // you get '1+44'
Read more about decodeURIComponent() method from this. In URL, it should be encoded as region=1%2B44 in your case; while it should be decoded if you want to use it in your JavaScript code or display in the web page.
Update 1
You should encode your string when it's used as a part of parameter of HTTP request. Therefore, it looks good if the URL is:
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all®ion=1%2B4
What you need to do is decode the string on your server side. I assume that you are in control of the server side. If you are using Node.js, you can just use decodeURIComponent() method to decode the parameter. If you're using Python or PHP as your server language, it should be something like decodeURIComponent() in that language.
Update 2
The solution above only replace the first occasion of comma to +. To solve that, simply use:
<script>
var node = document.getElementById('pre-region');
node.innerHTML = node.innerHTML.replace(/,/g, '+');
// Regular Expression is used here, 'g' for global search.
</script>
PHP has a replaceAll() method, so we can add that method to String.prototype like below if you want:
<script>
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
}
// Another method to replace all occasions using `split` and `join`.
</script>
Alright, so this is my first answer ever on stack overflow so I'm alien to this whole thing but here we go:
You could try this code in another js file that runs after handlebars:
var pre = $('#pre-region'); // defines a variabe for the element (same as
// document.getElementById('pre-region'))
var retrievedRegion = pre.innerHTML;
var splitten = retrievedRegion.split(',');
var concatenated = parseInt(split[0]) + parseInt(split[1])
retrievedRegion.innerHTML = "'" + concatenated) + "'";
or using replace():
retrievedRegion.replace(',','+')
I'm trying to print java string return values into script java .
this is my method in java class
public static String getchamps (){ //Bdconnection class
String str;
{
str = "date" ;
}
return str ;
}
the question is how can i have this code
<script type="text/javascript" >
"date"
</script>
You should in this context look at JSF as a HTML code generator. You can use JSF tags/components and EL expressions to let it produce the desired HTML output. As JavaScript is as being a client side language technically part of HTML (not of JSF!), you can just do the same for JavaScript.
Once you fix that bad static method to really comply the Javabeans specification as below:
public String getChamps() {
return "date";
}
Then you can just let JSF print it as if it's a JS variable as below:
<script>
var champs = "#{bean.champs}";
</script>
To verify the result, just open the JSF page in webbrowser and do rightclick, View Source. You should see something similar to:
<script>
var champs = "date";
</script>
Beware of JS-special characters in the string though! This would fail if the string contains e.g. a doublequote or even a newline. If that's the case, then you'd better escape it using an EL function as shown in this answer: Escape JavaScript in Expression Language.
Do this:
<h:inputText id="propertyId" value="#{Bdconnection.str}" />
and access in script
document.getElementById('propertyId').val();
I am trying to print the result of cgi script inside a <div> in html page using the code
HTML
<b>Already Loaded Data</b>
<div id="result"></div>
JS
<script type="text/javascript" >
var fdate='document.ccform.cdt.value';
var tdate='document.ccform.cdt.value';
$( "#result" ).load( "../cgi-bin/coll.cgi?ctype=''&cdet=''&fdt=$fdate&tdt=$tdate" );
</script>
Note:- The HTML form name is ccform and the date field name is cdt.Coll.cgi takes four values which are ctype, cdet, fdt and tdt.
fdt and tdt are dates.
I presume the syntax of date field needs to be corrected.
There is a lot wrong here. You cannot interpolate variables into strings with $ this way, and you cannot access values from variables using 'document.ccform.cdt.value'. You also don't need to supply empty values ('') for your empty query string variables.
You seem to be lacking an understanding of what strings are and how they work; nothing anywhere in JavaScript would suggest that 'fdt=$fdate' would be a correct way of building a query string, or that you can access a variable using 'document.ccform' instead of document.ccform. You should read a tutorial on JavaScript rather than trying to feel your way around these fundamental syntax issues.
Your code should look something like this:
var fdate = document.ccform.cdt.value;
var tdate = document.ccform.cdt.value;
$("#result").load( "../cgi-bin/coll.cgi?ctype=&cdet=&fdt=" + fdate + "&tdt=" + tdate );
In my MVC view am having the below piece of code
<script type="text/javascript">
#foreach (var item in Model.Test)
{
<text> jsFunction(#item.someValue); </text>
}
</script>
Where am calling the Javascript function based on the data i get from model dynamically.
For Example At run time it is rendered like below based on the model data
jsFunction("Works Fine");
jsFunction("works Fine");
Which correctly calls my javascript function
But in case of a new line getting "unterminated string literal" because of the new line
jsFunction("not working
with new line");
What is the best way to handle this Scenario
Thanks
What is the best way to handle this Scenario
Use a JSON serializer which will ensure that the value passed to your javascript function is properly escaped:
<script type="text/javascript">
#foreach (var item in Model.Test)
{
<text>jsFunction(#Html.Raw(Json.Encode(item.someValue)));</text>
}
</script>
or if you update your jsFunction to take an array instead of a single item you could do this:
<script type="text/javascript">
var values = #Html.Raw(Json.Encode(Model.Test));
jsFunction(values);
</script>
and then loop through the normal javascript array that will be passed to your function.
P.S: Don't worry if Razor Intellisense is putting a red squiggle around this code. Visual Studio Intellisense in Razor views doesn't work well. Just ignore the warning and run your application and observe the properly generated code.
Simplest solution is to create a helper or something:
#* declared at top of razor page *#
#helper jsFunction(String str)
{
str = (str ?? String.Empty).Trim().Replace(Environment.NewLine, "\\n");
#:jsFunction("#Html.Raw(str)");
}
#* example usage *#
foreach (var item in Model.Test)
{
#jsFunction(#item.Comment)
}
That would perform sanitization on the string to make it convert \n in to the JavaScript counter-part \\n. You may also include exceptions for quotation marks (turn " into \", etc.)
The better alternative is to use something like JSON.NET though:
<text>jsFunction(#Html.Raw(JsonConvert.Serialize(#item.Comment)))</text>
That would make it completely safe to JavaScript (and handle the exceptions for you).
try this
jsFunction(#Html.Raw(Json.Encode(item.Comment)))
I think this should solve your issue.
I'm writing some Javascript code for an ASP.net page.
I have the string "foo" assigned to a string variable myString.
I would like to assign the value of myString to a JavaScript variable, so I write in my ASP.net code:
<script type='txt/javascript' language='javascript'>
var stringFromDotNet = '<%=myString%>';
</script>
This works fine as long as myString does not contain quotation marks or line-breaks, but as as soon as I try to assign something with quotation marks or line-breaks, all hell breaks loose and my code doesn't work. As a matter of fact, I can see that this code is vulnerable to all sort of injection attacks.
So... What can I do get the value of myString assigned to a variable in JavaScript?
Update: I've tried creating a page with just an ASP:Hidden field. It looks like the values inside are html encoded.
You could use JavaScriptSerializer and that's guaranteed to be safe against XSS:
<script type="text/javascript">
var stringFromDotNet = <%= new JavaScriptSerializer().Serialize(myString) %>;
</script>
This approach also allows you to pass complex objects and not just plain strings:
<script type="text/javascript">
var complexObjectFromDotNet = <%= new JavaScriptSerializer().Serialize(new { id = 123, name = "foo\"' <bar>" }) %>;
alert(complexObjectFromDotNet.name);
</script>
I think this may be the answer are looking for: http://www.velocityreviews.com/forums/t70655-escape-function-in-asp-net.html#edit352659. Basically, encode the value on the server side and unencode it with JavaScript:
var stringFromDotNet = decodeURI(<%=Server.URLEncode(myString)%>);
This will ensure that quotes and other dangerous characters won't break your script, or open up attack vectors.
You could either assign the js variable using double quotes like so
var stringFromDotNet = "<%=myString%>";
Or you could escape the single quotes and replace line breaks with literal "\r\n" in your string in the server side.