Function parameter used in jQuery selector - javascript

I have an event handler that appends a new row to a table.
$("#pre_script_12").change(function() {
$("#selected_pre_scripts")
.append("<tr><td><a href='javascript:moveScriptUp("
+ this.id
+ ")'>Move</a></td></tr>");
moveScriptUp() looks like this:
function moveScriptDown(id) {
current = $("tr." + id).eq(1);
$(current).prev().before($(current).next());
$(current).prev().before($(current).next());
}
However, I am getting an error when when appending id to tr..
Error: Syntax error, unrecognized expression: tr.[object HTMLInputElement]
How can I supply the id as a parameter to the above JavaScript function without getting this error when attempting to use it in a jQuery selector?

You need to quote strings in your function call.
Right now, your <a> tag looks like this:
<a href='javascript:moveScriptUp(pre_script_12)'>Move</a>
In (most) browsers, all elements IDs become a global variable, so pre_script_12 refers to the element. You need to add quotes, so you're passing a string:
$("#selected_pre_scripts")
.append("<tr><td><a href='javascript:moveScriptUp(\""
+ this.id
+ "\")'>Move</a></td></tr>");
P.S. I highly reccomend, not using inline JavaScript. Why not bind a (delegated) event handler to call the moveScriptUp() function?

Related

How to pass argument from onclick function?

I have created a table and populated it using jQuery. Now I would like to add a text such as when we click on it a function executes. I have used onclick and it worked fine, but I also need to send a few arguments to my function, how can I send arguments to the targeted function from onclick:
var dataHtml = '';
$.each(data, function (index, user) {
dataHtml+="<code onclick=show_popup(1,user['donner'][0])> Donner details</code>";
});
$("#t-data").html(dataHtml);
function show_popup(show=0, donner){
$(document).ready(function(){
var showModel=show;
if(showModel==`1`){
$(`#modal-default-admin`).modal(`show`);
}
});
But it shows a "user is not defined" error. User is defined and I also can access it.
The user is in fact not defined. The problem you are facing is that you are using HTML as a string, so you are providing onclick=show_popup(1,user['donner'][0]) as string. When jQuery "makes HTML" out of this string and you click on it, it calls show_popup with 1 and user['donner'][0] and the user here is undefined. It was only available inside the $.each loop, not outside of it.
The simplest fix is to pass the value directly and not trying to do it as a pointer.
onclick=show_popup(1,\""+ user['donner'][0] +"\")>
Like this, it will use the value of user['donner'][0] when creating the HTML.
Bonus point: You should wrap the onclick attribute with quotes:
dataHtml += "<code onclick='show_popup(1,\""+ user['donner'][0] +"\")'> Donner details</code>";
Just to make sure that for example a space in the value of user['donner'][0] doesn't break it again.

Add Variable inside th:onsubmit thymeleaf

I'm trying to add variable inside th:onsubmit with
th:onsubmit="return confirm('Hi '" + ${user.name} + "')"
but it always get me error like
Malformed markup: Attribute "+" appears more than once in element
also i can't find onsubmit example on thymeleaf official document
There is nothing special about onsubmit which is why there is nothing in the official documentation about it -- you're simply not formatting the expression correctly. I would format the expressions like this:
th:data-username="${user.name}"
onsubmit="return confirm('Hi ' + this.getAttribute('data-username'))"
(To avoid security errors, Thymeleaf may prohibit you from concatenating strings directly in your JavaScript, which is why I'm separating it out to it's own attribute.)
You can use a function in your onsubmit event, and assign the Thymeleaf expression to a variable within that function.
Example (using onclick in my case):
<yourtag ... onclick="runMyFunction();"></yourtag>
...
<script th:inline="javascript">
function runMyFunction() {
var user_name = [[${user.name}]];
console.log(user_name);
}
</script>
This uses Thymeleaf's JavaScript inlining syntax [[${...}]].
Note that in this case, the event does not have to be th:onsubmit - just onsubmit.

Function parameter evaluates to undefined

When dynamically creating an element of type select, there are two problems when setting the onclick method:
It is impossible to simply set the onclick with element.onclick="updateInput(this.articleIndex)";
This results in a final HTML tag where no onclick is shown at all.
When set by e.setAttribute("onclick","updateInput(this.articleIndex)");, it does appear in the final HTML. And the updateInput method does get called.
However the functionality seems to be broken, as the argument always evaluates to undefined
Here a simple example of my problems:
var selectElem = document.createElement("select");
selElem.id="articleSelector_"+this.articleIndex;
console.log("the index of the article is " + this.articleIndex);
selElem.setAttribute("onclick","updateInput(this.articleIndex);");
//selElem.onclick="updateInput(this.articleIndex)"; //this does not work
The log shows the correct number. Inside the updateInput method, the argument is of value undefined instead of the number previously shown in the log.
Try attaching handlers with pure Javascript, and not with HTML, without onclick = "... (which is as bad as eval).
The this in your script refers to the calling context of the function - what is it?
You might want:
element.addEventListener('click', () => {
updateInput(this.articleIndex);
});
(arrow functions retain the this of their surrounding scope)
it is impossible to simply set the onclick with element.onclick="updateInput(this.articleIndex)";
What that code does is it assigns the string "updateInput(this.articleIndex)" to the onclick which makes no sense and certainly not what you want.
Even if you remove the quotes:
element.onclick = updateInput(this.articleIndex);
It is still incorrect because it assigns the result of the updateInput() function to the onclick which is again not what you want.
You need to assign a function name to the onclick like this:
element.onclick = updateInput;
However, this doesn't allow you to pass a parameter as you wish. To do so, you need to use an anonymous function:
element.onclick = function() {
updateInput(this.articleIndex)
};
When set by e.setAttribute("onclick","updateInput(this.articleIndex)");, it does appear in the final HTML. And the updateInput method does get called.
This works because it sets the attribute onclick and it is a string type, so everything is correct. It is equivalent to using the anonymous function above. The only difference is this, which in this case refers to the element itself, while in the above code it depends on the context that the code appears in. That's why in this case the argument always evaluates to undefined because the select element doesn't have an articleIndex property.
The problem is the value of the context this when that element is clicked, the context this is not available anymore at that moment.
You have two ways to solve this problem:
You can use the function addEventListener to bind the event click, and bind the function/handler with the desired context this:
The function bind binds a specific context to a function.
selElem.addEventListener('click', updateInput.bind(this));
function updateInput() {
console.log(this.articleIndex);
}
As you need a specific value, you can use data attributes. That way, you don't need to worry about the context this.
selElem.dataset.articleIndex = this.articleIndex;
selElem.addEventListener('click', function() {
updateInput(this.dataset.articleIndex); // Here you can get that value.
});

onclick setAttribute workaround for IE7

I can't seem to get this:
top.document.getElementById("clickThis").setAttribute("onclick", "tinyMCE.execCommand('mceInsertContent',false,'<div style=\"width: 600px; margin: 0 auto .5em;\" class=\"wp-caption alignnone\"><img class=\"alignnone\" src=\"<?php echo $full_width; ?>\" alt=\"<?php echo $value; ?>\" /><p class=\"wp-caption-text\"><?php echo $get_image->caption; ?></p></div>');");
To work in IE7, I have tried all of the workarounds I could find online and wondering if anyone could help?
Don't do that.
Instead, add an event handler by calling attachEvent / addEventListener.
I know I'm a bit late, but this was bugging the hell out of me too, and I finally got it.
To get IE to execute dynamically built code during the onclick event, do this:
Write the code for all other browsers: element.setAttribute( "onclick", object.varName + "method( " + var + " )" );
Use a custom attribute to hold your dynamic statement: element.setAttribute( "exec", object.varName + "method( " + var + " )" );
Create an anonymous function to execute the statement stored in our custom attribute when the element is clicked: element.onclick = function(){ eval( this.exec ); };
This approach is working for me in IE9 running in IE7 browser mode, as well as the current versions of Chrome and Firefox.
A couple of things to note:
First, in my case, I needed to execute an objects method. To do that, I need to know the var name for the object, which I set as a property when initiating the class. So the object.varName property is one I created and set in my runtime code.
Second, "exec" is not a standard attribute, which is why it works to hold the string I want to execute. But you can call it what ever you want as long as you use a non-standard attribute.
Third, here's why this works: IE, or at least IE7, will only let you set the onclick event to contain an anonymous function. If you assign an object's method or a variable containing
a function, the function is executed when the onclick attribute is set instead of when the element is actually clicked. In my case, I couldn't build an anonymous function because the variables change at runtime. So instead, I dynamically build a statement that is then stored in an attribute of the element. The onclick event then executes whatever statement is stored in that attribute.
Cheers.
worked like a dream when I did this:
if(navigator.userAgent.indexOf("MSIE 7.0") != -1){
document.getElementById("pb").onclick = function(){ eval( this.onClick ); };
}
that way only ie7 looks at it.

How do I pass an HTML element as an argument to a Javascript function?

i have a chat window which has a close button(input type='image') and onclick i want to remove the chat window from the parent node and i use this code
closeBtn.setAttribute("onclick", "return closeContainer(cc" + friendId + ");");
please note that this button is created through javascipt and the cc223423432 (say) will be the id of the chat window
here is my code to remove it
function closeContainer(ccId) {
var x = ccId;
x.parentNode.removeChild(x);
//..........
}
now in IE8 and Chrome it finds the passed argument as HTMLDIV and works fine but in firefox it give an error cc223423432 is undefined
any idea why???
i know i can always do a document.getElementByID and then remove it but please if there is anything i am missing please tell
closeBtn.setAttribute("onclick", "return closeContainer(cc" + friendId + ");");
Don't use setAttribute to set event handlers... actually don't use setAttribute on an HTML document at all. There are bugs in IE6-7 affecting many attributes, including event handlers. Always use the ‘DOM Level 2 HTML’ direct attribute properties instead; they're reliable and make your code easier to read.
Lose the attempt to create a function from a string (this is almost always the wrong thing), and just write:
closeBtn.onclick= function() {
return closeContainer(document.getElementById('cc'+friendId));
};
or even just put the closeContainer functionality inline:
closeBtn.onclick= function() {
var el= document.getElementById('cc'+friendId);
el.parentNode.removeChild(el);
return false;
};
in firefox it give an error cc223423432 is undefined any idea why???
Because IE makes every element with an id (or in some cases name) a global variable (a property of window). So in IE you can get away with just saying cc223423432 and getting a reference to your object.
This is a really bad thing to rely on, though. As well as not existing in other browsers, it clutters up the global namespace with crap and will go wrong as soon as you do actually have a variable with the same name as an id on your page.
Use getElementById to get a reference to an id'd node instead, as above. This works everywhere and is unambiguous.
Since the parameter is not enclosed in quotes Firefox considers this as a variable with name
cc223423432 which is not defined. Thats why it generates the error.
Better to pass this as a string and then use
document.getElementById ( parameter );
to get the object.
You need to pass that id as a string:
closeBtn.setAttribute("onclick", "return closeContainer('cc" + friendId + "');");
Then:
function closeContainer(ccId) {
var x = document.getElementById(ccId);
x.parentNode.removeChild(x);
//..........
}
jquery will work in all of those browsers. I would do the following:
closeBtn.click(function(){
('#cc' + friendId ).remove();
});
However, if you don't want the ramp-up time of learning the jquery api, it looks like you need to pass your id parameter as a string, otherwise firefox considers this a variable name (notice the additional single quotes inside the closeContainer call:
closeBtn.setAttribute("onclick", "return closeContainer('cc" + friendId + "');");
Or you could do the following
function handler(elementRef) {
console.log(elementRef);
}
<button onclick="handler(this)">Click Me!</button>

Categories