I'm creating a software using CefSharp and needs to executes some JS code. What I'm doing for now is to write the script using only one line, but it's not convenient and it makes it hard to apply modifications.
Here is the JS script from file that I tried to execute :
console.log(size) //size.Text is the variable defined in C#
But as the size variable is defined in c#, the output I get is undefined.
Here is the code I use to load the file :
string size = "XL";
string testJs = Path.Combine(Environment.CurrentDirectory, #"Data\", "test.js");
string test = File.ReadAllText(testJs);
browser.ExecuteScriptAsyncWhenPageLoaded(test);
And the one that would work (the one-lined one) :
browser.ExecuteScriptAsyncWhenPageLoaded("console.log(" + size + ");")
So the main problem is to pass the variable to have XL as an output in the console of the browser.
Considering that size is passed from C# code, what you need in the js file is a placeholder which later can be replaced.
One possible solution might be -
JS File
console.log('#{SIZE}#');// you can use any formatting for your placeholder
C# Code
string size = "XL";
string testJs = Path.Combine(Environment.CurrentDirectory, #"Data\", "test.js");
string test = File.ReadAllText(testJs).Replace("#{SIZE}#", size);
browser.ExecuteScriptAsyncWhenPageLoaded(test);
This approach will allow you to use as many placeholders as you want in your js file and as many number of places you want to use them.
Are you passing a view model to a Razor template? If so, you can use razor syntax within script tags:
<script>
console.log(#Model.size);
</script>
Related
I have a form in JSP. I have to populate it based on the request object (from the servlet). How do I use Java Script for accessing request object attributes or if you can suggest me any other better way to populate form dynamically?
You need to realize that Java/JSP is merely a HTML/CSS/JS code producer. So all you need to do is to just let JSP print the Java variable as if it is a JavaScript variable and that the generated HTML/JS code output is syntactically valid.
Provided that the Java variable is available in the EL scope by ${foo}, here are several examples how to print it:
<script>var foo = '${foo}';</script>
<script>someFunction('${foo}');</script>
<div onclick="someFunction('${foo}')">...</div>
Imagine that the Java variable has the value "bar", then JSP will ultimately generate this HTML which you can verify by rightclick, View Source in the webbrowser:
<script>var foo = 'bar';</script>
<script>someFunction('bar');</script>
<div onclick="someFunction('bar')">...</div>
Do note that those singlequotes are thus mandatory in order to represent a string typed variable in JS. If you have used var foo = ${foo}; instead, then it would print var foo = bar;, which may end up in "bar is undefined" errors in when you attempt to access it further down in JS code (you can see JS errors in JS console of browser's web developer toolset which you can open by pressing F12 in Chrome/FireFox23+/IE9+). Also note that if the variable represents a number or a boolean, which doesn't need to be quoted, then it will just work fine.
If the variable happens to originate from user-controlled input, then keep in mind to take into account XSS attack holes and JS escaping. Near the bottom of our EL wiki page you can find an example how to create a custom EL function which escapes a Java variable for safe usage in JS.
If the variable is a bit more complex, e.g. a Java bean, or a list thereof, or a map, then you can use one of the many available JSON libraries to convert the Java object to a JSON string. Here's an example assuming Gson.
String someObjectAsJson = new Gson().toJson(someObject);
Note that this way you don't need to print it as a quoted string anymore.
<script>var foo = ${someObjectAsJson};</script>
See also:
Our JSP wiki page - see the chapter "JavaScript".
How to escape JavaScript in JSP?
Call Servlet and invoke Java code from JavaScript along with parameters
How to use Servlets and Ajax?
If you're pre-populating the form fields based on parameters in the HTTP request, then why not simply do this on the server side in your JSP... rather than on the client side with JavaScript? In the JSP it would look vaguely like this:
<input type="text" name="myFormField1" value="<%= request.getParameter("value1"); %>"/>
On the client side, JavaScript doesn't really have the concept of a "request object". You pretty much have to parse the query string yourself manually to get at the CGI parameters. I suspect that isn't what you're actually wanting to do.
Passing JSON from JSP to Javascript.
I came here looking for this, #BalusC's answer helped to an extent but didn't solve the problem to the core. After digging deep into <script> tag, I came across this solution.
<script id="jsonData" type="application/json">${jsonFromJava}</script>
and in the JS:
var fetchedJson = JSON.parse(document.getElementById('jsonData').textContent);
In JSP file:
<head>
...
<%# page import="com.common.Constants" %>
...
</head>
<script type="text/javascript">
var constant = "<%=Constants.CONSTANT%>"
</script>
This constant variable will be then available to .js files that are declared after the above code.
Constants.java is a java file containing a static constant named CONSTANT.
The scenario that I had was, I needed one constant from a property file, so instead of constructing a property file for javascript, I did this.
In JSP page :
<c:set var="list_size" value="${list1.size() }"></c:set>
Access this value in Javascipt page using :
var list_size = parseInt($('#list_size').val());
I added javascript page in my project externally.
I have a form in JSP. I have to populate it based on the request object (from the servlet). How do I use Java Script for accessing request object attributes or if you can suggest me any other better way to populate form dynamically?
You need to realize that Java/JSP is merely a HTML/CSS/JS code producer. So all you need to do is to just let JSP print the Java variable as if it is a JavaScript variable and that the generated HTML/JS code output is syntactically valid.
Provided that the Java variable is available in the EL scope by ${foo}, here are several examples how to print it:
<script>var foo = '${foo}';</script>
<script>someFunction('${foo}');</script>
<div onclick="someFunction('${foo}')">...</div>
Imagine that the Java variable has the value "bar", then JSP will ultimately generate this HTML which you can verify by rightclick, View Source in the webbrowser:
<script>var foo = 'bar';</script>
<script>someFunction('bar');</script>
<div onclick="someFunction('bar')">...</div>
Do note that those singlequotes are thus mandatory in order to represent a string typed variable in JS. If you have used var foo = ${foo}; instead, then it would print var foo = bar;, which may end up in "bar is undefined" errors in when you attempt to access it further down in JS code (you can see JS errors in JS console of browser's web developer toolset which you can open by pressing F12 in Chrome/FireFox23+/IE9+). Also note that if the variable represents a number or a boolean, which doesn't need to be quoted, then it will just work fine.
If the variable happens to originate from user-controlled input, then keep in mind to take into account XSS attack holes and JS escaping. Near the bottom of our EL wiki page you can find an example how to create a custom EL function which escapes a Java variable for safe usage in JS.
If the variable is a bit more complex, e.g. a Java bean, or a list thereof, or a map, then you can use one of the many available JSON libraries to convert the Java object to a JSON string. Here's an example assuming Gson.
String someObjectAsJson = new Gson().toJson(someObject);
Note that this way you don't need to print it as a quoted string anymore.
<script>var foo = ${someObjectAsJson};</script>
See also:
Our JSP wiki page - see the chapter "JavaScript".
How to escape JavaScript in JSP?
Call Servlet and invoke Java code from JavaScript along with parameters
How to use Servlets and Ajax?
If you're pre-populating the form fields based on parameters in the HTTP request, then why not simply do this on the server side in your JSP... rather than on the client side with JavaScript? In the JSP it would look vaguely like this:
<input type="text" name="myFormField1" value="<%= request.getParameter("value1"); %>"/>
On the client side, JavaScript doesn't really have the concept of a "request object". You pretty much have to parse the query string yourself manually to get at the CGI parameters. I suspect that isn't what you're actually wanting to do.
Passing JSON from JSP to Javascript.
I came here looking for this, #BalusC's answer helped to an extent but didn't solve the problem to the core. After digging deep into <script> tag, I came across this solution.
<script id="jsonData" type="application/json">${jsonFromJava}</script>
and in the JS:
var fetchedJson = JSON.parse(document.getElementById('jsonData').textContent);
In JSP file:
<head>
...
<%# page import="com.common.Constants" %>
...
</head>
<script type="text/javascript">
var constant = "<%=Constants.CONSTANT%>"
</script>
This constant variable will be then available to .js files that are declared after the above code.
Constants.java is a java file containing a static constant named CONSTANT.
The scenario that I had was, I needed one constant from a property file, so instead of constructing a property file for javascript, I did this.
In JSP page :
<c:set var="list_size" value="${list1.size() }"></c:set>
Access this value in Javascipt page using :
var list_size = parseInt($('#list_size').val());
I added javascript page in my project externally.
I have a form in JSP. I have to populate it based on the request object (from the servlet). How do I use Java Script for accessing request object attributes or if you can suggest me any other better way to populate form dynamically?
You need to realize that Java/JSP is merely a HTML/CSS/JS code producer. So all you need to do is to just let JSP print the Java variable as if it is a JavaScript variable and that the generated HTML/JS code output is syntactically valid.
Provided that the Java variable is available in the EL scope by ${foo}, here are several examples how to print it:
<script>var foo = '${foo}';</script>
<script>someFunction('${foo}');</script>
<div onclick="someFunction('${foo}')">...</div>
Imagine that the Java variable has the value "bar", then JSP will ultimately generate this HTML which you can verify by rightclick, View Source in the webbrowser:
<script>var foo = 'bar';</script>
<script>someFunction('bar');</script>
<div onclick="someFunction('bar')">...</div>
Do note that those singlequotes are thus mandatory in order to represent a string typed variable in JS. If you have used var foo = ${foo}; instead, then it would print var foo = bar;, which may end up in "bar is undefined" errors in when you attempt to access it further down in JS code (you can see JS errors in JS console of browser's web developer toolset which you can open by pressing F12 in Chrome/FireFox23+/IE9+). Also note that if the variable represents a number or a boolean, which doesn't need to be quoted, then it will just work fine.
If the variable happens to originate from user-controlled input, then keep in mind to take into account XSS attack holes and JS escaping. Near the bottom of our EL wiki page you can find an example how to create a custom EL function which escapes a Java variable for safe usage in JS.
If the variable is a bit more complex, e.g. a Java bean, or a list thereof, or a map, then you can use one of the many available JSON libraries to convert the Java object to a JSON string. Here's an example assuming Gson.
String someObjectAsJson = new Gson().toJson(someObject);
Note that this way you don't need to print it as a quoted string anymore.
<script>var foo = ${someObjectAsJson};</script>
See also:
Our JSP wiki page - see the chapter "JavaScript".
How to escape JavaScript in JSP?
Call Servlet and invoke Java code from JavaScript along with parameters
How to use Servlets and Ajax?
If you're pre-populating the form fields based on parameters in the HTTP request, then why not simply do this on the server side in your JSP... rather than on the client side with JavaScript? In the JSP it would look vaguely like this:
<input type="text" name="myFormField1" value="<%= request.getParameter("value1"); %>"/>
On the client side, JavaScript doesn't really have the concept of a "request object". You pretty much have to parse the query string yourself manually to get at the CGI parameters. I suspect that isn't what you're actually wanting to do.
Passing JSON from JSP to Javascript.
I came here looking for this, #BalusC's answer helped to an extent but didn't solve the problem to the core. After digging deep into <script> tag, I came across this solution.
<script id="jsonData" type="application/json">${jsonFromJava}</script>
and in the JS:
var fetchedJson = JSON.parse(document.getElementById('jsonData').textContent);
In JSP file:
<head>
...
<%# page import="com.common.Constants" %>
...
</head>
<script type="text/javascript">
var constant = "<%=Constants.CONSTANT%>"
</script>
This constant variable will be then available to .js files that are declared after the above code.
Constants.java is a java file containing a static constant named CONSTANT.
The scenario that I had was, I needed one constant from a property file, so instead of constructing a property file for javascript, I did this.
In JSP page :
<c:set var="list_size" value="${list1.size() }"></c:set>
Access this value in Javascipt page using :
var list_size = parseInt($('#list_size').val());
I added javascript page in my project externally.
I am building a pyramid/python app where my view callable for a certain template passes in a value called data. This variable is an array in the form of [[[x1,y1,z1,],...],[[v1,v2,v3],...]]
in my viewcallable I have
import json
jsdata = json.dumps(data)
I want to put it into a javascript script tag section of my template so:
<script>
data=${jsdata}
</script>
but i'm pretty sure that syntax is incorrect. How can I do this?
Edit: from this: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/templates.html it seems that Genshi style replacements are the way to go, which I take to mean that what I have above is correct. I am still unsure however, about whether this should be treated differently because it is going inside a javascript tag. Is this true?
You want to insert a JavaScript array, not a Python list.
The easiest way to convert between Python and JavaScript formats is to use the json module. JSON is a JavaScript subset for data after all:
import json
jsdata = (json.dumps(data)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
then pass jsdata to your template instead. The str.replace() calls ensure that the data remains HTML safe.
In the template, interpolate this without escaping:
<script>
var data = ${structure:jsdata};
</script>
I'm not sure about Chameleon, but "classical" Zope Page Templates did not allow to do anything inside script tags - if you don't see your variables interpolated it is likely that Chameleon behaves the same. The reason for this, as I understand, is to avoid exactly this type of code generation (you're generating JavaScript from Python via the template). Also, ZPT is an XML-based templating language and the content of <script> tags does not have to be a valid XML.
To work around the problem, you could do something like
jsdata = '<script type="text/javascript">var data = ' + json.dumps(data) + ';</script>'
and in your template insert the whole thing:
<tal:myscript replace="structure jsdata" />
Alternatively, you could do something like
<tal:lt replace="string:<" />script>
var data = <tal:script replace="structure jsdata" />;
<tal:lt replace="string:<" />/script>
which would hide the script tags from Chameleon.
It would be a good practice to try to keep the amount of generated JavaScript in your pages as minimal as possible.
Working on an ASP.net web application, I've been wondering if there is a good way to avoid writing JavaScript code in string literals in my ASP.net code. See here: https://web.archive.org/web/20211020150655/https://www.4guysfromrolla.com/articles/030202-1.aspx.
In the linked example, I see code that looks like:
Private Sub Calendar1_SelectionChanged(sender As Object, e As EventArgs)
Dim strjscript as string = "<script language=""javascript"">"
strjscript &= "window.opener." & _
Httpcontext.Current.Request.Querystring("formname") & ".value = '" & _
Calendar1.SelectedDate & "';window.close();"
strjscript = strjscript & "</script" & ">" 'Don't Ask, Tool Bug
Literal1.Text = strjscript 'Set the literal control's text to the JScript code
End Sub
I'm not used to using much JavaScript. A lot of the code that I've worked with has been mostly server-side coding with T-SQL. The above code gives me a headache just looking at it. Not only is it ugly, but it shows a pattern where a malicious user could try to inject malicious code.
Is there a better way to avoid manipulating JavaScript code as string literals? Think of the ways we have to avoid manipulating T-SQL code as string literals.
Ugh, dynamically building javascript and putting it inside a literal?
Generally the only time I embed javascript in code is when I am making a custom control and want it packaged neatly (no sepatate js file to worry about), and even then I use RegisterClientScriptBlock instead of a hack like this.
Why not just have a javascript function inside the page source (or an include file) that takes two parameters (form name and selected date) and then dynamically build the function call instead of the entire script?
A common way is to use the clientscriptmanager class:
http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx
You can call the registerstartupscript method, which will add the script to the end of your page, executes when the page finishes loading but before the page's OnLoad event is raised.
The RegisterClientScriptBlock method adds the script to the top of your page. This is where you might add commonly used fnctions.
Dim script As New StringBuilder()
script.AppendFormat("window.opener.{0}", Httpcontext.Current.Request.Querystring("formname"))
script.AppendFormat(".value = '{0}';window.close();", Calendar1.SelectedDate)
Dim cs As ClientScriptManager = Page.ClientScript
cs.RegisterClientScriptBlock(Me.GetType(), "ScriptKey", script.ToString(), true)
The last parameter tells the script manager to wrap the script in <script>...</script> tags so that you don't have to.
Also, if you are adding scripts from a user control, the "ScriptKey" makes sure that the same script does not get added more than once. If you need a separate script for each control, you can dynamically generate that parameter based on the control id.
The other common method for adding links to script files on your page is RegisterClientScriptInclude
Instead of writing out the complete function, embed the function on the page or in an external file and only dynamically write out the values. For example:
<script>
<asp:Literal ID="ScriptValues" runat="server" />
</script>
<script>
function foo(bar) { ... }
</script>
Then in your code behind or wherever (sorry, I don't do VB):
var values = new StringBuilder();
values.Append("var bar = " + bar + ";");
...
ScriptValues.Text = values.ToString();
for starters the StringBuilder is far better for this than using String (it's easier to read and more performance tuned)
Dim sbuild As StringBuilder = New StringBuilder
sbuild.Append("<script language=""javascript"">")
sbuild.Append("window.opener.")
sbuild.Append(Httpcontext.Current.Request.Querystring("formname"))
sbuild.Append(".value = ")
sbuild.Append(Calendar1.SelectedDate)
sbuild.Append("';window.close();")
sbuild.Append("</script>")
Literal1.Text = sbuild.ToString
But beyond that, I would suggest trying something like the TagBuilder Class. It says it's for MVC, but I don't see why you can't use it in a Web Forms scenario as well (you'd just have to import the MVC namespace) - (though I could be wrong on this part).
There are a few things to consider in dealing with your issue.
There are several methods, including Page.RegisterClientScript, that handle some of the dirty work, by properly wrapping your JavaScript code in the proper tags, as well as placing it within the proper place in the page (inline vs. beginning/end) that will deal with some of the formatting issues.
Your code sample above is VB.Net, which is little rough working with with large amounts of text due to the requirement of having to append the &_ to every line. C# does a better job at this. The good news is that with the release of .Net 4, you no longer have to worry about doing all the line concatenations.
If you are dealing with a large amount of text that you need to embed, you could consider keeping your JavaScript in a separate text file, and read the file into your literal, or script registration. You can even do some simple string replacements if you have to have some dynamic data. The StringBuilder class is also a help, with the use of the Append and AppenLine methods(), but again it depends on how much text you're dealing with and how often you'll be needing to work with the code block in question.
Move as much as possible into a .js file.
If anything, you should only need to render simple js function calls. I try to minimize the need for these, by adding a css class and then using jquery's class selector to attach the behavior.
From the example posted by rockinthesixstring, if you want to "clean" up the visual aspect of the code, you would also write it as:
Dim sbuild As StringBuilder = New StringBuilder
With sbuild
.Append("<script language=""javascript"">")
.Append("window.opener.")
.Append(Httpcontext.Current.Request.Querystring("formname"))
.Append(".value = ")
.Append(Calendar1.SelectedDate)
.Append("';window.close();")
.Append("</script>")
End With
Literal1.Text = sbuild.ToString
However I would look into the methods Page.ClientScript
Page.ClientScript.RegisterStartupScript
or if you are using a ScriptManager
ScriptManager.RegisterStartupScript
When working with JavaScript in ASP.NET, these are the paths you should follow:
Put it in a seperate JavaScript file. More maintanable.
However, if you (for whatever reason) can't put it in a JavaScript file, put it in a static class which exposes the script as constants with placeholders for value insertion (use the # symbol so you don't have to escape characters.
Like this:
public static class JavaScriptStuff
{
public const string SpecialScriptFormat = #"window.opener.{0}.value = '{1}';window.close();"
}
Then register it using ClientScriptManager - this way you also don't need to explicity open/close the script tag (stops human error).
http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.aspx
string myScript = string.Format(JavaScriptStuff.SpecialScriptFormat, HttpContext.Current.Request.QueryString("formname"), Calendar1.SelectedDate);
Page.ClientScript.RegisterStartupScript(this.GetType(), "myscript", myScript, true);
You can go even further, and not expose the scripts as public properties, instead expose "getter" methods which accept the params - which adds another layer of maintainability:
public static class JavaScriptStuff
{
private const string SpecialScriptFormat = #"window.opener.{0}.value = '{1}';window.close();"
public string GetSpecialScript(string queryString, string selectedDate)
{
return string.Format(SpecialScriptFormat, queryString, selectedDate);
}
}
}
Page.ClientScript.RegisterStartupScript(this.GetType(), "myscript", JavaScriptStuff.GetSpecialScript(HttpContext.Current.Request.QueryString("formname"), Calendar1.SelectedDate), true);
HTH