i am relatively new to spring mvc.what i am trying to do is pass a variable as model attribute and try and access it on page load with javascript on my JSP page.
my java code is as follows
model.addAttribute("leagueCode",leagueCode);
model.addAttribute("league","new");
return "redirect:/Dashboard";
and on jsp side i am trying to access it by following
<script type="text/javascript"> function myFunction() { var leagueCode=${leagueCode}; alert(leagueCode); } </script> </head> <body onload="myFunction()">
but i am getting the value as blank. is this the right way i am following or is there any other way this has to be done? please help
In the JSP page you can set the values as javascript variables by adding a script tag in the <head> with the assignment inside as a json object for example:
<script>
var myServerSideVars = {
"aServerSideVarName" : "<here you set the value with el/jslt/scriptlet>",
"anotherServerSideVarName" : "<here you set the value with el/jslt/scriptlet>"
};
</script>
EDIT I
Example using EL (Expression Language) but the same could be done with scriptlets if you are using that (<% %>):
Lets say in your Servlet you put a Car instance in the request before forwarding to the JSP page.
The car:
public class Car{
protected String brand;
protected String year;
//getters and setters for the two properties.
}
In the Servlet you put it into the request:
Car car = new Car();
car.setBrand("BMW");
car.setYear("2017");
request.setAttribute("carInRequest", car);
In the JSP you set it to a Json Object accessible from javascript. Before closing the body tag I put a simple example of how the var can be accessed from javascript. I haven't run it so it may have some typo or error to correct:
<%#taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>System.out.println</title>
<script>
var aCar= {
"brand" : "${requestScope.carInRequest.brand}",
"year" : "${requestScope.carInRequest.year}"
};
</script>
</head>
<body>
<h2>Brand: <span id="brandPlaceHolder"></span></h2>
<h2>Year: <span id="yearPlaceHolder"></span></h2>
</body>
<script>
var brandSpan = document.findElementById("brandPlaceHolder");
brandSpan.html = aCar.brand;
var yearSpan = document.findElementById("yearPlaceHolder");
brandSpan.html = aCar.year;
</script>
</html>
Related
I am using Thymeleaf as template engine. How I pass a variable from Spring model to JavaScript variable?
Spring-side:
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("message", "hello");
return "index";
}
Client-side:
<script>
....
var m = ${message}; // not working
alert(m);
...
</script>
According to the official documentation:
<script th:inline="javascript">
/*<![CDATA[*/
var message = /*[[${message}]]*/ 'default';
console.log(message);
/*]]>*/
</script>
Thymeleaf 3 now:
Display a constant:
<script th:inline="javascript">
var MY_URL = /*[[${T(com.xyz.constants.Fruits).cheery}]]*/ "";
</script>
Display a variable:
var message = [[${message}]];
Or in a comment to have a valid JavaScript code when you open your template file in a static manner (without executing it at a server).
Thymeleaf calls this: JavaScript natural templates
var message = /*[[${message}]]*/ "";
Thymeleaf will ignore everything we have written after the comment and before the semicolon.
More info: http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining
var message =/*[[${message}]]*/ 'defaultanyvalue';
According to the documentation there are several ways to do the inlining.
The right way you must choose based on the situation.
1) Simply put the variable from server to javascript :
<script th:inline="javascript">
/*<![CDATA[*/
var message = [[${message}]];
alert(message);
/*]]>*/
</script>
2) Combine javascript variables with server side variables, e.g. you need to create link for requesting inside the javascript:
<script th:inline="javascript">
/*<![CDATA[*/
function sampleGetByJquery(v) {
/*[+
var url = [[#{/my/get/url(var1=${#httpServletRequest.getParameter('var1')})}]]
+ "&var2="+v;
+]*/
$("#myPanel").load(url, function() {});
}
/*]]>*/
</script>
The one situation I can't resolve - then I need to pass javascript variable inside the Java method calling inside the template (it's impossible I guess).
MAKE sure you have thymleaf on page already
//Use this in java
#Controller
#RequestMapping("/showingTymleafTextInJavaScript")
public String thankYou(Model model){
model.addAttribute("showTextFromJavaController","dummy text");
return "showingTymleafTextInJavaScript";
}
//thymleaf page javascript page
<script>
var showtext = "[[${showTextFromJavaController}]]";
console.log(showtext);
</script>
I've seen this kind of thing work in the wild:
<input type="button" th:onclick="'javascript:getContactId(\'' + ${contact.id} + '\');'" />
If you use Thymeleaf 3:
<script th:inline="javascript">
var username = [[${session.user.name}]];
</script>
If you need to display your variable unescaped, use this format:
<script th:inline="javascript">
/*<![CDATA[*/
var message = /*[(${message})]*/ 'default';
/*]]>*/
</script>
Note the [( brackets which wrap the variable.
Another way to do it is to create a dynamic javascript returned by a java controller like it is written here in the thymeleaf forum: http://forum.thymeleaf.org/Can-I-use-th-inline-for-a-separate-javascript-file-td4025766.html
One way to handle this is to create a dynamic javascript file with the
URLs embedded in it. Here are the steps (if you are using Spring MVC)
#RequestMapping(path = {"/dynamic.js"}, method = RequestMethod.GET, produces = "application/javascript")
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public String dynamicJS(HttpServletRequest request) {
return "Your javascript code....";
}
Assuming request attribute named "message":
request.setAttribute("message", "this is my message");
To read it in the html page using Thymeleaf template:
<script>
var message = "[[${message}]]";
alert(message);
</script>
Below is my Spring Controller code.My intention is to pass the values of variables int a, int b, int c to the Jsp page ADMINRESULTS.
Please note that the values of these variables are to be used to intialise javascript variables in adminhome jsp page
#RequestMapping("/adminresults") //this is called by form action. This does not refer to adminhome jsp page
public String adminhome(Map<String, Object> model) {
ArrayList<Block> blockChain = NoobChain.getBlockChain();
Map<String, Integer> dataMap = new HashMap<String, Integer>();
if (!blockChain.isEmpty()) {
if (!NoobChain.isChainValid(blockChain)) { //if not valid to print the data.
model.put("tampermsg", "Unathorized acess detected and vote data is attacked.Correct values are ");
dataMap = NoobChain.validChainData(blockChain);
} else {
dataMap = blockChain.get(0).getData();
}
}
String blockchainJsonFromFile = new GsonBuilder().setPrettyPrinting().create().toJson(blockChain);
System.out.println("after.." + blockchainJsonFromFile);
model.put("message", "\n" + dataMap);
System.out.println("Before extracting DATA is "+dataMap);//to check the format of data map
int a=0;
int b=0;
int c=0;
if (dataMap.containsKey("A"))
{
a = dataMap.get("A");
System.out.println("value for key \"A\" is:- " + a);
}
if (dataMap.containsKey("B"))
{
b = dataMap.get("B");
System.out.println("value for key \"B\" is:- " + b);
}
if (dataMap.containsKey("C"))
{
c = dataMap.get("C");
System.out.println("value for key \"C\" is:- " + c);
}
model.put("a", a);
model.put("b", b);
model.put("c", c);
return "adminhome"; //significance of this code is to return adminhome jsp page
}
Below is a code snippet from adminhome jsp page
<html>
<head> </head>
<body>
<script type="text/javascript">
var as=8,cs=1,bs=4;
</script>
</body>
</html>
My intention is to intialise the above variables as,bs,cs with int a, int b, int c(from the Spring Controller Mentioned above)
Send json object from controller and assign to your hidden variable on html and use that object in your java script.
Below is code, just a sudo code below
Inside Controller
List<Someclass> list = new ArrayList<>();
Someclass someClass = new Someclass();
someClass.setKey("a");
someClass.setValue(1);
list.add(someClass);
Gson gson = new Gson();
ModelAndView modelAndView = new ModelAndView("adminhome");
modelAndView.addObject("list", gson.toJson(someClass));
JSP
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<script type="text/javascript">
$(document).ready(function() {
var someClassJson = $('#"admin"');
list admins = JSON.parse(someClassJson.val());
for (var i = 0; i < admins.lenth; i++) {
var item = admins[i];
console.log(someClass.key);
console.log(someClass.value);
}
});
</script>
<head>
<title>Admin Example</title>
<script src="jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="personScript.js"></script>
</head>
<body>
<h1>
<Admin/h1> <input type="hidden" id="admin" value="${list}"/>
</body>
</html>
hope this will help.
Found an easy answer,Thank you Sanjay for helping,Also Nishant Raj(check out his code too,as Im a beginner ,I couldn't implement his code)
In the adminhome jsp page
<html>
<head> </head>
<body>
<script type="text/javascript">
var aa="${a}",bb="${b}",cc="${c}";
</script>
</body>
</html>
The above will fetch the values to javascript variables aa,bb,cc etc from the spring controller.
But please note if the fetched values if need to be used as Integer it must be converted.Presently it is of String type.
The code for it is.
<html>
<head> </head>
<body>
<script type="text/javascript">
var aa="${a}",bb="${b}",cc="${c}";
var as=parseInt(aa),cs=parseInt(cc),bs=parseInt(bb);
</script>
</body>
</html>
The parseInt will convert it into integer for using it in some future functions if needed.
Thank You all, Issue solved :)
Good day!
I need a help on activating my javascript function via on-load on code behind.
Here is my code:
string script = #"var applyCss = function () {
var css = '#CalendarPanel1-month-day-20170607, #CalendarPanel1-month-day-20170614 {background-color: #D0D3D4;}';
Ext.net.ResourceMgr.registerCssClass('someCssClassId', css);
}; ";
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "css", script, true);
By the way, my code above works in front-end via button click.
But my desired result is, I want my javascript function to work on page load without needing to click the button. I put my javascript function in code-behind because I will put dynamic dates in the css variables. The code above still has static variables. (CalendarPanel1-month-day-20170607)
Will gladly appreaciate any response / solution. Big thanks!
You could use an immediately invoked function to do the trick. Basically you don't give a name to your javascript function and you invoke it right after it's defined.
For example:
var script = #"(function () {alert('Hello');})(); ";
ScriptManager.RegisterStartupScript(this, typeof(Page), "123", script, true);
You need to wrap the function with its body between parenthesis then another set of parenthesis to invoke the function.
You can also pass parameters to your function (which I'm assuming it's what you want to do):
var myAlertText = "Hello Hello";
var script = #"(function (myText) {alert(myText);})('" + myAlertText + "');" ;
If I were you though I would defined the function in client code and just invoke it from code behind with the right parameters.
An alternative and fancier way to call javascript code from code behind would be using X.Call(). Check out this example:
<%# Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
string script = #"var myJSSideVar = 'my var value';
var applyCss = function (paramOne, paramTwo) {
var css = '#CalendarPanel1-month-day-20170607, #CalendarPanel1-month-day-20170614 {background-color: #D0D3D4;}';
Ext.net.ResourceMgr.registerCssClass('someCssClassId', css);
Ext.Msg.alert('applyCss called.', 'I\'ve been run with parameters: (' + paramOne + ', ' + paramTwo + ').');
};";
var hi = "hello";
X.AddScript(script);
X.Call("applyCss", new object[] { hi, new JRawValue("myJSSideVar") });
}
}
</script>
<html>
<head runat="server">
<title></title>
</head>
<body>
<form runat="server" id="form1">
<div>
<ext:ResourceManager runat="server" />
</div>
</form>
</body>
</html>
Notice the second parameter sent to the script call is sent "raw", i.e., it calls: applyCss("hello", myJSSideVar)
If you need to pass but one single parameter you don't need to pass an array, e.g. X.Call("applyCss", hi);
I am using a Spring MVC. Inside controller I am get list object from model and passing this list to on view. I pass index of loop to javascript function.It's OK but now I would like to get value of each object by index inside javascript. How can i do it? Here is my controller class:
#RequestMapping(method = RequestMethod.GET)
public Model handleRequest(HttpServletRequest request,
HttpServletResponse response,
#RequestParam(required = false, value = "q") String query) throws Exception {
Model model = new ExtendedModelMap();
String orderItem = request.getParameter("order_item");
List<Long> itemsIdList = new ArrayList<Long>();
List<OrderRequest> orderRequestList = getItemToppingCount(orderItem,itemsIdList);
model.addAttribute("itemsSelected", orderRequestList);
return model;
}
This is my JSP:
<script>
function remove_confirm_order(index){
alert(index); // OK
// Get value of first object in list
var str1 = '${itemsSelected[0].name}';
// When adding this line, I can't show anything from JSP
var str2 = '${itemsSelected['+index+'].name}';
alert(str1);
}
</script>
<c:forEach var="item" items="${itemsSelected}" varStatus="loop">
<a href="#" onclick="remove_confirm_order('${loop.index}');" />
</c:forEach>
You can achieve the same referring below snippet:
<script>
function remove_confirm_order(index, item){
alert(index); // OK
alert(item); //OrderRequest
var orderRequest = item;
// Now extract value from item(instance of OrderRequest), example, orderRequest.getValue(index);
// Get value of first object in list
var str1 = '${itemsSelected[0].name}';
// When adding this line, I can't show anything from JSP
var str2 = '${itemsSelected['+index+'].name}';
alert(str1);
}
</script>
<c:forEach var="item" items="${itemsSelected}" varStatus="loop">
<a href="#" onclick="remove_confirm_order('${loop.index}', ${item});" />
</c:forEach>
Better is to make an AJAX call to the controller from JavaScript, get the response back and do whatever you want to do.
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
function callHandleRequest() {
$.ajax({
url : '/url/to/your/controller',
success : function(result) {
console.log(result);
}
});
}
</script>
You can do this.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<script>
var data = [];
<c:forEach var="spring_data" items="${data_from_spring}">
data.push(spring_data);
</forEach>
console.log(data);
</script>
You create an array in javascript. Then using a jsp tag within the script tag, you can fill in the data to the array. Remember to do the jstl declaration at the top
Friends,
I am trying to use DyGraph in my application. Please look at the code below -
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
<title>crosshairs</title>
<script type="text/javascript" src="dygraph-combined.js"></script>
<script type="text/javascript" src="data.js"></script>
</head>
The code uses data.js file containing function to get some static data.
I want data.js to be generated using a controller method so that it will generate data using database.
Can anybody help me out to resolve this issue.
Thanks for sharing your valuable time.
You could define a controller action:
public ActionResult Data()
{
// Obviously this will be dynamically generated
var data = "alert('Hello World');";
return JavaScript(data);
}
and then:
<script type="text/javascript" src="<%= Url.Action("Data", "SomeController") %>"></script>
If you have some complex script that you don't want to generate in the controller you could follow the standard MVC pattern by defining a view model:
public class MyViewModel
{
... put required properties
}
a controller action which would populate this view model and pass it to the view:
public ActionResult Data()
{
MyViewModel model = ...
Response.ContentType = "application/javascript";
return PartialView(model);
}
and finally a view which in this case will be the javascript representation of the view model (~/Views/SomeController/Data.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MyViewModel>" %>
alert(<%= new JavaScriptSerializer().Serialize(Model.Name) %>);
Full Disclosure
This answer is copy/pasted from another question:
Dynamically generated Javascript, CSS in ASP.NET MVC
This answer is similar to other answers here.
This answer uses cshtml pages rather than ascx controls.
This answer offers a View-Only solution rather than a Controller-Only solution.
I don't think my answer is 'better' but I think it might be easier for some.
Dynamic CSS in a CSHTML File
I use CSS comments /* */ to comment out a new <style> tag and then I return; before the closing style tag:
/*<style type="text/css">/* */
CSS GOES HERE
#{return;}</style>
Dynamic JS in a CSHTML File
I use JavaScript comments // to comment out a new <script> tag and then I return; before the closing script tag:
//<script type="text/javascript">
JAVASCRIPT GOES HERE
#{return;}</script>
MyDynamicCss.cshtml
#{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
}
/*<style type="text/css">/* */
#foreach (var field in fieldList) {<text>
input[name="#field"]
, select[name="#field"]
{
background-color: #bbb;
color: #6f6f6f;
}
</text>}
#{return;}</style>
MyDynamicJavsScript.cshtml
#{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
fieldArray = string.Join(",", fieldList);
}
//<script type="text/javascript">
$(document).ready(function () {
var fieldList = "#Html.Raw(fieldArray)";
var fieldArray = fieldList.split(',');
var arrayLength = fieldArray.length;
var selector = '';
for (var i = 0; i < arrayLength; i++) {
var field = fieldArray[i];
selector += (selector == '' ? '' : ',')
+ 'input[name="' + field + '"]'
+ ',select[name="' + field + '"]';
}
$(selector).attr('disabled', 'disabled');
$(selector).addClass('disabled');
});
#{return;}</script>
No Controller Required (using Views/Shared)
I put both of my dynamic scripts into Views/Shared/ and I can easily embed them into any existing page (or in _Layout.cshtml) using the following code:
<style type="text/css">#Html.Partial("MyDynamicCss")</style>
<script type="text/javascript">#Html.Partial("MyDynamicJavaScript")</script>
Using a Controller (optional)
If you prefer you may create a controller e.g.
<link rel="stylesheet" type="text/css" href="#Url.Action("MyDynamicCss", "MyDynamicCode")">
<script type="text/javascript" src="#Url.Action("MyDynamicJavaScript", "MyDynamicCode")"></script>
Here's what the controller might look like
MyDynamicCodeController.cs (optional)
[HttpGet]
public ActionResult MyDynamicCss()
{
Response.ContentType = "text/css";
return View();
}
[HttpGet]
public ActionResult MyDynamicJavaScript()
{
Response.ContentType = "application/javascript";
return View();
}
Notes
The controller version is not tested. I just typed that off the top of my head.
After re-reading my answer, it occurs to me it might be just as easy to comment out the closing tags rather than use the cshtml #{return;}, but I haven't tried it. I imagine it's a matter of preference.
Concerning my entire answer, if you find any syntax errors or improvements please let me know.