HTML Component That Is Fetched With JavaScript Not Responding To Click Event - javascript

I have an HTML component that is fetched when user clicks on a button. This component/modal is used to change a user's profile image (this is processed with PHP). The JavaScript fetch() happens with the following code:
var newProfileImageButton = document.getElementById('replace-profile-photo'),
changeProfileImageWrapper = document.getElementById('change-profile-image-wrapper'),
profileImageModalPath = "modals/change-profile-image.php";
newProfileImageButton.addEventListener('click', function(){
fetch(profileImageModalPath)
.then((response) => {
return response.text();
})
.then((component)=>{
changeProfileImageWrapper.innerHTML = component;
})
.catch((error => {console.log(error)}))
})
This fetched component includes a 'close' button should the user wish to close the modal and not update their profile image.
When I click the close button though nothing is happening. I have the script below - is the issue to do with the fact the Javascript has loaded before the component/modal is fetched? And if so how do I fix this? I guess I could just toggle display:none off and on for this component but would prefer to fetch it if possible.
Note: The button is responding to CSS hover events so I'm confident it's not an HTML / CSS markup issue.
// close button is part of the HTML component that is fetched
var closeComponent = document.getElementById('form-close-x')
if (closeComponent) {
closeComponent.addEventListener('click', function(){
// Hide the main component wrapper so component disappears
changeProfileImageWrapper.style.display = 'none';
})
}
I've also tried using the following code, which I found in a similar question, but this doesn't work either (it was suggested this was a duplicate question).
var closeComponent = document.getElementById('form-close-x')
if (closeComponent) {
closeComponent.addEventListener('click', function(e){
if (e.target.id == 'form-close-x') {
changeProfileImageWrapper.style.display = 'none';
}
})
}

Try this:
// var closeComponent = document.getElementById('form-close-x') <-- remove
// if (closeComponent) { <-- remove
document.addEventListener('click', function(e){
if (e.target.id === 'form-close-x') {
changeProfileImageWrapper.style.display = 'none';
}
})
//} <-- remove

Related

Why doesn't my class names update when set though JS?

This may be a really simple problem but I can't seem to find why this is happening. I'm trying to develop a SPA in vanilla js using webpack, so far I was able to implement routing
with hashchange event and triggering rerendering. But when I tried to add an active class to the relevant link though when the hash changes, It doesn't work. But when I log to the console, it seems that class was added successfully, but in the HTML it doesn't get updated. Why is this?
this is my hashchange listener,
window.addEventListener("hashchange", (e) => {
const hash = window.location.hash.replace("#", "");
const view = routes.find((route) => {
return route.path == hash;
});
const links = document.querySelectorAll(".nav-list--link");
app.render(view.name);
links.forEach((l) => {
const hashHref = l.getAttribute("href").replace("/#", "");
if (hash === hashHref) {
l.classList.add("active");
console.log(l, l.classList);
} else {
l.classList.remove("active");
console.log(l, l.classList);
}
});
});
And this is the console output,
This is the HTML,
I don't understand why it doesn't update in the HTML if it's shown as updated in Javascript

addEventListener' of null

I don't know why it stills showing me addEventListerner of null and as you can see below I add window.onload function. it load the page and then it will break again showing me that the eventListener is null. But if I click on the X button in the page the error disappear and my page is return normal, except that the toggle Icon is not clickable again... Whicm means the event is not listening... please spare me some of your time and help me resolve this issue. Thank you
/*==================== SHOW NAVBAR ====================*/
const showMenu = (headerToggle, navbarId) =>{
const toggleBtn = document.getElementById(headerToggle),
nav = document.getElementById(navbarId)
// Validate that variables exist
window.onload=function(){
if(headerToggle && navbarId){
toggleBtn.addEventListener('click', ()=>{
// We add the show-menu class to the div tag with the nav__menu class
nav.classList.toggle('show-menu')
// change icon
toggleBtn.classList.toggle('bx-x')
})
}
}
}
showMenu('header-toggle','navbar')
/*==================== LINK ACTIVE ====================*/
const linkColor = document.querySelectorAll('.nav__link')
function colorLink(){
linkColor.forEach(l => l.classList.remove('active'))
this.classList.add('active')
}
linkColor.forEach(l => l.addEventListener('click', colorLink))
I hope I understand your problem correctly... if you are getting Cannot read property 'addEventListener' of null error that means that variable on which you are calling this function is null, and I suppose it's coming from this line toggleBtn.addEventListener('click', ()=>{. Make sure toggleBtn is not null, you can check that by using console.log(toggleBtn); before adding listener and then looking into console if it printed null or not. It is possible const toggleBtn = document.getElementById(headerToggle) can't find element with requested id. You haven't provided your HTML code, so that's only a guess.
Your code is not well structured, window.onload should be wrapping your code rather than the other way round. Also if you add an event listener on click, you'll be adding multiple event listeners and your function will fire multiple times. Try something like this (not tested)
const showMenu = (headerToggle, navbarId) => {
nav.classList.toggle("show-menu");
// change icon
toggleBtn.classList.toggle("bx-x");
};
window.onload = function () {
const toggleBtn = document.getElementById(headerToggle),
nav = document.getElementById(navbarId);
if (headerToggle && navbarId) {
toggleBtn.addEventListener("click", () => showMenu);
}
showMenu("header-toggle", "navbar");
};
/*==================== LINK ACTIVE ====================*/
const linkColor = document.querySelectorAll(".nav__link");
function colorLink() {
linkColor.forEach((l) => l.classList.remove("active"));
this.classList.add("active");
}
linkColor.forEach((l) => l.addEventListener("click", colorLink));

