I'm wondering if there's a way to access a JavaScript object from within thymeleaf's inline syntax.
I'm trying to build a URL using the [[#{}]] syntax in JavaScript. However, inside of the URL, I need to get access to a JS variable.
Here's the code:
var fieldPathStr = /*[[#{{lessonId}/questions/{questionId}(lessonId=${lesson.id}, questionId=question.id)}]]*/"1/questions/2";
Specifically, it's the question.id that is the JS variable, but it (obviously) just creates the final URL as:
1/questions/question.id
Is there a way to structure this assignment statement so that I can get the actual value of question.id and have it evaluate it properly?
You can extract values like this:
var lessonId = [[${lesson.id}]];
var questionId = [[${question.id}]];
but I am not sure that it is a way to go. If you are working with the lists, you would need to extract them in js which means twice the work on the machine side...
There is a way to do it, but probably little different than what you thought!
An example of how I managed my popup box to confirm removal of item from the list:
<script th:inline="javascript">
function deleteObject(id) {
bootbox.confirm([[#{msg.ask}]], function(result) {
if (result) {
var url = /*[[ #{'/admin/vozila/izbrisi?vin='} ]]*/ "genericUrl";
url = url+id;
document.location = url;
}
});
};
</script>
Once this is done, all you need is to call it and pass the object id:
<a class="btn btn-default btn-sm" href="#" th:onclick="'javascript:deleteObject(\'' + ${vozilo.vin} + '\');'"><i class="glyphicon glyphicon-remove"></i><span th:text="#{rad.obr}">Radnja - izbrisi</span></a>
So you are not getting thymeleaf rendered inside js, but you pass the values to the function when called.
I guess in your case it would look something like this:
<script th:inline="javascript">
function callLink(lessonID, questionID){
var fieldPathStr = lessonID+/*[[#{'/questions/'}]]*/"1/questions/2";
var finalStr = lessonID+fieldPathStr+questionID;
};
</script>
where questionID, and lessonID should look like this:
Hope this works for you?
Related
So as you might know, Razor Syntax in ASP.NET MVC does not work in external JavaScript files.
My current solution is to put the Razor Syntax in a a global variable and set the value of that variable from the mvc view that is making use of that .js file.
JavaScript file:
function myFunc() {
alert(myValue);
}
MVC View file:
<script language="text/javascript">
myValue = #myValueFromModel;
</script>
I want to know how I can pass myValue directly as a parameter to the function ? I prefer to have explicit calling with param than relying on globals, however I'm not so keen on javascript.
How would I implement this with javascript parameters? Thanks!
Just have your function accept an argument and use that in the alert (or wherever).
external.js
function myFunc(value) {
alert(value);
}
someview.cshtml
<script>
myFunc(#myValueFromModel);
</script>
One thing to keep in mind though, is that if myValueFromModel is a string then it is going to come through as myFunc(hello) so you need to wrap that in quotes so it becomes myFunc('hello') like this
myFunc('#(myValueFromModel)');
Note the extra () used with razor. This helps the engine distinguish where the break between the razor code is so nothing odd happens. It can be useful when there are nested ( or " around.
edit
If this is going to be done multiple times, then some changes may need to take place in the JavaScript end of things. Mainly that the shown example doesn't properly depict the scenario. It will need to be modified. You may want to use a simple structure like this.
jsFiddle Demo
external.js
var myFunc= new function(){
var func = this,
myFunc = function(){
alert(func.value);
};
myFunc.set = function(value){
func.value = value;
}
return myFunc;
};
someview.cshtml
<script>
myFunc.set('#(myValueFromModel)');
myFunc();//can be called repeatedly now
</script>
I often find that JavaScript in the browser is typically conceptually tied to a specific element. If that's the case for you, you may want to associate the value with that element in your Razor code, and then use JavaScript to extract that value and use it in some way.
For example:
<div class="my-class" data-func-arg="#myValueFromModel"></div>
Static JavaScript:
$(function() {
$('.my-class').click(function() {
var arg = $(this).data('func-arg');
myFunc(arg);
});
});
Do you want to execute your function immediately? Or want to call the funcion with the parameter?
You could add a wrapper function with no parameter and inside call your function with the global var as a parameter. And when you need to call myFunc() you call it trough myFuncWrapper();
function myFuncWrapper(){
myFunc(myValue);
}
function myFunc(myParam){
//function code here;
}
I have searched hard for a syntax like the JSTL one ${pageContext.request.contextPath},
I did made a javascript code to change the action attribute on the form to call the edit method on the spring controller so, the problem is the below code dont work without calling the Context first like ${pageContext.request.contextPath}/edit.html
<script th:inline="javascript">
function edit() {
document.getElementById("user_form").action = "/edit.html";
}
</script>
so what is the Syntax to call Thymeleaf context path?
In Thymeleaf the equivalent of JSP's ${pageContext.request.contextPath}/edit.html would be #{/edit.html}
Check out this part of the Thymeleaf documentation for more details
In your case you would write :
<script th:inline="javascript">
function edit() {
var link = /*[[#{/edit.html}]]*/ 'test';
document.getElementById("user_form").action = link;
}
</script>
The /*[[ - ]]*/ syntax is used by Thymeleaf to evaluate variables used by Javascript, without breaking the script if that where to be statically loaded. Check out this part of the documentation for more details
My solution for Thymeleaf and jQuery is below.
Use ${#httpServletRequest.getContextPath()} in Thymeleaf to write the context path in the meta element:
<meta name="_ctx" th:content="${#httpServletRequest.getContextPath()}" />
and in jQuery, use $.ajaxPrefilter() to prepend context path to all jQuery AJAX requests:
var _ctx = $("meta[name='_ctx']").attr("content");
// Prepend context path to all jQuery AJAX requests
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
if (!options.crossDomain) {
options.url = _ctx + options.url;
}
});
Just in case anybody else stumbles upon this question looking for what I originally had been...setting a context path variable for the root of the page inside the Thymeleaf page to carry over to an external JQuery page. Here is how it worked for me...same as above just left blank...
Old way with JSP
<script >var contextRoot = "${pageContext.request.contextPath}"; </script>
New way with Thymeleaf
<script th:inline="javascript"> var contextRoot = /*[[#{/}]]*/ ''; </script>
and a link with more information...
http://forum.thymeleaf.org/JSESSIONID-in-td3386826.html
(also depending on the IDE, I set the script over two+ lines as opposed to the same line of the code number.)
Try this:
var BASE_CONTEXT_PATH = $('meta[name=context-path]').attr("content");
BASE_CONTEXT_PATH = BASE_CONTEXT_PATH.substr(0, BASE_CONTEXT_PATH.length - 1);
<meta name="context-path" th:content="#{/}"/>
Pretty noobish question, and I'm probably thinking about this wrong, but...
Is there a way to pass a javascript object (or a reference to it) to a javascript function within the HTML markup?
For example:
<script type="text/javascript">
var myObject = new Object();
$('body').append('<div onclick=testThis(' + myObject + ')></div>');
function testThis(object)
{
console.log(object);
}
</script>
The markup ends up looking something like this when I inspect it:
<div onclick="testThis([object Object])">
Additional context:
The real use case is a search page in which I am querying SOLR via AJAX and get a result back as JS objects. When the user clicks on the HTML markup representing one of these search results, I want to be able to pass the object(or a reference to it) to a separate JS function for processing.
Am I thinking about this the wrong way?
No, you can't embed a reference to an object into markup.
Instead you probably would like to setup your click event listening in Javascript/jQuery:
var object = new Object();
$('<div/>').appendTo('body').click(function() {
testThis(object);
});
function testThis(value) {
console.log(value);
}
I have a method that looks like this
function endcall_click(leadid) {
document.location = '#Url.Action("index","dispo",new{id=leadid})/';
}
Of course it doesn't work because it treats "leadid" as a server side variable but I want to inject the javascript variable passed into the method.
I tried wrapping lead id in but that didn't work.
function endcall_click(leadid) {
document.location = '#Url.Action("index","dispo",new{id="<text>leadid</text>"})/';
}
Any ideas?
You can't inject javascript variable to a script that is evaluated at the server simply because at the moment this script executes and generates the output this variable hasn't yet come to existence. The only way to achieve this is to manipulate the resulting string:
function endcall_click(leadid) {
document.location = '#Url.Action("index", "dispo")/' + leadid;
}
The drawback is that this assumes manipulating the routes in javascript and if you decide to change them on the server the code might break.
I finally found the solution (*.vbhtml):
<script type="text/javascript">
function razorsyntax() {
/* Double */
#(MvcHtmlString.Create("var szam =" & mydoublevariable & ";"))
alert(szam);
/* String */
var str = '#stringvariable';
alert(str);
}
</script>
I am in the process of writing a javascript object that contains a method that returns the html of a standard form. In this object I also have a method validate();
I'd like the form generated to use validate();
So the typical html of a form with validation would probably look like this:
<form id="a" onSubmit="return validate();">
The problem is that I need to be able to reference the object instance so
it would need to be more like onSubmit="my_object.validate();">
I've tried something like
return '<form id="a" onSubmit="return ' + this.validate + '();">';
but I get really strange behavior.
If I make the validate function arbitrarily return true the form gets submitted, false it doesn't. If I do any other calculations in the method I get this error:
> Error: syntax error Source Code:
> return id ==
Has anyone experienced anything like this?
Rather than outputting the event handler in the HTML attribute, you can output the HTML, get a reference to the form object, then attach an event handler programmatically, like this:
<html>
<head>
<script type="text/javascript">
var my_object = {
outputForm: function(container) {
container.innerHTML =
'<form id="a"><input type="submit" value="Validate" /></form>';
this.createdForm = document.getElementById('a');
this.createdForm.onsubmit = this.validate;
},
validate: function() {
// use this.createdForm to get at the controls.
alert("Who dares awake my slumber?");
}
};
function createTheForm() {
my_object.outputForm(document.getElementById('container'));
}
</script>
</head>
<body onload="createTheForm()">
<div id="container"></div>
</body>
</html>
sorry for posting this as an answer, after registering it wouldn't let me edit my original post as non registered user?
I thought about eval but I'm not sure how to even use it in this situation? I've tried it like so
' onSubmit="return eval(' + this.validate+'();)">';
and some other variations but I get the same error.
I would like to avoid having to manually add the event handling as I would like it to be pretty self contained. I was thinking about setting up a regular function which sits outside of the object and then doing something like
' onSubmit="return my_function(' + this + ');">';
then in my_function do this:
my_function(given){ return given.validate(); }
this seems like an awful hack and I'm not even sure if it will work.
Why are you not just applying it to the element after you add it to the page and using a closure to keep scope?
var myId = "bar" + index;
foo.innerHTML="<form id='" + myId + "'>...</form>";
var that = this;
document.getElementById(myId).onsubmit = function(){ that.validate(this); }
Adding event handlers to the markup is always a bad idea.
Use eval() to execute a string as javascript
[EDIT}
Sounds then like you need to prototype the form and then in submit call this.validate(). Get a reference to the form object when you create it using javascript and then define your method for validation and assign that to the validate property.