Thymeleaf passing fragment parameter to javascript method with th:onclick - javascript

I'm trying to use th:onclick to call a submit() on form whose ID is given as Thymeleaf variable. I write:
th:fragment="fragGname(formname)"
......
th:onclick="'document.getElementById(\'' + ${formname} + '\').submit();'">
But I receive the error
org.thymeleaf.exceptions.TemplateProcessingException: Only variable expressions returning numbers or booleans are allowed in this context, any other datatypes are not trusted in the context of this expression, including Strings or any other object that could be rendered as a text literal. A typical case is HTML attributes for event handlers (e.g. "onload"), in which textual data from variables should better be output to "data-*" attributes and then read from the event handler.
Where is the mistake? Thanks!

I got it:
th:onclick="document.getElementById([[${formname}]]).submit();"

Related

Pass pug variable inside function

I'm trying to pass a variable in my Pug code to an onSubmit event in a form element. Here's my code for that:
each post in posts
p(class="postContent") #{post.content}
form(method='post' id="likeForm" target="invis" onSubmit="addLike(`${post._id}`)")
As you can see, in the addLike function, I'm trying to pass in the post._id variable. The variable is very much defined, and the function works, but I seem to be passing the variable into the function incorrectly. I also tried addLike(#{post._id}) but that doesn't work either. What am I doing wrong?
It looks like you are trying to pass the post._id variable as a string argument to the addLike function using template literals (${post._id}) in a JavaScript event handler for the onSubmit attribute of the form.
The correct way to pass the variable in this case is to remove the ` and ${} and just use post._id like this:
onSubmit="addLike(post._id)"
You also don't need to use #{post._id}

Variables As Arguments To Tag Functions

Is it possible to create a tag function when the template literal is a variable?
e.g. instead of this
render`<h1>Hello World</h1>`
Is there any way to do this?
const template = `<h1>Hello World</h1>`
render(template)
No, that's not possible. Tagged templates are a special syntax where render will get called with a string array and all the ${value} values. By storing it in a variable like that, the template literal is instead interpreted as a regular template literal to be converted to a string instead of a function call.
Of course, if all your render function does is concatenation of the template and its variables, it doesn't matter. But mind that the variables inside the template literal are already evaluated when you store it in a variable, it can't get re-evaluated later.

Passing object as a parameter in a template literal in javascript

I currently have an object which I want to pass as a parameter to another function inside a template literal:
var template = `<button onclick="onclick(${object})"></button>`;
However, this makes the parameter become a string value: [object Object] and doesn't pass the parameter. Is there any way to pass this parameter into the function?
Thank you very much in advance.
You are going to need to represent your object as a string. You can do this using JSON.stringify:
var template = `<button onclick="handleClick(${JSON.stringify(obj).split('"').join(""")})"></button>`;
You will need to escape double quotes (which this code does), and single quotes if used for your onclick event (this code doesn't).
onclick="onclick" actually calls window.onclick - meaning that it picks up clicks anywhere. You should use a different name (such as handleClick).
I would suggest refraining from using inline event listeners for reasons like this, and because they can cause issues if you ever need to adopt a content-security-policy.

How can I generate a unique JavaScript variable name from a JSF clientId?

I want to define a JavaScript function for every instance of a JSF composite component.
For this, inside the component, I'm trying something like:
<h:outputScript>
function myFunction_#{component.clientId}(day) {
//do my instance specific stuff
}
</h:outputScript>
Specifically I am trying to use this function in a RichFaces calendar like this:
<rich:calendar id="calendar" ... dayClassFunction="myFunction_#{component.clientId}">
But the clientId doesn't necessarily only contain characters which are valid in JavaScript variable names.
Is there a way to calculate an md5 hash or something similarly pseudo-unique from the clientId (or something else!) inside a JSF EL expression?
I need it instance-specific because the return value relies on the instance values and the dayClassFunction attribute doesn't accept a function that takes the clientId itself or something likewise specific as an argument.
I've done it before like this:
window['#{cc.clientId}'] = {
myFunction1 : function() { ... },
myFunction2 : function() { ... }
};
then simply call it where you need it with
dayClassFunction="window['#{cc.clientId}'].myFunction1()"
This way everything is scoped to your component. Eventually you can add some prefix to the client id to never get into conflict with other variable names on the window scope.
Can't think of any character, which is allowed in a client id, that would break the javascript.
Assuming it's the separator (:) that's the issue you could use fn:replace:
function myFunction_#{fn:replace(component.clientId, ':', '_')}
When calling your function, JSF will assign this to be the instance-specific JS object which JSF uses to implement the client side. You may be able to get the information you need from that.

Passing object from flex to javascript

I want to call a method in flex from javascript side,
so that I can retrieve javascript object which contains data in flex.
now I'm trying like
var result:Object = new Object()
var keyset:Array = data.getKeySet();
for (var i:int = 0 ; i < keyset.length ; i++) {
result[keyset[i]] = data.get(keyset[i]);
}
return result;
but it do not work. how can I make it right?
p.s. I know it is fundamental question, but I couldn't find anything even though I googled for an hour. So please help!
To communicate between Flash/Flex and JS on the page, use the ExternalInterface class. You can't directly pass objects, but you can convert your object into a serialisable/string. Here's how you'd call a function called 'myFunc' and set it two arguments, a string and a number:
ExternalInterface.call('myFunc',1,'aString');
After the function name, which must always be a string, there is a ...rest parameter. Simply enough, this means you can send any number of arguments to the function, separating them with commas (we do two here).
If you used AS2 at any point in the past you may know the 'eval' function, this was inherited from (and is thus still used by) JS - it analyses a string and attempts to parse it into JavaScript, using this you can literally send Javascript code instead of a func/args:
ExternalInterface.call('alert("Hello!")');
If you want two-way communication, use the ExternalInterface.addCallBack function to register a function as callable from JS.
In case of errors when doing this, you may need to adjust your embed code: "In the object tag for the SWF file in the containing HTML page, set the following parameter:
param name="allowScriptAccess" value="always"
I believe you cannot call a method in AS3 from JS directly (and vice-versa). There should be an interface for it though, where one can call the other. If i remember correctly, you should use the ExternalInterface API.
Also, you can't pass Flex objects to JS (and vice-versa) also. Try building a generic object that is serializable to JSON and use that serialized data in passing data to each other. The receiving party can parse it back to use the data. In this example, the code passed a string from JS to AS3.
In your case, the Flex function would:
build an object
stuff it with data
serialize it into a JSON string
return the string to the caller
Then when JS calls the function:
JS receives the string
Use JSON.parse() to reconstruct the JSON string into a JS object
use the object

Categories

Resources