I want to get the values from clicking the button with same class name, but whenever I clicked the button it shows undefined.
var clr;
const btn = document.querySelectorAll('.color');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
const btn = document.querySelectorAll('.color'); gets the div not the buttons. Change that to const btn = document.querySelectorAll('.btn');:
var clr;
const btn = document.querySelectorAll('.btn');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
If you only want the value from the button being clicked, then change your code to
function myFunction(btn) {
console.log(btn.value);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(this)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(this)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(this)"> Purple </button>
</div>
do it in this way it will give you exact result
function myFunction(event) {
clr = event.target.value;
console.log(clr);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(event)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(event)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(event)"> Purple </button>
</div>
First: scripting where scripting should be (no inline handlers). So add an event listener to the document, and let it check if the target (the element clicked) has classname btn. In that case: iterate through the an Array of elements with className btn (Array.from(document.querySelectorAll(".btn"))) using Array.forEach to display the values of those elements.
document.addEventListener("click", myFunction);
function myFunction(evt) {
console.clear();
if (evt.target.classList.contains("btn")) {
// a button.btn was clicked, so
let report = `You clicked button with value ${evt.target.value}. Other .btn values:`;
let values = [];
Array.from(document.querySelectorAll(".btn"))
.forEach(val => val !== evt.target && values.push(val.value));
console.log(`${report} ${values.join(", ")}`);
}
}
<div class="color">
<button class="btn" value="#BADA55"> Yellow </button>
<button class="btn" value="#10A426"> Green </button>
<button class="btn" value="#8787DE"> Purple </button>
</div>
Related
I am looking for an easy and clean Vanilla JS solution for this jQuery code:
$(this).addClass('highlighted');
$('button').not(this).removeClass('highlighted');
When I click a specific button element, it should add the class 'highlighted', all the other button elements not(this) should have the highlighted class removed.
If your buttons have IDs, using them would be a good solution. Otherwise, you can simply filter the results from querySelectorAll:
Using ids:
function highlight(event) {
const target = event.target;
target.classList.add('highlighted');
document.querySelectorAll(`button:not(#${target.id})`).forEach(item => item.classList.remove('highlighted'));
}
.highlighted {
background: pink
}
<button id="btn1" onclick="highlight(event)">Button 1</button>
<button id="btn2" onclick="highlight(event)">Button 2</button>
<button id="btn3" onclick="highlight(event)">Button 3</button>
<button id="btn4" onclick="highlight(event)">Button 4</button>
Filtering the results:
function highlight(event) {
const target = event.target;
target.classList.add('highlighted');
Array.from(document.querySelectorAll(`button`)).filter(item => item != target).forEach(item => item.classList.remove('highlighted'));
}
.highlighted {
background: pink
}
<button onclick="highlight(event)">Button 1</button>
<button onclick="highlight(event)">Button 2</button>
<button onclick="highlight(event)">Button 3</button>
<button onclick="highlight(event)">Button 4</button>
If you remove the highlighted class from all buttons first, you can add it afterward to the only highlighted button.
const stripHighlighted = (button) => {
button.classList.remove("highlighted");
}
document.querySelectorAll("button").forEach(stripHighlighted);
this.classList.add("highlighted");
I have 3 blocks, when opening one, all should hide. I wrote the simplest code (I'm a beginner), I understand that it can and should be optimized. How can I do that?
I'm thinking of using "if else" construction, but not sure how to do it correctly.
function openLink(){
document.getElementsByClassName('open_link')[0].style.display = 'block';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
function openImages(){
document.getElementsByClassName('open_images')[0].style.display = 'block';
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
function openVideo(){
document.getElementsByClassName('open_video')[0].style.display = 'block';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_link')[0].style.display = 'none';
}
function closeForm(){
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
<a onclick="openLink()" href='#'>One</a>
<a onclick="openVideo()" href='#'>Two</a>
<a onclick="openImages()" href='#'>Three</a>
<div class="open_link" style="display: none;">
<button onclick="closeForm()">Save 1</button>
<button onclick="closeForm()">Close 1</button>
</div>
<div class="open_video" style="display: none;">
<button onclick="closeForm()">Save 2</button>
<button onclick="closeForm()" >Close 2</button>
</div>
<form class="open_images" style="display: none;">
<input onclick="closeForm()" value="Upload 3"/>
<button onclick="closeForm()" >Close 3</button>
</form>
Delegate
Here is a start
const content = document.getElementById("content");
document.getElementById("nav").addEventListener("click", function(e) {
const tgt = e.target;
const id = tgt.dataset.id;
[...content.querySelectorAll("div")].forEach(div => {
if (div.id !== id) div.classList.add("hide");
})
document.getElementById(id).classList.remove("hide");
})
content.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("close")) {
tgt.closest("div").classList.add("hide")
}
})
.hide {
display: none;
}
<div id="nav">
<a data-id="link" href='#'>One</a>
<a data-id="video" href='#'>Two</a>
<a data-id="images" href='#'>Three</a>
</div>
<div id="content">
<div id="link" class="hide">
<button type="button" id="save1">Save 1</button>
<button type="button" class="close">Close 1</button>
</div>
<div id="video" class="hide">
<button type="button" id="save2">Save 2</button>
<button type="button" class="close">Close 2</button>
</div>
<div id="images" class="hide">
<form>
<input id="upload" value="Upload 3" />
<button type="button" class="close">Close 3</button>
</form>
</div>
</div>
You can sum up some of your redundant code into one function and pass parameters to it.
function openAndClose(classBlock, classNone, classNone1) {
document.getElementsByClassName(classBlock)[0].style.display = 'block';
document.getElementsByClassName(classNone)[0].style.display = 'none';
document.getElementsByClassName(classNone1)[0].style.display = 'none'
}
function closeForm(){
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
<a onclick="openAndClose('open_link', 'open_images', 'open_video')" href='#'>One</a>
<a onclick="openAndClose('open_video', 'open_images', 'open_link')" href='#'>Two</a>
<a onclick="openAndClose('open_images', 'open_link', 'open_video')" href='#'>Three</a>
<div class="open_link" style="display: none;">
<button onclick="closeForm()">Save 1</button>
<button onclick="closeForm()">Close 1</button>
</div>
<div class="open_video" style="display: none;">
<button onclick="closeForm()">Save 2</button>
<button onclick="closeForm()" >Close 2</button>
</div>
<form class="open_images" style="display: none;">
<input onclick="closeForm()" value="Upload 3"/>
<button onclick="closeForm()" >Close 3</button>
</form>
Try this but with your own ids and classes
.open are the div to open
id of the target is id of your div, you did this with classes
document.querySelectorAll(".open").forEach(div => {
div.onclick = (e) => {
switch (e.target.id) {
case "open_link":
openLink()
break;
case "open_video":
openVideo()
break;
case "open_images":
openImages()
break;
}
}
})
I want to transverse upwards in javascript. like if i give input an element it will show all its parent elements till html tag but its not working like that. It only shows DIV,BODY,HTML.
function Transverse(p) {
var path = "";
var A = [];
var element = document.querySelector(document.getElementById(p).nodeName);
path = element.parentElement;
while (path) {
A.push(path);
path = path.parentElement;
}
console.log(A);
}
<div>
<button id="btn1" onclick="Transverse('btn1')">button 1</button>
<ul>
<button id="btn2" onclick="Transverse('btn2')">button 2</button>
<li>
<button id="btn3" onclick="Transverse('btn3')">button 3</button>
</li><br>
<section>
<a href="#">
<button id="btn4" onclick="Transverse('btn4')">button 4</button>
</a>
</section>
</ul>
<ol>
<li>
<h1>End of Page</h1>
<button id="btn5" onclick="Transverse('btn5')">Button 5</button>
</li>
</ol>
</div>
Thanks all it is working now ! I did the following Changes
function Transverse(p){
var A=[];
var element = document.getElementById(p);
var path=element.parentElement;
while(path){
A.push(path.nodeName);
path=path.parentElement;
}
console.log(A);
}
I have these menus around my horizontal scrolling site.
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section
The goal is to filter them based if the button classes have the same class as the ones in the section. If they have the same class (in this example 'fun-stuff') then that button will display:none.
My jQuery. I feel I'm close or totally over-complicating it.
jQuery(document).ready(function($) {
var theList = $('.nav-list button');
var i;
for (i=0; i < theList.length; i++){
var theButtons = '"' + theList[i].className + '"';
var parentClassName = theList[i].closest('section').className;
// tried this one. Was close i believe but no dice
if(theButtons = theList[i].closest('section').hasClass('"' + theButtons + '"') ){
// display that button as none
}
// tried this as well and for each button got 'no' in the console
if( $(theList[i].closest('section') ).hasClass(theButtons) ){
console.log('yes');
} else {
console.log ('no');
}
}
});
Yes you overdid it somewhat
$(function() {
$("button").each(function() {
var $parent = $(this).closest("section"), // the section wrapping the button
same = $parent.hasClass($(this).attr("class")); // parent has this button's class too
$(this).toggle(!same); // hide if the same (show if not)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
If you have more than one class on the button and you want to hide if one of them matches
$(function() {
$("button").each(function() {
var bList = this.classList,
parentList = $(this).closest("section")[0].classList, // the DOM element's classList
same = [...parentList] // convert to iterable
.filter(ele => bList.contains(ele)) // look up parent class in button classList
.length>0; // found?
$(this).toggle(!same);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff bla">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can turn the section classes into a regular array, then filter and hide the buttons.
jQuery(document).ready(function($) {
var classes = $('#slide-1').attr("class").split(/\s+/);
classes.forEach(function (cls) {
$('.nav-list button').filter('.' + cls).hide()
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can do this pretty easily with vanilla Javascript:
const classNames = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach((el) => {
if(classNames.contains(el.classList)){
el.style.display = "none";
}
});
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
Edit: Done with two lines of code:
const classList = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach(el => el.style.display = classList.contains(el.classList) ? "none": "initial");
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
Squares = Buttons with x = clicked, x = value
How do I create a textarea value onClick on a button that contains the value of each square AND empty values of anything that is not selected,
i.e.
<textarea>x,&bnsp;,&bnsp; ,&bnsp;\n,&bnsp;x,&bnsp; ,&bnsp;\n etc.</textarea>
Basically the text output needs to reflect the values of the squares in plain text, that’s why I need empty values to create that “visual”.
The rows and squares in each row are also subject to being dynamically generated when the page loads, based on a default or changed value.
Thank you!
It requires a bit of jQuery, but this does what you want.
var result = [];
var idnum;
for (var i = 1; i < 10; i++) {
result.push($("#" + i).html() + ",");
}
$(".result").html(result);
$(".button").click(function() {
idnum = $(this).attr("id");
$(this).html("x");
result[idnum - 1] = "x,";
$(".result").html(result);
});
.button {
width: 50px;
height: 50px;
vertical-align: top;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button" id="1"> </button>
<button class="button" id="2"> </button>
<button class="button" id="3"> </button>
<br>
<button class="button" id="4"> </button>
<button class="button" id="5"> </button>
<button class="button" id="6"> </button>
<br>
<button class="button" id="7"> </button>
<button class="button" id="8"> </button>
<button class="button" id="9"> </button>
<br><br>
<textarea class="result">Result</textarea>