onclick triggered automatically - how to create button on the fly - javascript

I tried to search through similar questions but I can't get a solution.
I have a snippet of code which is creating some HTML to append to a div:
var list="<ul>";
for(i=0; i<data.length; i++) {
sid=data[i].sid;
list += "blablabla <a onclick=delete(sid)>delete</a></li>";
}
list +="</ul>";
document.getElementById("my_container").innerHTML = list;
The function delete(sid):
function delete(Sid){
doSomething(taskSid,
function(error) {
if(error) {
console.log(error.code);
console.log(error.message);
return;
}
console.log("deleted");
}
);
The problem is that the function delete(sid) is called automatically.
I have read that it's because I am calling directly the function, and I have tried different proposed solutions, but cannot really make them work.
My code will create a several rows which have this button or link which need to call the function delete.
Probably it is completely wrong also the approach of having one container and define the list in javascript?
Any help appreciated.
Thanks

You should try binding the function
<a onclick=delete.bind(null,sid)>delete</a>
Something like this bind prepares your listener to be executed here you are calling the function so because of that it get executed right away. You can also try arrow function here and calling delete function from inside it, like this
<a onclick=()=>delete(sid)>delete</a>

Better approach is to use createElement method. Something like this:
let list = document.createElement('ul');
for(i = 0; i<data.length; i++) {
let sid=data[i].sid;
let link = document.createElement('li');
link.innerHTML = 'delete';
link.onclick = function(){
deleteTask(sid);
};
list.appendChild(link);
}
document.getElementById("my_container").appendChild(list);

Related

Removing a created function in JavaScript

I have written this code by using some basics. I simply wanted to remove the image that I have created by using the function Generate() by a button. I have written the following code to remove the image generated. Please help me.
Please note that I have linked my button with the function Reset1(). Can someone give me the code to do the following please.
function Generate()
{
var image=document.createElement('img');
var div=document.getElementById('flex-box-gen');
image.src="https://thecatapi.com/api/images/get?format=src&type=gif&size=small"
div.appendChild(image);
}
function Reset1()
{
document.getElementById('Generate').remove();
}
You could either assign an id to your image element and use that to remove in your second function:
function generate() {
var image=document.createElement("img");
image.id = "image-01";
...
}
function reset() {
var image = document.getElementById("image-01");
var parent = image.parentNode;
parent.removeChild(image);
}
Or if there is nothing else in your containing div element you could just empty all elements from it:
function reset() {
document.getElementById("flex-box-gen").innerHTML = "";
}
getElementById will query a DOM element, not a javascript element.
What you can do, supposing you have only one img in your flex-box-gen is:
var imgs = document.querySelectorAll('#flex-box-gen img')
if(imgs.length > 0){
imgs[0].remove();
}
With a null-check in case the image was already removed
image.setAttribute('id',"Generate");
Add this line in generate function.

how to have div contain only the element from last (javascript) function call (if called multiple times)?

So I am creating a table through javascript,
Part of my assignment says: "the output div should only contain the table of the most recent call"
It is a class where we don't talk too much syntax and I am new to web development and javascript.
I have this function and it works:
<body>
<div id="output"></div>
<script type="text/javascript">
var functionCreate = function(strInput) {
var dividedArray = strInput.split("\n");
var dLength = dividedArray.length;
var myRow, myCell;
var myNewTable = document.createElement('table');
myNewTable.border = "1"
for(var i = 0; i< dLength; i++){
if(dividedArray[i].length >0){
myRow = myNewTable.insertRow(-1);//here
for(var j = 0; j<dividedArray[i].length;j++){
if(dividedArray[i][j] != ','){
myCell = myRow.insertCell(-1); //here
myCell.innerHTML = dividedArray[i][j]
}
}
}
}
document.getElementById("output").appendChild(myNewTable);
};
</script>
</body>
When its called one time, it does what it is supposed to do. When it is called twice, I get two tables, naturally(?)
However I have no idea how to only use the table from last call . I have no access to where it is being called. Can anyone direct me towards the right direction? What is the most basic and straight forward approach that I should take to implement this?
The reason why your code is adding new tables is due to the line of code here:
document.getElementById("output").appendChild(myNewTable);
The function appendChild appends (adds) a child (myNewTable) to the end of the element of id output.
So when u run the function multiple times, it just keeps adding a newly created myNewTable element to the output div.
To make sure it only appends the latest table, clear the output div with something like document.getElementById('output').innerHTML = ""; at the beginning of your function

id of a link that a function is called from

I hope it's not a problem to post much specific code here, but I figure it will be better explained if everyone can just see it, so I will give you my code and then I will explain my problem.
My code:
function addBeGoneLinks () {
var beGoneClassElems;
var beGoneSpan;
var beGoneLink;
var beGonePrintSafe;
var spacesSpan;
//var middotSpan = document.createElement ('span');
var interactionContainer = document.getElementsByClassName('feedItemInteractionContainer');
for (var i=0; i<children.length; i++)
{
beGonePrintSafe = false;
beGoneClassElems = children[i].getElementsByClassName('beGone')
beGonePrintSafe = true;
if (beGoneClassElems.length == 0)
{
beGoneLink = document.createElement('a');
beGoneLink.href = 'javascript:void(0);';
beGoneLink.appendChild(document.createTextNode('Be Gone'));
beGoneLink.className = 'beGone';
beGoneLink.id = 'beGoneLink' + i.toString();
beGoneLink.addEventListener ("click", function() {beGone();}, false);//This line!
beGoneLink.align = 'right';
spacesSpan = document.createElement('span');
spacesSpan.innerHTML = ' - ';
if (interactionContainer[i] != undefined)
{
interactionContainer[i].appendChild(spacesSpan);
interactionContainer[i].appendChild(beGoneLink);
}
}
}
}
Here I have a function from a Greasemonkey script that I am working on. When one of the links is clicked, my aim is to have it call the function beGone() which will, among other things, remove the whole element a few parents up, thereby removing their sibling's, their parents and their parents' siblings, and one or two levels after that.
My idea was just to get the id of the link that was pressed and pass it to beGone() so that I could then get the parents using its id, but I do not know how to do that. Am I able to have the id of a link passed by the function that it calls? If not, is there any other way to do this?
I am not sure whether I am missing some really simple solution, but I haven't been able to find one rooting around the web, especially because I was unsure how I would search for this specific problem.
Try this:
beGoneLink.addEventListener("click", beGone, false);
beGone = function (evt) {
evt.target; // evt.target refers to the clicked element.
...
}
You can then use evt.target.id, evt.target.parentNode, etc.

Remove onclick event from img tag

Heres my code:
<div id="cmdt_1_1d" class="dt_state1" onclick="sel_test(this.id)">
<img id="cmdt_1_1i" onclick="dropit('cmdt_1_1');" src="/site/hitechpackaging/images/items/bags_menu.jpg ">
<span class="dt_link">
BAGS
</span>
</div>
Unfortunately I cannot modify this file, is there a way using javascript to disable the onclick from the img tag only.
I was using this script but it disable the onclick event from all images. But i want only from this component
var anchorElements = document.getElementsByTagName('img');
// for (var i in anchorElements)
// anchorElements[i].onclick = function() {
// alert(this.id);
// return false;
// }
Any ideas will be appreciated.
Edited:
Is there a way to stop the function dropit from executing, is it possible using javascript. On page load, etc.
another option is can i rename the img file using javascript??
document.getElementById('cmdt_1_1i').removeAttribute("onclick");
var eles = document.getElementById('cmdt_1_1d').getElementsByTagName('img');
for (var i=0; i < eles.length; i++)
eles[i].onclick = function() {
return false;
}
Lots of answers, but the simplest is:
document.getElementById('cmdt_1_1i').onclick = '';
try something like this:
var badImage = document.getElementById("cmdt_1_1i");
badImage.onclick = null;
badImage.addEventlistener("click",function(e){
e.preventDefault();
e.stopPropagation();
return null;
},true);
If you later need to restore the onclick property, you can save it in a field before overwriting it:
document.getElementById(id).saved=document.getElementById(id).onclick;
document.getElementById(id).onclick = '';
so that later you can restore it:
document.getElementById(id).onclick=document.getElementById(id).saved;
This can be useful especially in the case, in which the original onclick property contained some dynamically computed value.
You can programmatically reassign event listeners. So in this case, it might look something like:
const images = document.querySelectorAll('#cmdt_1_1d img')
for (let i = 0; i < images.length; i++) {
images[i].onclick = function() => {}
}
...where the query above returns all of the img tags that are descendants of the element with ID cmdt_1_1d, and reassigns each of their onclick listeners to an empty function. Therefore no actions will take place when those images are clicked.

Javascript - Dynamically assign onclick event in the loop

I have very simple html page with js code:
<html>
<head>
<title></title>
</head>
<body>
<div id="divButtons">
</div>
<script type="text/javascript">
var arrOptions = new Array();
for (var i = 0; i < 10; i++) {
arrOptions[i] = "option" + i;
}
for (var i = 0; i < arrOptions.length; i++) {
var btnShow = document.createElement("input");
btnShow.setAttribute("type", "button");
btnShow.value = "Show Me Option";
var optionPar = arrOptions[i];
btnShow.onclick = function() {
showParam(optionPar);
}
document.getElementById('divButtons').appendChild(btnShow);
}
function showParam(value) {
alert(value);
}
</script>
</body>
</html>
That page binds 10 buttons, but when you click on any button it always shows alert "option9". How is it possible assign onclick event to show correspondent option !?
Thanks!
You'll have to do something like this:
btnShow.onclick = (function(opt) {
return function() {
showParam(opt);
};
})(arrOptions[i]);
Consider the fact that when the onclick() function is executed, all it has is:
showParam(optionPar);
, verbatim. The optionPar will be resolve at the time the click event is executed, and at this point it most likely be the latest value you assigned to it. You should generally avoid passing variables in such a way.
The problem you are trying to solve is best solved by re-writing the piece such as:
btnShow.value = "Show Me Option";
var optionPar = arrOptions[i];
btnShow.optionPar = optionPar;
btnShow.onclick = function(e) {
// if I'm not mistaking on how to reference the source of the event.
// and if it would work in all the browsers. But that's the idea.
showParam(e.source.optionPar);
}
The accepted answer seems to work, but seems to be confusing and a somewhat cumbersome way to do it. A better way perhaps might be to use the data attribute for the element you're looking to assign the event listener for. It's simple, easy to understand, and way less code. Here's an example:
btnShow.data = arrOptions[i];
btnShow.onclick = function() {
showParam(this.data);
}
I attach an event handler:
window.onload = function() {
var folderElement;
tagFolders = document.getElementById("folders");
for (i = 0; i < folders.length; i++) {
folderElement = folderButtons[i];
folderElement = document.createElement("button");
folderElement.setAttribute("id", folders[i]);
folderElement.setAttribute("type", "button");
folderElement.innerHTML = folders[i];
if (typeof window.addEventListener !== "undefined") {
folderElement.addEventListener("click", getFolderElement, false);
} else {
folderElement.attachEvent("onclick", getFolderElement);
}
tagFolders.appendChild(folderElement);
}
which can retrieve anything from the element that triggered the event:
// This function is the event handler for the folder buttons.
function getFolderElement(event) {
var eventElement = event.currentTarget;
updateFolderContent(eventElement.id);
}
in which case you have to embed the option inside the element / tag. In my case I use the id.
For jquery, check out the adding event data section from the API:
...
for (var i = 0; i < arrOptions.length; i++) {
$('<input id="btn" type="button" value="Show Me Option"><input>').appendTo("#divButtons")
$('#btn').bind("click", {
iCount: i},
function(event) {
showParam(arrOptions[iCount]);
});
}
The accepted answer is correct but I feel that no real explanation was done.
Let me try to explain, the issue here is classical missing closure.
The variable 'i' is getting increased by 1 per loop iteration,
and the on-click event actually is not being executed, whether only applied to the a element, it getting summarize up to the length of arrOptions which is 10.
So, the loop continues up until 'i' is 10,
Then, whenever the on-click event is being triggered, it takes the value of i which is 10.
now, for the solution,
in the solution we are using a closure, so that when we apply the value of 'i' to the on-click event of the a element, it actually gets the exact value of i at in time.
The inner function of the onclick event create a closure where it references the parameter (arrOptions[i]), meaning what the actual i variable is at the right time.
The function eventually closes with that value safely,
and can then return its corresponding value when the on-click event is being executed.
You pass just the reference of the variable to the function, not it's value. So every time the loop is iterated, it assigns a reference to your anonymous function and all of them point to the same value in memory. But since you use the same variable name in the loop, you overwrite the value of the variable. You can concatenate the variable to a string to preserve it's value. For example like that:
btnShow.onclick = new Function("", "showParam(" + arrOptions[i] + ");");
The first parameter is the name of the function but afaik it is optional (it can be left blank or omitted at all).
pp();
function pp()
{
for(j=0;j<=11;j++)
{
if(j%4==0)
{
html+= "<br>";
}
html += "<span class='remote' onclick='setLift(this)' >"+ j+"</span>";
}
document.getElementById('el').innerHTML = html;
}
function setLift(x)
{
alert(x.innerHTML);
}

Categories