Functions on "newly" created objects in Javascript - javascript

Sorry for the title i don't know how to explain it differently.
I created a popup window, there is an "x" close button on right top, advanced and close button on mid bottom. After clicking and replacing text in HTML those newly created buttons just doesn't work.
let mda = document.getElementById("popup");
document.addEventListener("DOMContentLoaded", () => { //show the pop up after loading the stie
mda.style.display = "block";
});
const adv = document.querySelector(".adv"); //Advanced button
let mdc = document.querySelector(".popup-content"); //Pop up content block that changes
adv.onclick = () => {
mdc.innerHTML =
'<span class="close"></span>' + ' ... ' +
'<button class="back">Go back</button>' +
'<button class="closebtn">Go to site</button>'; //Here it creates same button as before
// I thought since it has the same class name it would work but it doesn't,
// tried with simple onclick function but it doesn't work either.
const back = document.querySelector(".back");
back.onclick = () => {
mdc.innerHTML =
'<span class="close"></span>' +
'<button class="adv">Advanced</button>' + //creates adv button again but doesn't work
'<button class="closebtn">Go to site</button>';
};
};
const xbtn = document.querySelector(".close");
const cbtn = document.querySelector(".closebtn");
const close = () => {
xbtn.onclick = () => {
mda.style.display = "none";
};
cbtn.onclick = () => {
mda.style.display = "none";
};
};
close();
I tried everything I could come up with, adding onclick=() to the buttons, addEventListener instead of onclick functions...
Also one weird thing that's happening is if i use getElementByClass or Id instead of query selector those close functions stops working... Please can someone guide me how am i supposed to do it correctly? BTW can't use any libraries.

Related

element.onclick not doesn't call function when element is clicked

I am building a Modal dynamically. I want to make some buttons in this modal to open a SubModal. The buttons show up in html, but clicking these buttons does nothing.
Here is my code.
const subtaskList = document.getElementById('subtaskList');
for (const subtaskIndex in task.subtasks) {
const subtaskButton = document.createElement('button');
subtaskButton.classList.add('taskModalSubtaskButton');
subtaskButton.onclick = () => {
openSubTaskModal(task.subtasks[subtaskIndex], task);
}
subtaskButton.innerText = task.subtasks[subtaskIndex].name;
subtaskList.appendChild(subtaskButton);
subtaskList.innerHTML += '<br>';
}
While troubleshooting I made an array to hold the buttons and used console.log() to see its elements. They all had the onclick function. I've clicked the buttons from the dev console by getting their class name and nothing, so I know it's not a display issue. I feel like I am misunderstanding something and any help would be appreciated.
The problem is subtaskList.innerHTML += '<br>'; it is good idea to use subtaskList.appendChild(document.createElement("br")); instead.
Here is working snippet:
function doSomething(url) {
alert(url);
}
const subtaskList = document.getElementById('subtaskList');
for (var i = 0; i < 3; i++) {
const subtaskButton = document.createElement('button');
subtaskButton.classList.add('taskModalSubtaskButton');
subtaskButton.innerText = "name" + i;
subtaskButton.onclick = (function (url) {
return function () {
doSomething(url);
};
})("URL #" + i)
subtaskList.appendChild(subtaskButton);
subtaskList.appendChild(document.createElement("br"));
}
<div id="subtaskList"></div>
Also I change a bit onclick function to send correspond index to doSomething function

Event listener on multiple elements with the same class