CKEditor 5 Insert text on button click - Pure JS

I'm trying to create a sort of dropdown menu that a user can insert tokens into a CKEditor with. I've found that I can insert text in an editor with this code:
editorInstance.model.change( writer => {
let pos = editorInstance.model.document.selection.getFirstPosition();
writer.insertText( "TEST", pos,0);
});
It works when I put it in the ClassicEditor.create.then for testing but it does nothing when I place this in a $().click event. I can log something from inside the callback so I know the code is executed but nothing is inserted.
I've been trying to get this working for hours now but all the examples I can find is in angular or any other frameworks.
I Solved the issue you faced as follows
first defined new editor that is null and Then instatiate Ckeditor 5
let neditor = null;
ClassicEditor.create(document.querySelector('#editor'))
.then(editor => {
neditor = editor;
})
.catch(error => {
console.error(error);
});
using pure js
document.addEventListener("click", (event) => {
var button = event.target;
if (event.target.type === 'button' && event.target.className.includes('testtokenbutton')) {
neditor.model.change(writer => {
const insertPosition = neditor.model.document.selection.getFirstPosition();
writer.insertText(button.id, insertPosition);
});
}
});

Change window.location.href upon dismissal of modal

Following OctoberCMS guidelines I need to redirect users when they attempt to reach a certain path (ex: www.foo.com/bar) to the home page with php variables (ex: www.foo.com/?bar=1) and have a modal open if the variable is found.
I've created bar.htm which redirects with the proper variable:
title = "bar"
url = "/bar"
layout = "default"
meta_title = ""
meta_description = ""
is_hidden = 0
==
<?php
function onStart() {
header('Location:/?bar=1');
}
?>
==
and then in my JS (with #submitBtn being the button on the modal to send the form)
$(document).ready(function(){
if(window.location.href.indexOf('1') > -1) {
$('#myModal').modal('show');
$('#submitBtn').click(function() {
window.location.href='/';
})
}
});
So this is not working, it is just showing the modal in a constant loop and never moving to the success modal or changing the href. This form is working properly in all other situations, so I do not believe the issue lies there.
Shortened example modal code:
$('#myModal').on('show.bs.modal', function (event) {
var newForm = $('#newFakeForm');
var config = {
submitBtn: $('#submitBtn'),
contactModal: $('#myModal'),
successModal: $('#successModal'),
};
initContactForm(newFakeForm, config);
});
and my HTML button to dismiss the modal:
Thank you
What if you do the redirect on JS?
Just listen for the hidden.bs.modal event and do the redirect there.

Javascript and JQuery conflict

I'm not very expert in using javascript and jquery but I'm working with them for a client.
I have encountered a problem using two script: the first one makes a top panel sliding, the second is in a form. This one is used in order to hide or show a particular field basing on the drop down list choice.
I've found that if I disable the first script (the panel), the second script is working fine and vice versa. I tried usign JQuery noConflict() in the head of the page but nothing happened.
Here the code of the first script (sliding panel):
$(document).ready(function () {
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function () {
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
}); // end on DOM
Here the JS code for the form (hide/show field):
$document.addEvent('domready', function () {
$('motivo_contatto').addEvent('change', function () {
if ($('motivo_contatto').value == 'Invia CV') {
$('upload_file').style.visibility = 'visible';
} else {
$('upload_file').style.visibility = 'hidden';
}
});
$('upload_file').style.visibility = 'hidden';
});
});
Can anyone help me ? Thank you and have a nice day!
you're using 2 different ways to add things to happen to the document ready event:
$(document).ready(function(){ ... });
and
$document.addEvent('domready', function() { ... });
maybe if you just use one it works; maybe the code below will work; I put it all in the first option to run code on document ready:
I edited below code and removed all mootools code; so it might work now.
$(document).ready(function(){
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function(){
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
document.getElementById('motivo_contatto').onchange = function() {
if(document.getElementById('motivo_contatto').value == 'Invia CV') {
document.getElementById('upload_file').style.visibility = 'visible';
} else {
document.getElementById('upload_file').style.visibility = 'hidden';
}
};
document.getElementById('upload_file').style.visibility = 'hidden';
}); // end on DOM
Mixing up two different libraries. Not a good idea.
If you want to keep on following on that pattern, wrap one of the function on a different function and call if from another.
Like:
function moo() {
$('motivo_contatto').addEvent('change', function () {
if ($('motivo_contatto').value == 'Invia CV') {
$('upload_file').style.visibility = 'visible';
} else {
$('upload_file').style.visibility = 'hidden';
}
});
$('upload_file').style.visibility = 'hidden';
});
}
Then call it from another
$(document).ready(function () {
moo(); // Call the moo function
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function () {
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
}); // end on DOM
Check this answer, if you want to use both libraries side by side

Categories