This js code is supposed to change the the value of class attribute 'skills__open' to 'skills__close' when the 'skills__header' div is clicked. It changes the 'skills__open' to 'skills__close' on the first click, but after the first click, it is not working.
Js
const skillsContent = document.getElementsByClassName('skills__content'),
skillsHeader = document.querySelectorAll('.skills__header')
function toggleSkills(){
let itemClass = this.parentNode.ClassName
for(i=0; i < skillsContent.length; i++){
skillsContent[i].className = 'skills__content skills__close'
}
if(itemClass === 'skills__content skills__close'){
this.parentNode.className = 'skills__content skills__open'
}
}
skillsHeader.forEach((el) =>{
el.addEventListener('click', toggleSkills)
});
Html
<div class="skills__content skills__open">
<div class="skills__header">
</div>
<div class="skills__content skills__close">
<div class="skills__header">
</div>
<div class="skills__content skills__close">
<div class="skills__header">
</div>
css
.skills__open .skills__list{
height: max-content;
margin-bottom: var(--mb-2-5);
}
.skills__open .skills__arrow{
transform: rotate(-180deg);
}
nothing significant
try that:
const skillsContents = document.querySelectorAll('.skills__content');
skillsContents.forEach( skc =>
{
skc
.querySelector('.skills__header')
.addEventListener('click', () =>
{
skillsContents.forEach( el =>
{
if (skc===el) el.classList.replace('skills__close','skills__open')
else el.classList.replace('skills__open','skills__close')
})
})
});
Related
Here is the case. I have a page, on which I have several options to choose. Choice is being made by clicking a link, which leads to an anchor and displays necessary content. Unfortunately this could not be changed. The problem is, that I also have a language panel, which leads me to the same page but already translated to necessary locale. My goal is to be able change language, but also save the chosen anchor from a clicked link. Was not able to find solution yet, could someone please give any idea, how that could be done?
Here is link to a fiddle https://jsfiddle.net/william_eduards/psuLrv02/87/
let contents = Array.from(document.querySelectorAll('.content'));
let contentOne = document.querySelector('.content--a');
let contentTwo = document.querySelector('.content--b');
const handleClick = (e) => {
e.preventDefault();
contents.forEach(node => {
node.classList.remove('active');
});
e.currentTarget.classList.add('active');
if (document.querySelector('.content-a').classList.contains('active')) {
contentOne.classList.add('show');
} else {
contentOne.classList.remove('show');
}
if (document.querySelector('.content-b').classList.contains('active')) {
contentTwo.classList.add('show');
} else {
contentTwo.classList.remove('show');
}
}
contents.forEach(node => {
node.addEventListener('click', handleClick);
});
.content--a, .content--b {
display: none;
}
.show {
display: block;
}
<div class="container">
<div class="select-option">
<a class="content content-a" href="#contentA">Content A</a>
<a class="content content-b" href="#contentB">Content b</a>
</div>
<div class="options">
<div class="content--a" id="contentA">
<p>I am content a</p>
</div>
<div class="content--b" id="contentB">
<p>I am content b</p>
</div>
</div>
</div>
To show your contents, just use CSS with pseudo class :target (remove all your js)
.content--a, .content--b {
display: none;
}
.options > *:target {
display: block;
}
If your page is reloaded when you select language, use sessionStorage to remember which link was last clicked, and restore it on next page load. Following code assumes the URL is unchanged when you switch languages:
window.addEventListener('DOMContentLoaded', e => {
const contents = document.querySelectorAll('.content');
//Save selection on click as url#anchor
contents.forEach(node => {
node.addEventListener('click', e => {
const href = node.getAttribute('href');
console.log(href);
if (href) {
const spl = href.split('#');
if (spl.length > 1 && spl[1].length) {
const spl2 = window.location.href.split('#');
sessionStorage.setItem('shown-content', spl2[0] + '#' + spl[1]);
console.log(sessionStorage.getItem('shown-content'));
}
}
});
});
//Restore selection on load if URL is the same up until anchor
const anch = sessionStorage.getItem('shown-content');
if (anch) {
const spl = anch.split('#');
if (spl.length) {
const spl2 = window.location.href.split('#');
console.log(spl[0], spl2[0]);
if (spl[0] == spl2[0])
window.location.href = anch;
}
}
});
Adapt above code to your needs if URL changes between languages
Full example (doesn't run as a snippet. Use server or local html file)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Test</title>
<style>
.content--a, .content--b {
display: none;
}
.options > *:target {
display: block;
}
</style>
<script>
window.addEventListener('DOMContentLoaded', e => {
const contents = document.querySelectorAll('.content');
//Save selection on click as url#anchor
contents.forEach(node => {
node.addEventListener('click', e => {
const href = node.getAttribute('href');
console.log(href);
if (href) {
const spl = href.split('#');
if (spl.length > 1 && spl[1].length) {
const spl2 = window.location.href.split('#');
sessionStorage.setItem('shown-content', spl2[0] + '#' + spl[1]);
console.log(sessionStorage.getItem('shown-content'));
}
}
});
});
//Restore selection on load if URL is the same up until anchor
const anch = sessionStorage.getItem('shown-content');
if (anch) {
const spl = anch.split('#');
if (spl.length) {
const spl2 = window.location.href.split('#');
console.log(spl[0], spl2[0]);
if (spl[0] == spl2[0])
window.location.href = anch;
}
}
});
</script>
</head>
<body>
<div class="container">
<div class="languages">
English
Français
</div>
<div class="select-option">
<a class="content content-a" href="#contentA">Content A</a>
<a class="content content-b" href="#contentB">Content b</a>
</div>
<div class="options">
<div class="content--a" id="contentA">
<p>I am content a</p>
</div>
<div class="content--b" id="contentB">
<p>I am content b</p>
</div>
</div>
</div>
</body>
</html>
You can simply save the element which is active. No big deal.
let contents = Array.from(document.querySelectorAll('.content'));
...
let activeEl = null;
const handleClick = (e) => {
...
e.currentTarget.classList.add('active');
activeEl = e.currentTarget; // adding the `<a/>` tag in a global
...
}
I'm wanting to add the Google Maps API div, <div id="map"></div> within a card that's dynamically added to the DOM, after a user has input a search. I'm able to append it the main div, as a test, but not within the card one I'm appending after the the card is inserted into the DOM.
Code is below.
const APIURL = 'https://restcountries.eu/rest/v2/name/'
const GOOGLE_MAPS_API = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDhlU1KMTlTh4C__bTJBxbVA-s7wvQbO9E&callback=initMap'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')
async function getCountryData(name) {
try {
const { data } = await axios.get(APIURL + name)
data.forEach(res => {
const countryData = res
addGMapsEl()
createCountryCard(countryData)
getLatLngPos(countryData)
} )
} catch (err) {
if(err.response.status == 404) {
createErrorCard('No countries found')
setTimeout(() => {
main.innerHTML = ''}
, 1500);
}
}
}
// Google Map API
function addGMapsEl() {
const script = document.createElement('script');
script.src = GOOGLE_MAPS_API;
script.defer = true;
document.head.appendChild(script);
const mapDiv = document.createElement('div')
mapDiv.id = 'map'
main.appendChild(mapDiv)
}
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 51, lng: 9},
zoom: 7
});
}
function createCountryCard(country) {
const cardHTML = `
<div class="content-container">
<div class="card">
<div class="wrapper">
<div class="card-title">
<h2>${country.name}</h2>
<h4>Capital: ${country.capital}</h4>
<h5>Population: ${country.population.toLocaleString('en')}</h5>
</div>
<div class="card-image">
<img
src="${country.flag}"
alt="${country.name +'-flag'}"
/>
</div>
</div>
<div class="wrapper">
<div class="map-content">
</div>
<div class="card-content">
<ul class="card-list">
<li><strong>Region:</strong> ${country.region}</li>
<li><strong>Subregion:</strong> ${country.subregion}</li>
<li><strong>Currency:</strong> ${country.currencies[0].name}<span> ${country.currencies[0].symbol}</span></li>
<li><strong>Spoken Language:</strong> ${country.languages[0].name}</li>
<li><strong>Timezone:</strong> ${country.timezones}</li>
</ul>
</div>
</div>
</div>
</div>
`
main.innerHTML += cardHTML
}
// Creates error card after no results found
function createErrorCard(msg) {
const cardHTML = `
<div class="card">
<h1>${msg}</h1>
</div>
`
main.innerHTML = cardHTML
}
// Clears the DOM on search
function clearDOM() {
main.innerHTML = ''
}
// Search Input
form.addEventListener('submit', (e) => {
e.preventDefault()
clearDOM()
const countryName = search.value
if(countryName) {
getCountryData(countryName)
search.value = ''
}
})
<body>
<div class="search-container">
<form id="form" class="form">
<input type="text" id="search" placeholder="Search for country..." />
</form>
</div>
<main id="main"></main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="script.js"></script>
</body>
Ok - so - to create a MAP you need to use new google.maps.Map( ELEMENT_TO_CONTAIN_THE_MAP, MAP_OPTIONS) which is in your mapInit func.
You should also load the API only once - so i moved things a little bit in your code...
I have removed the callback=initMap from your maps url - because your element doesn't exist in the DOM at the moment when google's script is loaded.
Then placed the call to mapInit after your createCountryCard call - because it adds your map element to the DOM - and now we can place the map within it.
Given your element the id argument <div class="map-content" id="map-content">. And then changed the id in mapInit function to match your elements id which is map-content.
const APIURL = 'https://restcountries.eu/rest/v2/name/'
const GOOGLE_MAPS_API = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDhlU1KMTlTh4C__bTJBxbVA-s7wvQbO9E'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')
async function getCountryData(name) {
try {
const {
data
} = await axios.get(APIURL + name)
data.forEach(res => {
const countryData = res
//gmaps element is on card
createCountryCard(countryData);
initMap();
getLatLngPos(countryData)
})
} catch (err) {
if (err.response.status == 404) {
createErrorCard('No countries found')
setTimeout(() => {
main.innerHTML = ''
}, 1500);
}
}
}
// Google Map API
function addGMapsEl() {
const script = document.createElement('script');
script.src = GOOGLE_MAPS_API;
script.defer = true;
document.head.appendChild(script);
const mapDiv = document.createElement('div')
mapDiv.id = 'map'
main.appendChild(mapDiv)
}
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map-content"), {
center: {
lat: 51,
lng: 9
},
zoom: 7
});
}
function createCountryCard(country) {
const cardHTML = `
<div class="content-container">
<div class="card">
<div class="wrapper">
<div class="card-title">
<h2>${country.name}</h2>
<h4>Capital: ${country.capital}</h4>
<h5>Population: ${country.population.toLocaleString('en')}</h5>
</div>
<div class="card-image">
<img
src="${country.flag}"
alt="${country.name +'-flag'}"
/>
</div>
</div>
<div class="wrapper">
<div id="map-content" class="map-content">
</div>
<div class="card-content">
<ul class="card-list">
<li><strong>Region:</strong> ${country.region}</li>
<li><strong>Subregion:</strong> ${country.subregion}</li>
<li><strong>Currency:</strong> ${country.currencies[0].name}<span> ${country.currencies[0].symbol}</span></li>
<li><strong>Spoken Language:</strong> ${country.languages[0].name}</li>
<li><strong>Timezone:</strong> ${country.timezones}</li>
</ul>
</div>
</div>
</div>
</div>
`
main.innerHTML += cardHTML
}
// Creates error card after no results found
function createErrorCard(msg) {
const cardHTML = `
<div class="card">
<h1>${msg}</h1>
</div>
`
main.innerHTML = cardHTML
}
// Clears the DOM on search
function clearDOM() {
main.innerHTML = ''
}
// Search Input
form.addEventListener('submit', (e) => {
e.preventDefault()
clearDOM()
const countryName = search.value
if (countryName) {
getCountryData(countryName)
search.value = ''
}
})
addGMapsEl();
.map-content {
width: 100%;
height: 300px;
}
.card-image img {
max-height: 50px;
box-shadow: 1px 1px 5px #aaa;
}
<body>
<div class="search-container">
<form id="form" class="form">
<input type="text" id="search" placeholder="Search for country..." />
</form>
</div>
<main id="main"></main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="script.js"></script>
</body>
Looks like it works now ...you probably want to use setCenter on yor map later to move the view to the new location - do it after mapInit
Added some CSS also - to give a size for the map element and shrink that huge flag you had.
I can see the url in your constant is wrong ... the correct one will be :
'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap'
Another thing you never call addGMapsEl() function to initialize the map.
Finally the .card-content element isn't presented on DOM.
To present the country on map you should create an event to handle that
$(document).on("input", "#search", function(e){
//handle input information here
})
I'm trying to implement a searchbar to search adresses and show the selected place on a map.
When I type in the searchbar the results are showing in a dropdown, now I want to edit my map and other stuff when I click on a result.
But I can't manage to add a listener to the elements (which are dynamically created when I got the results of the search), no matter what I try (addEventListener, JQuery, href) when I inspect the elements on my browser no listener is attached to any of them.
Here is my html :
<div class="container p-3 text-center text-md-left clearfix">
<h1>Smart-bornes</h1>
<p>Je localise les smart-bornes les plus proches</p>
<div class="input-group dropdown mx-auto w-75 float-md-left">
<input id="localisation_barreRecherche" class="form-control" type="text" placeholder="Rechercher un lieu"/>
<button id="localisation_boutonRecherche" class="btn btn-light">Rechercher</button>
<div id="localisation_dropdownRecherche" class="dropdown-menu w-100"></div>
</div>
</div>
<div class="container p-3">
<div id="map"></div>
</div>
And my JS:
function initBarreRecherche(){
let barreRecherche = document.getElementById('localisation_barreRecherche');
let boutonRecherche = document.getElementById('localisation_boutonRecherche');
let dropdownResultats = document.getElementById('localisation_dropdownRecherche');
barreRecherche.onkeyup = function (event) {
console.log('onkeyup');
if(event.key === 'Enter'){
}else if(event.key === 'keydown'){
}else if(barreRecherche.value !== '') {
rechercheAdr(barreRecherche.value);
$(dropdownResultats).show();
}else{
$(dropdownResultats).hide();
}
};
boutonRecherche.onclick = function () {
}
}
function rechercheAdr(entree){
console.log('recherche');
return new Promise((resolve, reject) => {
fetch(rechercheURL + entree)
.then(resp => {
return resp.text();
})
.then(adressesJSON => {
let adresses = JSON.parse(adressesJSON);
let dropdownResultats = document.getElementById('localisation_dropdownRecherche');
//dropdownResultats.style.width = '100%';
dropdownResultats.style.zIndex = '10000';
let resultats = document.createElement('ul');
resultats.className = 'list-group';
if(adresses.length > 0){
for(let [key, adr] of Object.entries(adresses)){
let result = document.createElement('li');
result.className = 'list-group-item list-group-item-action';
result.href = 'javascript : resultOnClick(adr)';
result.style.paddingLeft = '5px';
result.style.paddingRight = '5px';
result.style.cursor = 'pointer';
//result.style.overflow = 'hidden';
result.innerText = adr.display_name;
result.addEventListener('click', () => console.log('onclick'));
resultats.appendChild(result);
}
}else{
console.log('aucun résultat');
let msgAucunResultat = document.createElement('li');
msgAucunResultat.style.paddingLeft = '5px';
msgAucunResultat.style.paddingRight = '5px';
msgAucunResultat.innerText = 'Aucun résultat';
resultats.appendChild(msgAucunResultat);
}
dropdownResultats.innerHTML = resultats.innerHTML;
console.log(adresses)
})
})
}
manually call initBarreRecherche() at the end of response.
.then(adressesJSON => {
///....
this.initBarreRecherche()
})
You are using jquery so instead of all 'onClick' syntax, or addEventListener, you can attach click handler like:
$(dropdownResultats).on('click', 'li', event => {
alert('some li clicked')
})
I am making a website with a text input box.
I have this piece of code in a JS file:
$(document).ready(function() {
$("#filterTextBox").on("keyup", function () {
var search = this.value;
$(".person").show().filter(function () {
return $(".name", this).text().indexOf(search) < 0;
}).hide();
});
});
With this when I search "hello", it won't find the name "Hello"
Can I make it doesn't matter if it is "Hello" or "hELLo" or whatever?
You Can
Use toLowerCase() to convert all of user inputs to lower case so every time you compare or use a word you already matching the same value if non-casing words
For Example
"Hello".toLowerCase() outputs 'hello'
"hELLo".toLowerCase() outputs 'hello'
In your code
Make sure $(".name", this).text() is lowercased before you search for the index of the search value
So you code will be something like that
//hide all the elements except for the matches
$(document).ready(function() {
$("#filterTextBox").on("keyup", function () {
var search = this.value.toLowerCase();
$(".person").show().filter(function () {
return $('.name', this).text().toLowerCase().indexOf(search)<0;
}).hide();
});
});
Thanks #mark.hch for your code https://jsfiddle.net/yd9k12bz/
The vanilla version shows how everything fits together.
const getPeople = () => document.querySelectorAll('.person');
document.addEventListener('keyup', ({ target }) => {
if (target.matches('#search')) {
const searchFor = target.value.toLowerCase();
if (searchFor.length > 0) {
getPeople().forEach(p => {
if (p.innerText.toLowerCase().includes(searchFor)) {
p.classList.remove('hide');
} else {
p.classList.add('hide')
}
});
} else {
// Show all
getPeople().forEach(p => p.classList.remove('hide'));
}
}
})
.hide {
display: none;
}
<div class="person">Paul T</div>
<div class="person">John B</div>
<div class="person">David C</div>
<div class="person">Lisa A</div>
<div class="person">Claire W</div>
<div class="person">Paul W</div>
<div class="person">John F</div>
<div class="person">David S</div>
<div class="person">Lisa R</div>
<div class="person">Claire B</div>
<input type="text" id="search">
Here is part of my html layout (with sciter framework):
<div id="volume_micphone_slider" style="z-index:1;">
<input id="volume_slider" class="volume_slider" type="vslider" name="p1c" max="100" value="20" buddy="p1c-buddy" />
</div>
<div>
<button id="volume_show" class="volume_show" ></button>
<button id="micphone_show" class="micphone_show"></button>
</div>
Here is my onClick() method of the Button(use tiscript):
var volume_flag=1;
function volume_ctrl()
{
if(volume_flag)
{
$(#volume_slider).style#display ="none";
volume_flag=0;
}
else
{
$(#volume_slider).style#display ="inline-block";
volume_flag=1;
}
}
$(#volume_show).onClick = function()
{
volume_ctrl();
}
But this method can't be useful.Please help me to figure out my problem.Thanks.
Multiple problems in your code as explained inline
var volume_flag=1;
function volume_ctrl()
{
if(volume_flag)
{
$("#volume_slider").style.display ="none"; //selector in quotes and . before style
volume_flag=0;
}
else
{
$("#volume_slider").style.display ="inline-block";
volume_flag=1;
}
}
$("#volume_show").onclick = function() //small c instead of C in onclick
{
volume_ctrl();
}
it is pure javascript code
var volume_flag = 1;
function volume_ctrl() {
if (volume_flag) {
document.getElementById('volume_slider').style.display = "none";
volume_flag = 0;
} else {
document.getElementById('volume_slider').style.display = "inline-block";
volume_flag = 1;
}
}
document.getElementById('volume_show').addEventListener("click", function() {
volume_ctrl();
})