How to modify outside variable from inside an event handler in javascript? - javascript

I have a button with a click event listener
let button = document.createElement('button');
let show = false;
button.addEventListener('click', (e) => {
e.stopPropagation();
show = !show;
console.log("show from inside:", show)
});
console.log("show from outside:", show) // => is always equal to false
But this line above still shows the same value for variable show as initialized.
How can i modify show variable from inside like this line show = !show and get that modification from outside at this line console.log("show from outside:", show) ?

You have created the element but did not append it to body/parent node. You need to add the following line to your code.
document.body.appendChild(button);
If you need to get the modified show value, you can write a function to return the value of show and use it whereever you want.
Final Code:
let button = document.createElement('button');
document.body.appendChild(button);
let show = false;
function getShow() { return show; } // => returns the latest value of show
button.addEventListener('click', (e) => {
e.stopPropagation();
show = !show;
console.log("show from inside:", getShow());
});
console.log("show from outside:", getShow()); // => Keep in mind that this line will run before the event handler does and only for once.
Hope this helps!

Related

I have to double click the follow button to functioning this is due to using click event 2 time

I am working on follow button and with the help of JavaScript I've come up with the following code.
But the problem is I have to double click the follow button to functioning this is due to using click event 2 time. I am open to better methods of solving this too.
var value = null;
const onClick = (event) => {
// event.target.id
value = event.target.id;
console.log(value);
document.getElementById(`${value}`).addEventListener('click',function(){
// console.log(value.id);
if(this.classList.contains('follow')){
this.classList.remove('follow');
this.innerHTML ="Following";
this.style.backgroundColor = 'green' ;
}else{
this.classList.add('follow');
this.style.backgroundColor = 'rgb(27,18,83)' ;
this.innerHTML="Follow";
}
})
}
window.addEventListener('click', onClick);
There is a double click event. You can check the if it satisfies your requirement.
MDN link - https://developer.mozilla.org/en-US/docs/Web/API/Element/dblclick_event
For multiple buttons with the same function, I would give all of them the same class (e.g. "btn"). Then in JS simply get all of the elements with this class, loop over the HTMLCollection which you would get and assign each element an eventlistener. When you want to change something on the button you have to use event.target in the function:
let buttons = document.getElementsByClassName("btn");
for (btn of buttons) {
btn.addEventListener("click", (event) => {
if(event.target.classList.contains('follow')){
event.target.classList.remove('follow');
event.target.innerHTML ="Following";
event.target.style.backgroundColor = 'green' ;
}else{
event.target.classList.add('follow');
event.target.style.backgroundColor = 'rgb(27,18,83)' ;
event.target.innerHTML="Follow";
}
});
}
<button class="btn">1</button>
<button class="btn">2</button>

How to change variable value when click function is called?

I want to change the check value from false to true whenever I click on the a link. So far I've not found any suggestions on how to do this
Click Me
let check = false;
document.querySelectorAll('.click').forEach(item => {
item.addEventListener('click', event => {
check = true;
});
});
console.log(check);
Your console.log() is being executed after you assign the onclick event, not after it is called - So the only thing you log is the value of checked at the very beginning of your script
I've moved the console.log() inside the function, and also added a separate button so you can confirm that the value of check has changed in the global scope
let check = false;
document.querySelectorAll('.click').forEach((item) => {
item.addEventListener('click', (event) => {
check = true;
// Check value has changed
console.log(check);
});
});
Click Me
<br>
<button style="margin-top: 10px" onclick="console.log(check);">Console.log(check)</button>
Your solution already works, you just have to move your console.log(check) to print the new value
let check = false;
document.querySelectorAll('.click').forEach(item => {
item.addEventListener('click', event => {
check = true;
// print the new value
console.log(check);
});
});
console.log(check);
Click Me

How do I get my modal to close when a user clicks on the container?

