Event listener not working after inserting html via js

Label modal is opening at first and label is being appended to parent. when i click on save button im reseting the entire label-create html so that when Add card is clicked previous label doesnt show and i think this is where the issue is, i cant figure out how to work aroud this https://codepen.io/avinash-tallapaneni/pen/VwEGMoK around 45th line is where the issue happens
16 Replies
Jochem
Jochem•2y ago
when you add elements to the dom, you have to manually add the event listeners to them whatever you're using to set saveCardBtn won't rerun just because you added some new element that qualifies for the original selection criteria you used you probably want to define the handler callback itself as a function, then add it whenever you need to:
const saveCardBtnHandler = (event) => { ... };
saveCardBtn.addEventListener("click", saveCardBtnHandler);

//later

document.querySelector(".card-label-assign").innerHTML = `<snip>`;
document.querySelector('whatever you need to do to access the new element').addEventListener("click", saveCardBtnHandler);
const saveCardBtnHandler = (event) => { ... };
saveCardBtn.addEventListener("click", saveCardBtnHandler);

//later

document.querySelector(".card-label-assign").innerHTML = `<snip>`;
document.querySelector('whatever you need to do to access the new element').addEventListener("click", saveCardBtnHandler);
Avinash
Avinash•2y ago
since im removing existing html code, event listners that were attached to the html code will also be removed ? 🤔
Jochem
Jochem•2y ago
yes to be precise, the listener is attached to the DOM element, and when that element gets removed, the listener goes with it
Avinash
Avinash•2y ago
Its not working.
Avinash
Avinash•2y ago
https://codepen.io/avinash-tallapaneni/pen/VwEGMoK I have updated the code, this is how u mean right? check last few line
Jochem
Jochem•2y ago
this isn't all the code, right? so, looking at what you're doing, you seem to be assuming that this:
const labelCreateAdd = document.querySelector(
".card-label-assign div:last-child"
);
const labelCreateAdd = document.querySelector(
".card-label-assign div:last-child"
);
will always contain the element that qualifies for that selector, even if it's removed and re-added later. That's just not true. That code runs once, then stores the element that existed at that point in that variable, and then never updates unless you rerun document.querySelector with that parameter and reassign it yourself the reattach wrapper you made isn't necessary, you just need to rerun that labelCreateAdd line and attach the original event listener back to the new element that's been returned
Avinash
Avinash•2y ago
if i wrap this inside a function
js
const labelCreateAdd = document.querySelector(
".card-label-assign div:last-child"
);
js
const labelCreateAdd = document.querySelector(
".card-label-assign div:last-child"
);
and called after updating new html will it work? 🤔
Jochem
Jochem•2y ago
you shouldn't update variables inside functions, it's an antipattern. You can write a wrapper for the queryselector if you really want to though:
const getLabelCreateAdd = () => document.querySelector(
".card-label-assign div:last-child"
);

let labelCreateAdd = getLabelCreateAdd();
const getLabelCreateAdd = () => document.querySelector(
".card-label-assign div:last-child"
);

let labelCreateAdd = getLabelCreateAdd();
and then later
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd = getLabelCreateAdd();
Avinash
Avinash•2y ago
ok understoood i will give it a try
Jochem
Jochem•2y ago
Just remember, there's no magic in the background in vanilla JS. Nothing happens unless you explicitly tell it to do something. Some frameworks will update things based on what you did before with reactive properties or whatever, but that's not something vanilla will do for you without you explicitly setting it up yourself
Avinash
Avinash•2y ago
const getLabelCreateAdd = () =>
document.querySelector(".card-label-assign div:last-child");
let labelCreateAdd = getLabelCreateAdd();

const labelAddModal = document.querySelector(".label-create");
const labelModalClose = document.querySelector(".label-header svg");

const attachLabelCreateAddListener = () => {
labelCreateAdd.addEventListener("click", () => {
labelAddModal.style.display = "block";
labelCreatePositionModal();
});
};

saveCardBtn.addEventListener("click", (event) => {
..........
document.querySelector(".card-label-assign").innerHTML = `<div class="flex">
<svg>
<use href="icons.svg#IcOutlineAdd"></use>
</svg>
<span> Add </span>
</div>`;
......
updateLabelUI();
}
});

const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", attachLabelCreateAddListener);
};
const getLabelCreateAdd = () =>
document.querySelector(".card-label-assign div:last-child");
let labelCreateAdd = getLabelCreateAdd();

const labelAddModal = document.querySelector(".label-create");
const labelModalClose = document.querySelector(".label-header svg");

const attachLabelCreateAddListener = () => {
labelCreateAdd.addEventListener("click", () => {
labelAddModal.style.display = "block";
labelCreatePositionModal();
});
};

saveCardBtn.addEventListener("click", (event) => {
..........
document.querySelector(".card-label-assign").innerHTML = `<div class="flex">
<svg>
<use href="icons.svg#IcOutlineAdd"></use>
</svg>
<span> Add </span>
</div>`;
......
updateLabelUI();
}
});

const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", attachLabelCreateAddListener);
};
its working. this is how i did it. thumbup
Jochem
Jochem•2y ago
I'm not sure you need that attachLabelCreateAddListener abstraction
const labelCreateAddListener = () => { //instead of attachLabelCreateAddListener
labelAddModal.style.display = "block";
labelCreatePositionModal();
});
........
const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", labelCreateAddListener);
};
const labelCreateAddListener = () => { //instead of attachLabelCreateAddListener
labelAddModal.style.display = "block";
labelCreatePositionModal();
});
........
const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", labelCreateAddListener);
};
unless you're doing something somewhere else in the code that makes it necessary
Avinash
Avinash•2y ago
oh yeah i made a mistake.
Jochem
Jochem•2y ago
in fact, if that's the first time you're using labelCreateAdd, you really don't need to define it at the top, or even the method to abstract the document.querySelector, but again, I can't see all your code
Avinash
Avinash•2y ago
const getLabelCreateAdd = () =>
document.querySelector(".card-label-assign div:last-child");
let labelCreateAdd = getLabelCreateAdd();


const labelCreateAddListener = () => {
labelAddModal.style.display = "block";
labelCreatePositionModal();
};
labelCreateAdd.addEventListener("click", labelCreateAddListener);

saveCardBtn.addEventListener("click", (event) => {
..........
document.querySelector(".card-label-assign").innerHTML = `<div class="flex">
<svg>
<use href="icons.svg#IcOutlineAdd"></use>
</svg>
<span> Add </span>
</div>`;
......
updateLabelUI();
}
});
const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", labelCreateAddListener);
};
const getLabelCreateAdd = () =>
document.querySelector(".card-label-assign div:last-child");
let labelCreateAdd = getLabelCreateAdd();


const labelCreateAddListener = () => {
labelAddModal.style.display = "block";
labelCreatePositionModal();
};
labelCreateAdd.addEventListener("click", labelCreateAddListener);

saveCardBtn.addEventListener("click", (event) => {
..........
document.querySelector(".card-label-assign").innerHTML = `<div class="flex">
<svg>
<use href="icons.svg#IcOutlineAdd"></use>
</svg>
<span> Add </span>
</div>`;
......
updateLabelUI();
}
});
const updateLabelUI = () => {
labelCreateAdd = getLabelCreateAdd();
labelCreateAdd.addEventListener("click", labelCreateAddListener);
};
i have updated. also what do you mean by calling it fr the first time? 🤔
Jochem
Jochem•2y ago
hm, nm, you're using it earlier, I missed that
Want results from more Discord servers?
Add your server