Iam a newbie of .NET MVC. I was trying to run all return types of MVC but I couldnt do work javascriptResult. The below is in my controller:
public ActionResult DoSomething() {
string s = "alert('Hello world!');";
return JavaScript(s);
}
This is in my view
#Ajax.ActionLink("click", "DoSomething", new AjaxOptions())
When I clicked the link, it puts "alert('Hello world!');" as a string and so not firing the alert. Whats wrong here ?
Seems that the documentation is "wrong" and the Controller.JavaScript action result is most likely only considered to return JavaScript include files (see also this thread):
Controller
public ActionResult JavaScript()
{
string s = "alert('Hello world!');";
return JavaScript(s);
}
View
<script type="text/javascript" src="~/Controller/JavaScript"></script>
If you want to return inline JavaScript you can use Controller.Content as your action result in combination with Html.RenderAction:
Controller
public ActionResult JavaScript()
{
string s = "alert('Hello world!');";
return Content(s);
}
View
<script type="text/javascript">
#{ Html.RenderAction("JavaScript", "Controller"); }
</script>
Related
I am facing a problem passing string to HTML page through javascript.
I have a window form,
A HTML file, where I have my Javascript and HTML code.
In the function in C# page, I have a string that I need to send to the HTML page through javascript. But I can not pass it. Please advise me.
Thanks
My C# method code below
private void Form1_Load(object sender, EventArgs e)
{
Assembly assembly = Assembly.GetExecutingAssembly();
StreamReader reader = new StreamReader(assembly.GetManifestResourceStream("ProjectName.Maps.html"));
webBrowser1.DocumentText = reader.ReadToEnd();
***//pass getDefaultMap() value (str) to the javascript in Maps.html page.***
}
private string getDefaultMap()
{
string str;
str = (#"Exec SP_Map_Display #Opt=1");
return str ;
}
My HTML page is below
<body>
<script>
$(document).ready(function () {
$("#btnSubmit").click(function () {
***// Get the data from C# code str***
}
</script>
<input type="button" name="btnSubmit" value="Submit" />
<div id="dvMap">
</div>
</body>
Assuming this is WinForms since there's a WebBrowser control, to call C# code from the HTML page JavaScript can be accomplished with this minimum example:
Simple HTML page added to the root of the project and Properties was setup to Copy to Output Directory: Copy if newer this will ensure there's a simple page for testing:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>WebForms WebBrowser Control Client</title>
</head>
<body>
<input type="button" onclick="getLocations()" value="Call C#" />
<script type="text/javascript">
function getLocations() {
var locations = window.external.SendLocations();
alert(locations);
}
</script>
</body>
</html>
The JS function getLocations will call C# method SendLocations, the important parts are the Form1 class annotations and setting webBrowser1.ObjectForScripting = this :
using System.Windows.Forms;
using System.Security.Permissions;
using System.IO;
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.ObjectForScripting = this;
var path = Path.GetFullPath("Client.html");
var uri = new Uri(path);
webBrowser1.Navigate(uri);
}
public string SendLocations()
{
return "SF, LA, NY";
}
}
Clicking the HTML button Call C# will show a popup with the return value from C# method
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>
In Cshtml the following doesn't work
ViewBag.alert = #"<script language='javascript'>alert('Plan Already Exists');</script>";
How can i achieve this
I am using MVC Razor with C#, and I got this logic to work in my view by updating it a bit:
#if (!string.IsNullOrEmpty(ViewBag.Message))
{
<script type="text/javascript">
alert("#ViewBag.Message");
</script>
}
You need to pass ViewBag.alert as string to alert() function. Currently you are assign string to ViewBag.alert
Use
<script>
alert('#ViewBag.alert');
</script>
You need to add a message to the ViewBag in your controller.
public ActionResult Index() {
ViewBag.Message = "Plan Already Exists";
return View();
}
And then in your view, add a bit of script:
<% if (!string.IsNullOrEmpty(ViewBag.Message)) { %>
<script type="text/javascript">
alert('<%=ViewBag.Message%>');
</script>
<% } %>
You Can Use Like this:
Controller:
public ActionResult Index()
{
ViewBag.msg = "View Bag Value";
return View();
}
View:
if (!string.IsNullOrEmpty(ViewBag.msg))
{
<script type="text/javascript">alert('#ViewBag.msg');</script>
}
I have a gap in my understanding. I have two view screens, one successfully gets a value from a devexpress selection grid but one doesn't... and I don't understand what I am doing differently.
When I use firebug I can't find where the model is set in the DOM.
The following works:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations;
namespace EtracsWeb.Areas.IO.Models
{
public class VoyageInputModel
{
[Required(ErrorMessage = "Value must be supplied")]
[Display(Name = "Show Received Voyages")]
public bool ShowReceivedVoyages { get; set; }
public string VoyageIDS { get; set; }
}
}
being used in the view (which works)...here is a fragment of the view:
#using EtracsWeb.Areas.IO.Models;
#model VoyageInputModel
#{
ViewBag.Title = "Voyage (Receive/UnReceive/etc..)";
Layout = "~/Views/Shared/_LayoutMenu.cshtml";
}
#* MUST go here and NOT at end or code won't work *#
<script type="text/javascript">
//This is the value from the devExpress Selection Grid...
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues("VoyageID", GetSelectedFieldValuesCallback);
}
//This is the value from the InputModel...notice it is different...
//This is why we need this two step process.
function GetSelectedFieldValuesCallback(values) {
// voyage_ids = values;
//alert(values);
document.getElementById('VoyageIDS').value = values;
//alert(document.getElementById('VoyageIDS').value)
}
</script>
Notice I am getting the value from the OnSelection changed as one variable and setting in the inputModel as different name....this all works...
I am trying to do it with a second view and the code dies where I try to access the variable in the model using a getElementbyID .... originally I was trying to use an int...but I switched it to a string...but neither work....
Where in the heck is the model in the DOM? How can I use Firebug to view the #model values (from asp.net mvc)???
Any ideas where I went wrong on the second window?
Here is the second inputmodel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations;
namespace EtracsWeb.Areas.Vehicle.Models
{
public class BookMarkListInputModel
{
public string SelectedBookMarkID { get; set; }
public int BookMarkID { get; set; }
public IEnumerable<BookMark> BookMarks { get; set; }
}
}
and the second view fragment:
#using EtracsWeb.Areas.Vehicle.Models
#model BookMarkListInputModel
#{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_LayoutMenu.cshtml";
}
#* MUST go here and NOT at end or code won't work *#
<script type="text/javascript">
//This is the value used in the DevExpress Selection Grid
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues("BookMarkID", GetSelectedFieldValuesCallback);
}
//This is the variable from the InputModel...notice it can be different
//So we need to have this two step process.
function GetSelectedFieldValuesCallback(values) {
alert(values);
document.getElementById('SelectedBookMarkID').value = values;
alert(document.getElementById('SelectedBookMarkID').value)
}
function Success(data) {
// alert(data.ReturnMessage);
id1.innerHTML = data.ReturnMessage;
}
</script>
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.