I'm currently studying a full stack course and my modal isn't behaving as expected
I'm a bit lost on what to do as I can't find any documentation anywhere and while clicking on the close button or pressing ESC works, clicking outside of the box doesn't.
The following code is how it has been suggested I approach the issue but, it doesn't work. I've honestly stared at this for about an hour and just can't connect the dots on what is (not) happening? Please excuse all the commenting and additional code as I'm still learning so, it's how I'm able to follow what's going on:
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
}
//modal IFFE
document.querySelector('#modal-button').addEventListener('click', () => {
showModal();
});
//-- show modal --
function showModal(title, text) {
var $modalContainer = document.querySelector('#modal-container');
//Selects the element with the associated id
// Clear all content for the selected element
$modalContainer.innerHTML = '';
var modal = document.createElement('div'); //creates a div element withing selected element
modal.classList.add('modal'); //assigns new class to the div element
// Add the new modal content
var closeButtonElement = document.createElement('button'); //creates the close button
closeButtonElement.classList.add('modal-close'); //assigns a class to the new (close) button
closeButtonElement.innerHTML = "×"; //inserts text within the new(close) button
closeButtonElement.addEventListener('click', hideModal);
var titleElement = document.createElement('h1');
titleElement.innerText = title;
var contentElement = document.createElement('p');
contentElement.innerText = text;
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
}
document.querySelector('#modal-button').addEventListener('click', () => {
showModal('PokéMon', 'Here is all of the info about your PokéMon');
});
window.addEventListener('keydown', (e) => {
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-
visible')) {
hideModal();
}
});
$modalContainer.addEventListener('click', (e) => {
var target = e.target;
if (target === $modalContainer) {
hideModal();
}
});
Expected result: User clicks outside of the modal (on the container) and the modal closed.
Current result: No change in state, modal remains active and visible. Only by clicking on the close button (x) or by pressing ESC is the desired result achievable.
By Looking at this code I am not sure what is actually supposed to make the modal visible or hide it. Without access to your css (if you have any). I am assuming that all you are doing is adding and removing the class .is-visible from the #modal-container element.
I would suggest that you apply this class to the modal itself, and then you could toggle this class on and off,
Modify your code to do this by doing something like this (added on top of your code):
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
document.querySelector('.modal').classList.remove('hide-el')
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
document.querySelector('.modal').classList.add('hide-el')
}
Where hide-el in your css is:
.hide-el {
display: none;
}
You could also modify your code to appply the is-visible class to your modal element. You should always try to attach the class/id to the element you want to manipulate if you have that option.
Or if you do not have access to a css file:
document.querySelector('.modal').style.display = "none"
and
document.querySelector('.modal').style.display = "block"
Also, your code seems very verbose, was this boilerplate part of the assignment?
heres a working example: https://codepen.io/mujakovic/pen/zVJRKG
The code was in the incorrect place in the end and should have looked something like this:
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentImage);
modal.appendChild(contentHeight);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
$modalContainer.addEventListener('click', (e) => { //listening for an event (click) anywhere on the modalContainer
var target = e.target;
console.log(e.target)
if (target === $modalContainer) {
hideModal();
}
});
};
window.addEventListener('keydown', (e) => { //listening for an event (ESC) of the browser window
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-visible')) {
hideModal();
}
});
This is because the action was originally being called on page load and targeted within the window instead of being called within the container and being loaded when the modal loads.
Thank for your help

bootstrap dropdown doesn't work as expected

I'm using dropdown functionality of bootstrap and I have this dropdown in container, but in outside I have wrapper, which is reacting on the same event (onclick), so I do
e.stopPropagation();
because I don't want to react on event in wrapper, when I'm clicking dropdown button. Unfortunately, this code also stops my dropdown event. Is it possible to avoid this behaviour and display only dropdown list, without alert?
https://jsfiddle.net/hms5265s/
Here is my solution.
document.querySelector('.container').addEventListener('click', (e) => {
if($(e.target).is("#dropdown")){
alert('work');
}
else{
e.stopPropagation();}
});
If you want your alert to be called on the click event of the wrapper but not the click event of the dropdown iteself you can try something like this
document.querySelector('#wrapper').addEventListener('click', (e) => {
var source = event.target || event.srcElement;
console.log(source.id);
if (source.id !== 'someId') {
// do some stuff
alert("I don't want this alert");
}
// you can stop the even propagation here if you want to.
});
Here is a JSFiddle
If you also don't want to assign an Id for your dropdown you can also check for a class.
here is my solution
Element.prototype.hasClass = function(className){
tClassName = this.className;
return tClassName.match(".*[ ]?"+className+"[ ]?.*") ? true : false;
};
document.querySelector('#wrapper').addEventListener('click', (e) => {
console.log('clicked' + e.target.hasClass('dropdown-toggle'));
if(e.target.hasClass('dropdown-toggle')) return
alert("I don't want this alert");
});
document.querySelector('.dropdown-menu').addEventListener('click', (e) => {
e.stopPropagation();
});
https://jsfiddle.net/hms5265s/6/
updated solution:
Element.prototype.hasClass = function(className){
tClassName = this.className;
return tClassName.match(".*[ ]?"+className+"[ ]?.*") ? true : false;
};
document.querySelector('#wrapper').addEventListener('click', (e) => {
if(e.target.hasClass('dropdown-toggle')) return
alert("I don't want this alert");
});
document.querySelector('.container').addEventListener('click', (e) => {
if(! e.target.hasClass('dropdown-toggle')){
e.stopPropagation();
}
});
https://jsfiddle.net/hms5265s/12/

How to keep extra fields added by js on refresh

var container = document.createElement("lastExp");
container.innerHTML = 'html code new form field';
document.getElementById("lastExp").appendChild(container);
It's simple i click button extra form field is added.
Question: When i refresh page how to not lose this extra fields on my form.
Stack Overflow is not the place to write code, but this will sits here in case someone besides OP need.
It's a minimal example--getting started--with localStorage. As I mentioned, under the hood, you have to append that element every time the page is loaded.
The snippet won't work here, unfortunately because the iframe is sandbox'd. Head over to my hub to experiment it.
var container = document.getElementById('container'),
toggle = document.getElementById('toggle');
element = null;
// initial check
init();
// add click event and listen for clicks
toggle.onclick = function() {
// both cases will update localStoage _inputIsThere
// if element is null -- doesn't exists, then add it
if (element == null) {
add();
} else {
// remove the element
remove();
}
}
// check if key exists in localStorage; this is where all the "magic" happens.
function init() {
var exists = localStorage.getItem('_inputIsThere');
if (exists && exists == 'true') {
add();
}
}
function remove() {
element.remove();
element = null;
// update key in localStorage to false
localStorage.setItem('_inputIsThere', false);
}
// adds the input and updates
function add() {
var e = document.createElement('input');
e.type = 'text';
element = e;
container.appendChild(e);
// update key in localStorage to true
localStorage.setItem('_inputIsThere', true);
}
<button id="toggle">Add/Remove</button>
<div id="container"></div>

Categories

Resources