How to change css property when you click on button? - javascript

I want when i click in each one of them to pop the span element with class color but only for that button.
[![enter image description here][1]][1]
I only achieved when i click on one of them to change the visibility to visible on all elements with class colors.
my Code : https://jsbin.com/govowakasa/edit?js
document.getElementById("btn-apple").addEventListener("click", function(e) {
showColor()
});
function showColor() {
const colors = document.getElementsByClassName("color");
for (let i=0; i<colors.length; i++) {
colors[i].style.visibility = 'visible';
}};

You can simply add this line
fruits[i].style.backgroundColor = 'red'

You can not use the same ID for more than 1 element.
I replaced the IDs of buttons with a new class name fruit-btn.
Then I made an array in JS of both buttons and color spans.
Then I looped through each button to add an EventListener.
In the event I added another loop that hides every color span and then makes the i span visible. There is no need for a function.
const fruit_btn = document.getElementsByClassName("fruit-btn");
const color_spans = document.getElementsByClassName("color");
for (let i = 0; i < fruit_btn.length; i++) {
fruit_btn[i].addEventListener("click", function(e) {
for (let i = 0; i < fruit_btn.length; i++) {
color_spans[i].style.visibility = "hidden";
}
color_spans[i].style.visibility = "visible";
});
}
body {
font-size: 2rem;
}
li {
margin: 20px;
list-style: none;
}
button i {
cursor: pointer;
font-size: 3rem;
}
.color {
margin: 10px;
border: 1px solid black;
background-color: blanchedalmond;
display: inline-block;
padding: 10px;
visibility: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fruits</title>
<link rel="stylesheet" href="list.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" integrity="sha512-0S+nbAYis87iX26mmj/+fWt1MmaKCv80H+Mbo+Ne7ES4I6rxswpfnC6PxmLiw33Ywj2ghbtTw0FkLbMWqh4F7Q==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
</head>
<body>
<p>
FRUITS
</p>
<ul>
<li class="items">
<button class="fruit-btn"><i class="fas fa-apple-alt"></i></button>
<span class="color">red and yellow</span>
</li>
<li class="items">
<button class="fruit-btn"><i class="fas fa-carrot"></i></button>
<span class="color">orange</span>
</li>
<li class="items">
<button class="fruit-btn"><i class="fas fa-lemon"></i></button>
<span class="color">yellow</span>
</li>
<li class="items">
<button class="fruit-btn"><i class="fas fa-pepper-hot"></i></button>
<span class="color">red and green</span>
</li>
</ul>
<script src="/week-4/index.js"></script>
</body>
</html>
I would suggest to add/remove a Class instead of adding/removing directly CSS styling.

Related

Javascript dropdown menu toggle button

I am trying to get my option list to hide until the dropdown menu button has been clicked and for it to hide again once it has been clicked however, it is not working. Here is my code. Please let me know what i can do to fix it
My html :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width initial-scale=1">
<title>Cocktail App</title>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;600&display=swap"
rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="css/recipe.css">
<script src="recipe.js"></script>
</head>
<body>
<h2>YOUR ONE STOP SHOP FOR AMAZING COCKTAIL RECIPES!</h2>
<div class="container">
<button onclick="myFunction()" class="dropbtn"> Cocktails!!</button>
<div id="myDropdown" class="search-container">
<input type="text" placeholder="Choose cocktail..." id="myInput" onkeyup="filterFunction()">
Margarita
<a href="#>Mojito</a>
Long Island tea
Whiskey Sour
</div>
</div>
<div id="result"></div>
</div>
</body>
</html>
My javascript :
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
function filterFunction() {
var input = document.getElementById("myInput");
var filter = input.value.toUpperCase();
var dropDown = document.getElementById("myDropdown");
var link = dropDown.getElementsByTagName("a");
for (i = 0; i < link.length; i++) {
textValue = link[i].textContent || link[i].innerText;
if (textValue.toUpperCase().indexOf(filter) > -1) {
link[i].style.display = "";
} else {
link[i].style.display = "none";
}
}
}
You'll need some CSS to define the class "show", for example add this inside your HTML <head>:
<style>
.hidden {
display: none !important;
}
</style>
Notice that I changed the class name to "hidden" instead of "show" for semantics.
This way, when an element has the class "hidden", it will not be displayed.
Now change your Javascript correspondingly, so it adds and removes the class "hidden":
document.getElementById("myDropdown").classList.toggle("hidden");
First try to add the missing quotation mark after # in:
<a href="#>Mojito</a> and see if it works then.
And remove the 'java' from tags since this is not java but javascript :)
I can't see your css but your .show class needs to defined. Add the following to your stylesheet:
#myDropdown {
display: none;
}
#myDropdown.show
{
display: block;
}
Working:
function myFunction() { document.getElementById("myDropdown").classList.toggle("show");
}
function filterFunction() {
var input = document.getElementById("myInput");
var filter = input.value.toUpperCase();
var dropDown = document.getElementById("myDropdown");
var link = dropDown.getElementsByTagName("a");
for (i = 0; i < link.length; i++) {
textValue = link[i].textContent || link[i].innerText;
if (textValue.toUpperCase().indexOf(filter) > -1) {
link[i].style.display = "";
} else {
link[i].style.display = "none";
}
}
}
#myDropdown {
display: none;
}
#myDropdown.show
{
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width initial-scale=1">
<title>Cocktail App</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;600&display=swap" rel="stylesheet" />
</head>
<body>
<h2>YOUR ONE STOP SHOP FOR AMAZING COCKTAIL RECIPES!</h2>
<div class="container">
<button onclick="myFunction()" class="dropbtn"> Cocktails!!</button>
<div id="myDropdown" class="search-container">
<input type="text" placeholder="Choose cocktail..." id="myInput" onkeyup="filterFunction()">
Margarita
Mojito
Long Island tea
Whiskey Sour
</div>
</div>
<div id="result"></div>
</body>
</html>

console is throwing undefined while me trying to Create an element for the Event listener to read

I am trying to create a todo list webapp and serves as my basic training ground for javascript but the console is throwing errors and I can figure out. it says todo is undefined but I defined it through the function as a div to be created. I just wanted that every input on the form will be added on to my unordered list . I just use a sample value, not the real input. I so confused rn. thanks for your help.
//selectors
const todoInput = document.querySelector(".todo-input");
const todoButton = document.querySelector("todo-button");
const todoList = document.querySelector("todo-list");
//event listener
todoButton.addEventListener('click', addTodo);
console.log(event);
//functions
function addTodo(event) {
//creating the Todo Div
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//creating the LI
const newTodo = document.createElement('li');
newTodo.innerText = "A new Task";
newTodo.classList.add('todo-item');
todoDiv.appendChild(newTodo);
//checkmark button
const completedButtton = document.createElement('button');
completedButtton.innerHTML = '<i class="fa fa-check></i>';
completedButtton.classList.add('complete-btn');
todoDiv.appendChild(completedButtton);
//trash button
const trashButtton = document.createElement('button');
trashButtton.innerHTML = '<i class="fa fa-trash></i>';
trashButtton.classList.add('trash-btn');
todoDiv.appendChild(trashButtton);
//add to main ul class todo-list
todoList.appendChild(todoDiv);
};
* {
margin: 0em;
padding: 0em;
box-sizing: border-box;
background-image: linear-gradient(120deg, #d4fc79 0%, #96e6a1 100%);
}
body {
text-align: center;
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
color: rgb(0, 0, 0);
}
header,
form {
min-height: 20vh;
display: flex;
justify-content: center;
align-items: center;
}
form input,
form button {
padding: 0.5rem;
font-size: 2rem;
border: none;
background: #fff;
}
form button {
color: #96e6a1;
background: white;
cursor: pointer;
transition: all 0.3s ease;
}
form button:hover {
color: #ffffff;
background-color: #96e6a1;
}
<title>Worklist</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/style.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/konpa/devicon#master/devicon.min.css">
<script src="https://use.fontawesome.com/3a734bc38d.js"></script>
<main>
<h1>My Todo-List</h1>
<p>Enjoy this handy website that you can use for free expecially for your todo list.</p>
<form>
<input type="text" class="todo-input" placeholder="Enter new task" />
<button class="todo-button" type="submit">
<i class="fa fa-plus" aria-hidden="true"></i>
</buton>
</form>
<div class="todo-container">
<ul class="todo-list"></ul>
</div>
</main>
Here is fully working to do list. There were alot of changes needed in your code.
You are not using preventDefault method which mean your page reload every time you add a new to do item
You were using the right class prefixes .
You also do not need to have seperate function to call on click. You can use the same eventlistener to add to do items.
Also, when to do items were getting added you are not displaying the check and trash icon properly.
Also, once the item is added successfully. its ideal to set the input to null to that another item can be added.
Demo:
//selectors
const todoButton = document.querySelector(".todo-button");
const todoList = document.querySelector(".todo-list");
//event listener
todoButton.addEventListener('click', (event) => {
event.preventDefault()
//
const todoInput = document.querySelector(".todo-input");
//creating the Todo Div
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//creating the LI
const newTodo = document.createElement('li');
newTodo.innerText = todoInput.value
newTodo.classList.add('todo-item');
todoDiv.appendChild(newTodo);
//checkmark button
const completedButtton = document.createElement('button');
completedButtton.innerHTML = '<i class="fa fa-check></i>';
completedButtton.classList.add('complete-btn');
completedButtton.innerHTML = '<i class="fa fa-check" aria-hidden="true"></i>';
todoDiv.appendChild(completedButtton);
//trash button
const trashButtton = document.createElement('button');
trashButtton.innerHTML = '<i class="fa fa-trash" aria-hidden="true"></i>';
trashButtton.classList.add('trash-btn');
todoDiv.appendChild(trashButtton);
//add to main ul class todo-list
todoList.appendChild(todoDiv);
//Clear div
todoInput.value = ''
})
<!DOCTYPE html>
<html lang="en">
<head>
<title>Worklist</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/konpa/devicon#master/devicon.min.css">
<script src="https://use.fontawesome.com/3a734bc38d.js"></script>
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> -->
</head>
<body>
<main>
<h1>My Todo-List</h1>
<p>Enjoy this handy website that you can use for free expecially for your todo list.</p>
<form>
<input type="text" class="todo-input" placeholder="Enter new task" />
<button class="todo-button" type="submit">
<i class="fa fa-plus" aria-hidden="true"></i>
</button>
</form>
<div class="todo-container">
<ul class="todo-list"></ul>
</div>
</main>
</body>

Toggle paragraph using link from another paragraph

I have similar code like this. Except for the fact that my JS file is external. The function myFunction() is called in the beginning of that file, like this:
document.addEventListener('DOMContentLoaded', function () {
myFunction()
})
But, it's not working - it's not showing the text from the second paragraph, when clicked on the word HERE from the first paragraph. I assume that maybe I should call the function somehow else. Any given ideas would be really helpful. Thanks.
P.S. Also, when clicked, the window should scroll to the newly opened paragraph.
function myFunction() {
var x = document.getElementById("myCollapsible2")
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
p{
background: #eee;
border: 1px solid #ccc;
margin: 20px 0;
padding: 30px;
}
.bs-example{
margin: 20px;
}
.link-color {
color: red;
}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js">.</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="bs-example">
<input type="button" class="btn btn-primary" data-toggle="collapse" data-target="#myCollapsible" value="Toggle Button">
<div id="myCollapsible" class="collapse"><p>This is a simple example of expanding and collapsing individual element via data attribute. <br>Click on the <b>Toggle Button</b> button to see the effect. If you click <a onclick="myFunction()" class="link-color" href="#">here</a>, you should see the other paragraph. </p></div>
<div id="myCollapsible2" class="collapse"><p>This is a simple example</p></div>
</div>
</body>
</html>
Since you are using bootstrap with popper, your function is unnecessary, just set the values according to the documentation. To scroll to the element, use the scrollIntoView method. I had to wrap it around a setTimeout, because the default method was executing afterwards, so when I called scroll the element wasn't visible yet.
function scrollTo2() {
var el = document.getElementById('myCollapsible2');
window.setTimeout(() => el.scrollIntoView(), 0);
}
p {
background: #eee;
border: 1px solid #ccc;
margin: 20px 0;
padding: 30px;
}
.bs-example {
margin: 20px;
}
.link-color {
color: red;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="bs-example">
<input type="button" class="btn btn-primary" data-toggle="collapse"
data-target="#myCollapsible" value="Toggle Button">
<div id="myCollapsible" class="collapse show">
<p>This is a simple example of expanding and collapsing individual element
via data attribute.<br>Click on the <b>Toggle Button</b>
button to see the effect.
If you click <a onclick="scrollTo2()" data-toggle="collapse"
data-target="#myCollapsible2" class="link-color" href="#">here</a>,
you should see the other paragraph. </p>
<div id="myCollapsible2" class="collapse">
<p>This is a simple example</p>
</div>
</div>
</div>

Why several clicks fire for each instance of a Class?

I have three tooltip buttons on a page. I can close any open tooltip by clicking anywhere outside buttons. And this is what I came across:
In the code below, when I click on any place on the page, the handler of this part of code is activated $(document).on('click', (event) => this.closeOnOutsideClick(event));
I can see in inspector, that function closeOnOutsideClick is fired three times - it makes three checks for each tooltip button present on the page. I cannot figure out what mechanism is responsible for that and why the check if (!$(event.target).closest(this.$elem)) is not performed only once? My code can be found here and also below: https://jsfiddle.net/bakrall/786cz40L/
This is a simplified version of a more complex code just to give example of my issue:
const selectors = {
tooltip: '.tooltip-container',
tooltipButton: '.tooltip-button',
tooltipMessage: '.tooltip-message'
}
class Tooltip {
constructor(tooltip) {
this.$elem = $(tooltip);
this.$tooltipButton = this.$elem.find(selectors.tooltipButton);
this.$tooltipMessage = this.$elem.find(selectors.tooltipMessage);
this.$tooltipMessageText = this.$tooltipButton.attr('data-tooltip-content');
this.bindUiEvents();
}
bindUiEvents() {
$(document).on('click', (event) => this.closeOnOutsideClick(event));
this.$tooltipButton.on('click', () => this.showTooltipMessage());
this.$tooltipButton.on('blur', () => this.hideTooltip());
}
showTooltipMessage() {
this.$tooltipMessage
.text(this.$tooltipMessageText)
.addClass('shown-message');
}
hideTooltip() {
this.$tooltipMessage
.text('')
.removeClass('shown-message');
}
closeOnOutsideClick(event) {
if (!$(event.target).closest(this.$elem)) {
this.hideTooltip();
}
}
}
//class in another file
const tooltip = $('.tooltip-container');
tooltip.each(function(index, item) {
new Tooltip(item);
})
.input-wrapper {
margin-bottom: 2em;
}
.tooltip-container {
position: relative;
display: inline-block;
}
.tooltip-message {
display: none;
position: absolute;
left: 100%;
top: 0;
width: 10em;
padding: 0.5rem;
background: #000;
color: #fff;
}
.tooltip-message.shown-message {
display: inline-block;
}
button {
width: 1.2em;
height: 1.2em;
border-radius: 50%;
border: 0;
background: #000;
font-family: serif;
font-weight: bold;
color: #fff;
}
button:focus {
outline: none;
box-shadow: 0 0 0 0.25rem skyBlue;
}
input {
display: block;
}
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title> </title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="tooltip.css">
</head>
<body>
<div class="input-wrapper">
<label for="name">
What's your name?
<span class="tooltip-container">
<button class="tooltip-button" type="button" aria-label="more info"
data-tooltip-content="This clarifies whatever needs clarifying">i</button>
<span class="tooltip-message" role="status"></span>
</span>
</label>
<input id="name" type="text"/>
</div>
<div class="input-wrapper">
<label for="age">
What's your age?
<span class="tooltip-container">
<button class="tooltip-button" type="button" aria-label="more info"
data-tooltip-content="This is to know how old you are">i</button>
<span class="tooltip-message" role="status"></span>
</span>
</label>
<input id="age" type="text"/>
</div>
<div class="input-wrapper">
<label for="nationality">
What's your nationality
<span class="tooltip-container">
<button class="tooltip-button" type="button" aria-label="more info"
data-tooltip-content="What country are you from?">i</button>
<span class="tooltip-message" role="status"></span>
</span>
</label>
<input id="nationality" type="text"/>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous">
</script>
<script src="tooltip.js" async defer></script>
</body>
</html>
tooltip.each(function(index, item) {
new Tooltip(item);
})
Since you instantiate 3 Tooltips, you bind a separate event listener to the document each time. Each listener is getting triggered with each click. However, each of those listeners has a different this which is what allows each listener to tell if its Tooltip was clicked and if not, hide it.
If you want a single listener you could store a list of all your Tooltips and have the event listener iterate through the list of Tooltips, closing all Tooltips that were not clicked.
Your click event is firing on mutliple elements, because you specified just (document). Maybe you can be more specific:
$(document).on('click', '.input-wrapper', (event) => this.closeOnOutsideClick(event));

Create popup box on click with value of hidden element

Hi i have looked every where for this but cant find a good way of doing it :/
I have a dynamically populated list on my website that looks like this:
<li>
name: blue<br/>
procesor: blue<br/>
<div class="right top">2001</div>
<input type="hidden" name="Description" value="short">
</li>
I have been looking for a way to have a small popup show with the contents of the hiddent text field in the list.
I have tried many free modal javascript code but they all seem to either stop working or destroy my template.
Dose anyone know how I could do this. I have no working javascript code as from now and am looking for the best way todo this. It doesn't need to be fancy. Just a white boc with the popup
The easiest way is to add title property to li:
<li title="Some short desc">
...
</li>
This should work on all desktop browsers, but not on mobiles.
Another way is to use excellent hint.css from http://kushagragour.in/lab/hint/
It does not rely on any JavaScript and rather uses data-* attribute, pseudo elements, content property and CSS3 transitions to create the tooltips. You can fine tune orientation, colours, and even animations.
Try this one
$(function() {
$(".list li input[type=hidden]").each(function(index, obj) {
$(".popup").append($(obj).val() + "<br/>");
});
$(".popup").show();
});
.popup {
position: relative;
top: 10px;
border: solid 2px #E5988A;
width: 200px;
text-align: left;
margin: 0px auto;
z-index: 2;
background-color: #FFF;
padding: 10px;
}
.disabled {
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
z-index: 1;
display: block;
background-color: #333;
opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="list">
<li>
name: blue
<br/>procesor: blue
<br/>
<div class="right top">2001</div>
<input type="hidden" name="Description" value="short" />
</li>
<li>
name: green
<br/>procesor: gree
<br/>
<div class="right top">2002</div>
<input type="hidden" name="Description" value="anothershort">
</li>
</ul>
<div class="popup"></div>
<div class="disabled"></div>
Html Code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="app1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"/>
</head>
<body>
<div>
Select <select id = "MyList"></select>
</div>
<input type="hidden" name="Description" value="short" id="hiddendiv">
</body>
</html>
Javascript
$(document).ready(function(){
var select = document.getElementById("MyList");
var options = ["1", "2", "3", "4", "5"];
for (var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
$('#MyList').hover(
function(){
var value=$('input').val();
alert(value);
}, function() {
}
)
});

Categories