On the site I have a navbar. When I click on the a in navbar I want a new div (with content) appears and everything else "hides". I did it withdisplay: none. In the corner there should be an "X" which closes the div and makes "first screen" appear again.
I did the first part, but have some problems with closing. Here is my code:
const about = document.getElementById('li-about');
const work = document.getElementById('li-work');
const contact = document.getElementById('li-contact');
^These are links in a navbar.
const openSlide = (id) => {
document.querySelector('main article#' + id).style.display = 'block';
document.querySelector('header').style.display = 'none';
};
about.addEventListener('click', () => openSlide('about'));
work.addEventListener('click', () => openSlide('work'));
contact.addEventListener('click', () => openSlide('contact'));
And here is the code. It works. But when I want to do similar thing to a closing div function, it only works with about, not work and contact.
const closeSlide = (id) => {
document.querySelector('main article#' + id).style.display = 'none';
document.querySelector('header').style.display = 'block';
};
const close = document.querySelector('.close');
close.addEventListener('click', () => closeSlide('about'));
close.addEventListener('click', () => closeSlide('work'));
close.addEventListener('click', () => closeSlide('contact'));
Can you tell me why? There is no error in console, I tried to replace closeSlide function with a simple console.log and it doesn't work as well. Is it possible that JavaScript detects only one (first in HTML code) .close div?
Is it possible that JavaScript detects only one (first in HTML code) .close div?
Yes, document.querySelector returns the first matching element it finds in the DOM. If you want to add your listeners to every .close on the page, either loop through the NodeList returned by document.querySelectorAll:
const closeList = document.querySelectorAll('.close');
closeList.forEach(element => {
element.addEventListener('click', () => closeSlide('about'));
element.addEventListener('click', () => closeSlide('work'));
element.addEventListener('click', () => closeSlide('contact'));
};
or add a listener to an element containing all of your .close elements that only takes action if a .close was clicked:
document.querySelector('#some-container').addEventListener('click', evt => {
if (!evt.target.closest('.close')) return;
closeSlide('about');
closeSlide('work');
closeSlide('contact');
});

addEventListener('click') not working on a button to close a modal

So I have a modal that does not seem to want to close when clicking the close button. This what my current code looks like to show and close the modal as well as adding the modal-backdrop into the DOM and removing it.
const $ = document;
class Selectable {
addElement = () => {
const html = '<div class="modal-backdrop show"></div>';
const body = $.querySelector('body');
body.innerHTML += html;
};
removeElement = elementClass => {
let element = $.querySelector('.' + elementClass);
element.parentNode.removeChild(element);
};
showModal = () => {
const modal = $.getElementById('modal-finish');
const body = $.querySelector('body');
modal.classList.add('show');
body.classList.add('modal-open');
this.addElement();
};
closeModal = () => {
const modal = $.getElementById('modal-finish');
const body = $.querySelector('body');
modal.classList.remove('show');
body.classList.remove('modal-open');
this.removeElement('modal-backdrop');
};
init() {
// Look Up Button
$.getElementById('btn-look-up').addEventListener(
'click',
this.showModal,
false
);
// Close the Modal
$.querySelector('.modal-close').addEventListener(
'click',
this.closeModal,
false
);
}
}
const Selectables = new Selectable();
Selectables.init();
I have a feeling it's because the clickEvent is being registered straight away or something but I'm not completely sure.
Basically the modal opens but the close button is not functioning at all.
I've only ever used jQuery before to do JavaScript so I am using const $ = document; to ease the change over to standard JavaScript.
Try below Code:
Try it
document.getElementById("myBtn").addEventListener("click", function(){ document.getElementById("demo").innerHTML = "Hello World";
});

ng-click not working after first click (embedded directives)

I'm having issues with a button and ng-click. I have an input and a button with and ng-click that when click generates 3 random words. I display this words in a div generated by a directive.
The problem I'm having is that when I click the button the first time the code runs perfectly, but when I click again, the button does nothing, I had to implement a clear button that clears the $scopes and then the generate button works again.
This is the code for my button:
<button class="btn btn-default" type="button" ng-click='generateRandom()'>Generate</button>
Here is the code for the directive:
<div jz-tabs camel='camel' snake='snake' kebab='kebab'></div>
The $scope.generateRandom():
$scope.generateRandom = function() {
var temp = '';
Words.getWords($scope.number)
.then(function(response) {
console.log(response);
response.data.forEach(function(e) {
console.log(e);
temp += ' ' + e.word;
});
$scope.camel = lodash.camelCase(temp);
$scope.kebab = lodash.kebabCase(temp);
$scope.snake = lodash.snakeCase(temp);
});
};
I tried clearing the $scopes inside of the function but it looks like after the first ng-click, the function isn't even been called. Does having embedded directives affect ng-clicks?
Any help with this? I don't want to click "clear" every time I want to generate words, I want them to be able to click generate and get random words every time.
Thank you in advance!
UPDATE: Here is a plnkr of the problem: http://plnkr.co/edit/qGB1VjsIJgBzWKl8tXMt?p=preview
I fixed the problem, I had this two functions:
$scope.generateRandom = function() {
var temp = '';
Words.getWords($scope.number)
.then(function(response) {
for (var i = 0; i < response.data.length; i++) {
temp += ' ' + response.data[i].word
}
$scope.camel = temp;
$scope.kebab = temp;
$scope.snake = temp;
});
};
$scope.clear = function() {
$scope.camel = '';
$scope.kebab = '';
$scope.snake = '';
};
All I had to do was add $scope.clear() at the end of the $scope.generateRandom function and it does the trick.

field value gets undefined jquery

Can I Clear a event que in javascript?
when I have done one click event and then does another click event the input field gets the value undefined even when it has a value like "newfile.jpg"
I retrieves the values by doing somevariable = $('#cke_104_textInput').val();
but somevariable gets the value undefined.
here is the javascript code:
$(function () {
// Handler for .ready() called.
function changeLink() {
link = $('#cke_104_textInput').val();
if (link == "") {}
else {
link = link.replace("_", "/");
parts = link.split('.');
explodeExtension = parts[parts.length - 1];
link = link.replace("/download/", "/download/" + explodeExtension + "/");
link = link.replace("." + explodeExtension, "");
$('#cke_104_textInput').val('');
$('#cke_104_textInput').val(link);
clearInterval(changelink);
}
}
function changePic() {
link = $('#cke_103_textInput').val();
if (link == "") {}
else {
link = link.replace("_", "/");
parts = link.split('.');
explodeExtension = parts[parts.length - 1];
link = link.replace("/download/", "/show/" + explodeExtension + "/");
link = link.replace("." + explodeExtension, "");
$('#cke_103_textInput').val('');
$('#cke_103_textInput').val(link);
clearInterval(changepic);
}
}
$('#cke_60').live('click', function (event) {
changelink = setInterval(function () {
changeLink()
}, 1000);
});
$('#cke_64').live('click', function (event) {
changepic = setInterval(function () {
changePic()
}, 1000);
});
});
In the code i try to rewrite the content of two input fields.
this has to be done because the files are not in the sites root they are outside of it, and to be able to show or download them on the site the urls need to be in a specific format.
To answer your first line question, yes you can. Take a look at unbind()
You are creating link as a global variable, which means it is clashing with itself.
Change link = $('#cke_104_textInput').val(); to var link = $('#cke_104_textInput').val();.
Also as a side note, you have this code twice:
$('#cke_104_textInput').val('');
$('#cke_104_textInput').val(link);
which is redundant and inefficient. You should remove the first line in both cases, because selecting an element (even via ID) is not a free operation.

Categories

Resources