I have a ul in which I'll add elements using JQuery, I have this
function addElement(e) {
let text = $('#itemToAdd').val();
let newItem = $('<li>' + text + '</li>');
let removeBtn = $('<button onclick = "removeElement">X</button>');
newItem.append(removeBtn);
$('#shoppingList').append(newItem);
$('#itemToAdd').val('');
e.preventDefault();
}
$(document).ready(function() {
$("#addBtn").on('click', addElement);
});
For removing the elements I have this:
function removeElement() {
$(this).parent().remove();
}
The adding function works awesome, but the removing one doesn't.
If you are using onclick then you have to invoke the function with the reference since this won't refer to clicked element(refers to window object most commonly) and based on that remove that element.
Element creation:
let removeBtn = $('<button onclick = "removeElement(this)">X</button>');
Function :
function removeElement(ele) {
$(ele).parent().remove();
}
Or alternately you can use the existing function but bind event handler using jQuery after element creation.
let removeBtn = $('<button>X</button>');
removeElement.click(removeElement);
An another option would be event delegation which helps to handle events on dynamically created elements.
Related
I am using bootstrap's list group to create a row of tabs. When someone clicks on an element in a table, it dynamically creates a new tab and appends it to that list group.
var newtext = "#"+ticket+" - "+parele.find("td:nth-child(3) strong").html();
var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("×");
var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket"+ticket).attr("id","ticket"+ticket+"-tab").append(newdiv);
$("#ticketpanel").append(newa);
The problem I am having is the newly created close button. I need to bind a function that identifies when that is clicked to handle closing that tab, but it doesn't seem to be working. In my example here, I added the "newlyaddedclose" class to help identify the new element temporarily and I added the following code below to bind a function that is defined at the top of my script tag:
$(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
This still doesn't work. When I inspect the close button element, console shows this error: Framework Event Listeners API Errors:
event listener's handler isn't a function or empt
Am I making this harder than it needs to be, or what am I doing wrong? I can simple put at the end of this element creation this:
$(".close").click(function() { ... });
But doing this starts to double up and triple up etc, those events on already created tabs.
EDIT:
Here is my entire block of script to clear up any confusion.
$(function() {
function closebtn() {
alert("Close button clicked...");
}
$(".ticket-line").click(function() {
var parele = $(this);
var ticket = parele.data("tnum");
// Check to see if ticket is already open in tabs
if($("#ticket"+ticket).length == 0) {
// Create tab on ticket panel
var newtext = "#"+ticket+" - "+parele.find("td:nth-child(3) strong").html();
var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("×");
var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket"+ticket).attr("id","ticket"+ticket+"-tab").append(newdiv);
$("#ticketpanel").append(newa);
$(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
// Create DIV with content
var newdata = $("<div>").addClass("tab-pane").attr("id","ticket"+ticket);
$("#ticket-tabs").append(newdata);
$("#ticket"+ticket+"-tab").tab("show");
} else {
// Ticket is already open, switch to it instead
$("#ticket"+ticket+"-tab").tab("show");
}
});
})
The error is clearly stating you are binding a non function to the event listener. So the error is saying that closeBtn is not a function. Your code, you defined closeBtn as the button you are trying to attach the event too. So change closeBtn in the click event listener to the name of the function you are actually trying to call. If it is the same function name, rename something.
Your problem:
var closeBtn = 1;
if (1===1) {
var closeBtn = 2;
console.log(closeBtn);
}
console.log(closeBtn);
It is unclear why you are selecting the element you just added. You can just attach the event when you create the button, no need to look up the element.
var closebtn = $("<button>")...
closeBtn.on("click", function (){
console.log('clicked', closeBtn);
});
Or use event delegation so any element you add will trigger the function.
$("#ticketpanel").on("click", ".close", function () {
const closeBtn = $(this);
console.log('clicked', closeBtn);
});
I am trying to add a click event on an element which i create dynamically in Vanilla JS. With jquery its super simple all i would do is
$(document).on('click','.el', function() {
//somecode
})
However with Vanilla JS (because i'm using react) i can't do the same thing.
I've tried adding the dynamic element as an argument just like i would in jquery but no money.
I'm sure it can be done just not the way i'm thinking. Any ideas?
I tried
let div = document.createElement('DIV')
div.classList.add('el')
document.addEventListener('click','.el', function() {
//some code
})
I also tried
document.addEventListener('click',div, function() {
//some code
})
None of these methods worked
let div = document.createElement('DIV');
div.classList.add(".whatever");
div.addEventListener('click', function() {
console.log('dynamic elements')
});
document.body.appendChild(div);
https://jsfiddle.net/yu1kchLf/
You could simply use and onclick function and just call it as variable from your dynamically added elements.
Live Demo
//Create function
let button = document.createElement('button');
button.classList.add("myBtn");
button.innerText = 'Click Me';
button.onclick = myFunction //assign a function as onclick attr
document.body.appendChild(button);
//Call function
function myFunction() {
console.log('I am being called from dynamically created button')
}
i think what you are missing is appending the element you created to your DOM.
have a look at this:
var createDiv = function() {
let div = document.createElement('DIV');
div.id = 'el';
div.innerHTML = '<b>hey</b>';
div.classList.add('styles');
document.body.appendChild(div);
div.addEventListener('click', function() {
alert('Look here');
})
};
here's a fiddle so you can playaround: https://jsfiddle.net/khushboo097/e6wrLnj9/32/
You can do something like the following:
const d=document.getElementById("container");
document.addEventListener('click', function(ev) {
if (ev.target?.classList.contains('el')) {
console.log("My .el element was clicked!");
ev.target.classList.contains("segundo") &&
(d.innerHTML+='<p class="el">another clickable paragraph</>');
}
})
<div id="container"><h2>Something unclickable</h2>
<p class="el primero">A clickable paragraph!</p>
<p class="otro primero">something unclickable again ...</p>
<button class="el segundo">add clickable element</button>
</div>
The event handler is attached to the document itself but will only fire the console.log() if the ev.target, i. e. the clicked element, is of class "el".
I have multiple selectors in a function with onclick event. And I want to update a global variable based on whichever one is clicked.
var sort = '';
$('#firstName, #lastName, #age, #yearLevel, #gender, #event, #year').onclick(function () {
sort = $(this).attr('id');
});
Will the $(this) use the value of the id which was clicked or all of them?
Question 2:
The ids are for <a>, can I use value attribute in <a>, instead of just getting the id name?
Use click instead of onclick.
var sort = '';
$('#firstName, #lastName, #age, #yearLevel, #gender, #event, #year').click(function ()
{
sort = $(this).attr('id');
});
See Plunker: http://plnkr.co/edit/4mEvS5UE7smOpMFw?open=lib%2Fscript.js
I have a javascript code, which adds an element dynamically and event handler to it.this event handler is called (and vanishes) when the element is added.when I see the dynamically added element through inspector(to see if the event handler was added successfully or not) I can't find onchnage="texttol(eletext)" function added it it.
eletext = document.createElement("input");
eletext.type="text";
eletext.placeholder = "Type Here";
eletext.onchange=texttol(eletext);
event.target.appendChild(eletext);
Add your event handling once the element is actually in the DOM.
var eletext = document.createElement("input");
eletext.type = "text";
eletext.placeholder = "Type Here";
eletext.id = "eletext";
document.body.appendChild(eletext);
eletext.addEventListener('change', function(e) {
texttol(eletext.value);
}, false);
function texttol(str) {
alert('texttol function passes: ' + str);
}
With this line, you are calling the method texttol and attaching whatever it returns to the event handler.
eletext.onchange=texttol(eletext);
You need to use a closure
eletext.onchange = function() { texttol(eletext) };
even better, use addEventListener
i have the same issue but the mentioned solutions do not work.
The event handler function theme_onChange is executed on adding each element.
I have a Bootstrap dropdwn menu (#themeDropdownMenu) and want to fill it dynamically with button elements via looping over the "Themes" object properties.
function setThemes () {
var lstThemes = document.querySelector('#themeDropdownMenu');
var newItem;
for ( x in Themes ) {
newItem = document.createElement('button');
newItem.innerHTML = x;
newItem.classList.add('dropdown-item');
newItem.type='button';
lstThemes.appendChild(newItem);
newItem.addEventListener('click', theme_onChange(newItem) );
}
}
function theme_onChange (item) {
/* console.log("Theme: " + item.innerHTML); */
console.log (item);
}
Result:
console logs each added button element.
I know this question has been answered a lot, but when I applied this solution Event binding on dynamically created elements? the selector selects all the elements and retrieved only the first element
$('body').on('click','a.delete',function() {
var id = $('a.delete').attr('id');
var par = $('a.delete').closest('.foo');
console.log(id);
par.hide();
postDelete(id);
});
.foo is a parent element of a.delete
this code hides all elements with class .foo and delete the first element with class a.delete not the clicked one
How can I retrieve the ID of the element I clicked and hide its parent?
You should use this instead of a.delete in click event to get the reference of clicked a.delete like following.
$('body').on('click', 'a.delete', function () {
var id = $(this).attr('id'); //change here
var par = $(this).closest('.foo'); //change here
console.log(id);
par.hide();
postDelete(id);
})
Use this to get the clicked element.
From the docs, In addition to the event object, the event handling function also has access to the DOM element that the handler was bound to via the keyword this
$('body').on('click', 'a.delete', function() {
var id = $(this).attr('id');
var par = $(this).closest('.foo');
console.log(id);
par.hide();
postDelete(id);
});