JavaScript functions help needed - javascript

I'm practicing JavaScript and have come up with a little project ... get the diameters of various bodies in our solar system when I click on corresponding buttons.
I've been able to do this, but not very efficiently. Currently, the only way my code works is with 11 functions. I also have two objects (one for the body names and the other for the body diameters).
Any feedback to make my code more efficient is very welcome. Thank you! :-)
//JavaScript
var bodyName = {
su:"the Sun",
me:"Mercury",
ve:"Venus",
ea:"Earth",
mo:"the Moon",
ma:"Mars",
ju:"Jupiter",
sa:"Saturn",
ur:"Uranus",
ne:"Neptune",
pl:"Pluto"
};
var bodyDiam = {
su:864576,
me:3032,
ve:7521,
ea:7918,
mo:2159,
ma:4212,
ju:86881,
sa:72367,
ur:31518,
ne:30599,
pl:1475
};
function suInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.su;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.su;
}
function meInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.me;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.me;
}
function veInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ve;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ve;
}
function eaInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ea;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ea;
}
function moInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.mo;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.mo;
}
function maInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ma;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ma;
}
function juInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ju;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ju;
}
function saInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.sa;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.sa;
}
function urInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ur;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ur;
}
function neInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.ne;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.ne;
}
function plInfo() {
document.getElementById("bodyNameDisplay").innerHTML = bodyName.pl;
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam.pl;
}
<!--CSS-->
p {
font-family: arial, sans-serif;
font-size: 1em;
}
.button {
font-size: 1em;
font-weight: bold;
color: #fff;
border: none;
border-radius: 0;
padding: 0.5em;
margin: 0 0.25em 0.5em 0;
background-color: #393;
}
.result {
font-weight: bold;
color: #e80;
}
<!--html-->
<!--buttons-->
<button type="button" class="button" id="suButton" onclick="suInfo()">Sun</button>
<button type="button" class="button" id="meButton" onclick="meInfo()">Mercury</button>
<button type="button" class="button" id="veButton" onclick="veInfo()">Venus</button>
<button type="button" class="button" id="eaButton" onclick="eaInfo()">Earth</button>
<button type="button" class="button" id="moButton" onclick="moInfo()">Moon</button>
<button type="button" class="button" id="maButton" onclick="maInfo()">Mars</button>
<button type="button" class="button" id="juButton" onclick="juInfo()">Jupiter</button>
<button type="button" class="button" id="saButton" onclick="saInfo()">Saturn</button>
<button type="button" class="button" id="urButton" onclick="urInfo()">Uranus</button>
<button type="button" class="button" id="neButton" onclick="neInfo()">Neptune</button>
<button type="button" class="button" id="plButton" onclick="plInfo()">Pluto</button>
<!--Information Display-->
<p>The diameter of <span class="result" id="bodyNameDisplay">this body</span> is <span class="result" id="bodyDiamDisplay">this many</span> miles.</p>

Instead of using seperate functions for each button, you can pass an argument to the functions
function info(planet) {
document.getElementById("bodyNameDisplay").innerText = bodyName[planet];
document.getElementById("bodyDiamDisplay").innerText = bodyDiam[planet];
}
Then in the button, you can pass the argument onclick
<button type="button" class="button" id="plButton" onclick="info('pl')">Pluto</button>
If you also want to generate the buttons automatically, you can use javascript for that as well:
html:
<div id="buttons"></div>
js:
var buttonsContainer = document.body.getElementById("buttons");
for(var planetId in bodyName){ // Loop over every planet
var button = document.createElement("button"); // Creates <button></button>
button.setAttribute("onclick", "info('"+planetId+"')") // Add onclick=info('id');
button.innerText = bodyName[planetId] // Add the text inside <button>PlanetName</button>
button.classList.add("button"); // Add the class="button" class
button.setAttribute("id", planetId+"Button"); // Add the id="idButton"
button.setAttribute("type", "button"); // Add the type="button"
buttonsContainer.appendChild(button); // Add the button to the div of buttons
}
Example:
//JavaScript
var bodyName = {
su:"the Sun",
me:"Mercury",
ve:"Venus",
ea:"Earth",
mo:"the Moon",
ma:"Mars",
ju:"Jupiter",
sa:"Saturn",
ur:"Uranus",
ne:"Neptune",
pl:"Pluto"
};
var bodyDiam = {
su:864576,
me:3032,
ve:7521,
ea:7918,
mo:2159,
ma:4212,
ju:86881,
sa:72367,
ur:31518,
ne:30599,
pl:1475
};
function info(planet) {
document.getElementById("bodyNameDisplay").innerText = bodyName[planet];
document.getElementById("bodyDiamDisplay").innerText = bodyDiam[planet];
}
var buttonsContainer = document.getElementById("buttons");
for(var planetId in bodyName){ // Loop over every planet
var button = document.createElement("button"); // Creates <button></button>
button.setAttribute("onclick", "info('"+planetId+"')") // Add onclick=info(id);
button.innerText = bodyName[planetId] // Add the text inside <button>PlanetName</button>
button.classList.add("button"); // Add the class="button" class
button.setAttribute("id", planetId+"Button"); // Add the id="idButton"
button.setAttribute("type", "button"); // Add the type="button"
buttonsContainer.appendChild(button); // Add the button to the div of buttions
}
p {
font-family: arial, sans-serif;
font-size: 1em;
}
.button {
font-size: 1em;
font-weight: bold;
color: #fff;
border: none;
border-radius: 0;
padding: 0.5em;
margin: 0 0.25em 0.5em 0;
background-color: #393;
}
.result {
font-weight: bold;
color: #e80;
}
<!--html-->
<!--buttons-->
<div id="buttons"></div>
<!--Information Display-->
<p>The diameter of <span class="result" id="bodyNameDisplay">this body</span> is <span class="result" id="bodyDiamDisplay">this many</span> miles.</p>

You can pass the planet identifier as an argument to the info() function:
function info(id) {
document.getElementById("bodyNameDisplay").innerHTML = bodyName[id];
document.getElementById("bodyDiamDisplay").innerHTML = bodyDiam[id];
}
This way one function is enough.
The HTML:
<button type="button" class="button" id="suButton" onclick="info('su')">Sun</button>

Convert the two sets of details into one array of objects that contain the details for that body.This way you can access all the information in a single function and simply pass a variable to the function that will access the index of the object within the array and return the name and diameter from a single object.
//JavaScript
var bodies = [
{name:"the Sun", "diameter": 864576},
{name:"Mercury", diameter: 3032},
{name:"Venus", diameter: 7521},
{name:"Earth", diameter: 7918},
{name:"the Moon", diameter: 2159},
{name:"Mars", diameter: 4212},
{name:"Jupiter", diameter: 86881},
{name:"Saturn", diameter: 72367},
{name:"Uranus", diameter: 31518},
{name:"Neptune", diameter: 30599},
{name:"Pluto", diameter: 1475},
];
function setInfo(index) {
document.getElementById("bodyNameDisplay").innerHTML = bodies[index].name;
document.getElementById("bodyDiamDisplay").innerHTML = bodies[index].diameter;
}
<!--CSS-->
p {
font-family: arial, sans-serif;
font-size: 1em;
}
.button {
font-size: 1em;
font-weight: bold;
color: #fff;
border: none;
border-radius: 0;
padding: 0.5em;
margin: 0 0.25em 0.5em 0;
background-color: #393;
cursor: pointer;
}
.result {
font-weight: bold;
color: #e80;
}
<!--html-->
<!--buttons-->
<button type="button" class="button" onclick="setInfo(0)">Sun</button>
<button type="button" class="button" onclick="setInfo(1)">Mercury</button>
<button type="button" class="button" onclick="setInfo(2)">Venus</button>
<button type="button" class="button" onclick="setInfo(3)">Earth</button>
<button type="button" class="button" onclick="setInfo(4)">Moon</button>
<button type="button" class="button" onclick="setInfo(5)">Mars</button>
<button type="button" class="button" onclick="setInfo(6)">Jupiter</button>
<button type="button" class="button" onclick="setInfo(7)">Saturn</button>
<button type="button" class="button" onclick="setInfo(8)">Uranus</button>
<button type="button" class="button" onclick="setInfo(9)">Neptune</button>
<button type="button" class="button" onclick="setInfo(10)">Pluto</button>
<!--Information Display-->
<p>The diameter of <span class="result" id="bodyNameDisplay">this body</span> is <span class="result" id="bodyDiamDisplay">this many</span> miles.</p>

Related

How to match user input with array data in JavaScript

I'm new in learning HTML, JavaScript and CSS. I'm stuck at this JavaScript code.
I'm trying to match user input on the searchbar with some city array list I already prepared, when the search result match the script will change the display style of element into showing the result of their search value, but until now the result always showing false value.
Is there any better way to do this? Is there something wrong with my code?
function searchRespond() {
if (document.getElementById("myInput").value.match(cities))
{
document.getElementById("areaCovered").style.display = "block";
}
else {
document.getElementById("areaNotCovered").style.display = "block";
document.getElementById("searchResult").innerHTML = document.getElementById("myInput").value;
}
}
var cities = ["Banda Aceh", "Bandar Lampung", "Banyuwangi", "Bandung", "Bali", "Batam", "Batu", "Bekasi", "Bengkulu", "Binjai", "Blitar", "Bogor", "Bukittinggi", "Cimahi", "Cirebon", "Denpasar", "Depok", "Dumai", "Gunungsitoli", "Jakarta", "Jambi", "Kediri", "Langsa", "Lhokseumawe", "Lombok", "Lubuklinggau", "Madiun", "Magelang", "Malang", "Medan", "Metro", "Mojokerto", "Padang", "Padang Sidempuan", "Padangpanjang", "Pagar Alam", "Palembang", "Pangkal Pinang", "Pariaman", "Pasuruan", "Payakumbuh", "Pekalongan", "Pekanbaru", "Pematangsiantar", "Prabumulih", "Prigi", "Probolinggo", "Sabang", "Salatiga", "Sawahlunto", "Semarang", "Serang", "Sibolga", "Solo", "Subussalam", "Sukabumi", "Sumbawa", "Sungaipenuh", "Surabaya", "Surakarta", "Tangerang", "Tangerang Selatan", "Tanjungbalai", "Tanjungpinang", "Tasikmalaya", "Tebing Tinggi", "Tegal", "Yogyakarta"];
.HeadlineSearchContainer {
position: relative;
top: 100px;
margin: auto;
height: 159px;
}
.SearchCharacterStyle {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
.searchrespond {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
#areaCovered {
display: none;
}
#areaNotCovered {
display: none;
}
#fillArea {
display: none;
}
<div class="HeadlineSearchContainer">
<div class="SearchCharacterStyle">
<h>SEARCH FOR AREA COVERANGE</h>
</div>
<div id="mySearch" class="searchbox_box">
<form autocomplete="off" name="myForm">
<div class="autocomplete" style="width:300px;">
<input id="myInput" type="text" name="city" placeholder="Enter Your Destination City">
<i class="searchbutton"></i>
</div>
<input type="button" formtarget="_new" onclick="searchRespond()" name="input" value="Search">
<div class="searchrespond" id="searchRespond">
<h id="areaCovered">YES! We cover your area destination</h>
<h id="areaNotCovered">We don't cover your area destination yet
<p id="searchResult"></p>
</h>
<h id="fillArea">Please fill your area destination first</h>
</div>
</form>
</div>
</div>
To do what you require you can use filter() to match the user's input to values in your array. You would be best to perform a case-insensitive match, which can be done by converting both values to the same case.
Note that this logic sets the notifications as hidden before the logic runs, so that the previous state of the search is removed.
In addition, I made a couple of improvements to the code. Firstly I stored the relevant elements in variables instead of accessing the DOM every time. This is slightly more performant, and makes the code a lot easier to read. I also used addEventListener() to bind events instead of inline event handlers in the HTML, which are bad practice and shouldn't be used. Lastly I converted the <h> elements to <h2 /> in this demo, as there is no <h> element in HTML.
const input = document.querySelector('#myInput');
const areaCovered = document.querySelector('#areaCovered');
const areaNotCovered = document.querySelector('#areaNotCovered');
const searchResult = document.querySelector('#searchResult');
const fillArea = document.querySelector('#fillArea');
const cities = ["Banda Aceh", "Bandar Lampung", "Banyuwangi", "Bandung", "Bali", "Batam", "Batu", "Bekasi", "Bengkulu", "Binjai", "Blitar", "Bogor", "Bukittinggi", "Cimahi", "Cirebon", "Denpasar", "Depok", "Dumai", "Gunungsitoli", "Jakarta", "Jambi", "Kediri", "Langsa", "Lhokseumawe", "Lombok", "Lubuklinggau", "Madiun", "Magelang", "Malang", "Medan", "Metro", "Mojokerto", "Padang", "Padang Sidempuan", "Padangpanjang", "Pagar Alam", "Palembang", "Pangkal Pinang", "Pariaman", "Pasuruan", "Payakumbuh", "Pekalongan", "Pekanbaru", "Pematangsiantar", "Prabumulih", "Prigi", "Probolinggo", "Sabang", "Salatiga", "Sawahlunto", "Semarang", "Serang", "Sibolga", "Solo", "Subussalam", "Sukabumi", "Sumbawa", "Sungaipenuh", "Surabaya", "Surakarta", "Tangerang", "Tangerang Selatan", "Tanjungbalai", "Tanjungpinang", "Tasikmalaya", "Tebing Tinggi", "Tegal", "Yogyakarta"];
document.querySelector('#search-from').addEventListener('submit', e => {
e.preventDefault();
const searchTerm = input.value.trim().toLowerCase();
fillArea.style.display = 'none';
areaCovered.style.display = 'none';
areaNotCovered.style.display = 'none';
if (!searchTerm) {
fillArea.style.display = 'block';
return;
}
let matches = cities.filter(city => city.toLowerCase() == searchTerm);
if (matches.length) {
areaCovered.style.display = 'block';
} else {
areaNotCovered.style.display = 'block';
}
});
.HeadlineSearchContainer {
position: relative;
top: 100px;
margin: auto;
height: 159px;
}
.SearchCharacterStyle {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
.searchrespond {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
#areaCovered {
display: none;
}
#areaNotCovered {
display: none;
}
#fillArea {
display: none;
}
.autocomplete {
width: 300px;
}
<div class="HeadlineSearchContainer">
<div class="SearchCharacterStyle">
<h>SEARCH FOR AREA COVERANGE</h>
</div>
<div id="mySearch" class="searchbox_box">
<form autocomplete="off" name="myForm" id="search-from">
<div class="autocomplete">
<input id="myInput" type="text" name="city" placeholder="Enter Your Destination City">
<i class="searchbutton"></i>
</div>
<button type="submit">Search</button>
<div class="searchrespond" id="searchRespond">
<h2 id="areaCovered">YES! We cover your area destination</h2>
<h2 id="areaNotCovered">We don't cover your area destination yet</h2>
<h2 id="fillArea">Please fill your area destination first</h2>
</div>
</form>
</div>
</div>
You can use javascript includes().
<script>
const fruits = ["Banana Aceh", "Orange", "Apple", "Mango"];
let str = "Banana Aceh"; //document.getElementById("myInput").value
if(fruits.some(v => str.includes(v))) {
console.log("Exists");
} else {
console.log("Did not Exists");
}
</script>
function searchRespond() {
let searchTerm = document.getElementById("myInput").value;
if (cities.find(city => city == searchTerm))
{
document.getElementById("areaCovered").style.display = "block";
}
else {
document.getElementById("areaNotCovered").style.display = "block";
document.getElementById("searchResult").innerHTML = document.getElementById("myInput").value;
}
}
var cities = ["Banda Aceh", "Bandar Lampung", "Banyuwangi", "Bandung", "Bali", "Batam", "Batu", "Bekasi", "Bengkulu", "Binjai", "Blitar", "Bogor", "Bukittinggi", "Cimahi", "Cirebon", "Denpasar", "Depok", "Dumai", "Gunungsitoli", "Jakarta", "Jambi", "Kediri", "Langsa", "Lhokseumawe", "Lombok", "Lubuklinggau", "Madiun", "Magelang", "Malang", "Medan", "Metro", "Mojokerto", "Padang", "Padang Sidempuan", "Padangpanjang", "Pagar Alam", "Palembang", "Pangkal Pinang", "Pariaman", "Pasuruan", "Payakumbuh", "Pekalongan", "Pekanbaru", "Pematangsiantar", "Prabumulih", "Prigi", "Probolinggo", "Sabang", "Salatiga", "Sawahlunto", "Semarang", "Serang", "Sibolga", "Solo", "Subussalam", "Sukabumi", "Sumbawa", "Sungaipenuh", "Surabaya", "Surakarta", "Tangerang", "Tangerang Selatan", "Tanjungbalai", "Tanjungpinang", "Tasikmalaya", "Tebing Tinggi", "Tegal", "Yogyakarta"];
.HeadlineSearchContainer {
position: relative;
top: 100px;
margin: auto;
height: 159px;
}
.SearchCharacterStyle {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
.searchrespond {
font-family: Roboto;
font-size: 12px;
line-height: 24.82px;
text-align: left;
}
#areaCovered {
display: none;
}
#areaNotCovered {
display: none;
}
#fillArea {
display: none;
}
<div class="HeadlineSearchContainer">
<div class="SearchCharacterStyle">
<h>SEARCH FOR AREA COVERANGE</h>
</div>
<div id="mySearch" class="searchbox_box">
<form autocomplete="off" name="myForm">
<div class="autocomplete" style="width:300px;">
<input id="myInput" type="text" name="city" placeholder="Enter Your Destination City">
<i class="searchbutton"></i>
</div>
<input type="button" formtarget="_new" onclick="searchRespond()" name="input" value="Search">
<div class="searchrespond" id="searchRespond">
<h id="areaCovered">YES! We cover your area destination</h>
<h id="areaNotCovered">We don't cover your area destination yet
<p id="searchResult"></p>
</h>
<h id="fillArea">Please fill your area destination first</h>
</div>
</form>
</div>
</div>
suggest to validate input by making first letter uppercase and rest lowercase to match the array values
with javascript indexOf function
function searchRespond() {
var input = document.getElementById("myInput").value;
var area2search = input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); /* make fist letter capital and rest lower case to match array */
if (cities.indexOf(area2search) > -1) {
document.getElementById("areaCovered").style.display = "block";
//In the array!
} else {
document.getElementById("areaNotCovered").style.display = "block";
document.getElementById("searchResult").innerHTML = document.getElementById("myInput").value;
}
}
var cities = ["Banda Aceh", "Bandar Lampung", "Banyuwangi", "Bandung", "Bali", "Batam", "Batu", "Bekasi", "Bengkulu", "Binjai", "Blitar", "Bogor", "Bukittinggi", "Cimahi", "Cirebon", "Denpasar", "Depok", "Dumai", "Gunungsitoli", "Jakarta", "Jambi", "Kediri", "Langsa", "Lhokseumawe", "Lombok", "Lubuklinggau", "Madiun", "Magelang", "Malang", "Medan", "Metro", "Mojokerto", "Padang", "Padang Sidempuan", "Padangpanjang", "Pagar Alam", "Palembang", "Pangkal Pinang", "Pariaman", "Pasuruan", "Payakumbuh", "Pekalongan", "Pekanbaru", "Pematangsiantar", "Prabumulih", "Prigi", "Probolinggo", "Sabang", "Salatiga", "Sawahlunto", "Semarang", "Serang", "Sibolga", "Solo", "Subussalam", "Sukabumi", "Sumbawa", "Sungaipenuh", "Surabaya", "Surakarta", "Tangerang", "Tangerang Selatan", "Tanjungbalai", "Tanjungpinang", "Tasikmalaya", "Tebing Tinggi", "Tegal", "Yogyakarta"];

How does one handle DOM events from various buttons by a single handler function

I'm not sure if it's possible, but I'd like to use one unique function to trigger 4 different buttons to count a value (+ and -). But there are four different span values, for example, if I trigger forest it will only add or remove from forest, if I do it for town it will only trigger for town, and so on.
// set inital value to zero
let count = 0;
// select value and buttons
const valueForest = document.querySelector("#valueForest");
const btns = document.querySelectorAll(".btn");
btns.forEach(function (btn) {
btn.addEventListener("click", function (e) {
const styles = e.currentTarget.classList;
if (styles.contains("decrease")) {
count--;
} else if (styles.contains("increase")) {
count++;
} else {
count = 0;
}
if (count > 0) {
valueForest.style.color = "green";
}
if (count < 0) {
valueForest.style.color = "red";
}
if (count === 0) {
valueForest.style.color = "#222";
}
valueForest.textContent = count;
});
});
<div class="scoreDiv">
<h3>Input below the quantity of each tile in the end of the game:</h3>
<div class="scoreItem">
<h4>Forest</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueForest">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Town</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueTown">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Production</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueProduction">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Factory</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueFactory">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
</div>
Since there is nothing to add to Mister Jojo's already perfectly answered event delegation based approach, I will focus on an approach that sees and treats repeatedly used DOM structures which feature a specific behavior as components
As for the OP's example there would be just a Score Item component which implements its specific behavior exactly once and independent from the semantics of the underlying HTML/CSS.
The amount of implemented/used JavaScript code is still small enough in comparison to what such a Score Item component actually is capable of.
Identifying component structures relies on data attributes which decouples this task from whatever provided HTML- and CSS- code/environment.
Each component encapsulates its state at initialization/creation time; thus it does not read the data from the DOM (it only does write to the latter), but it does read and write the data from/to its encapsulated state.
A component also can be configured via component specific data attributes for an initially displayed value as well as for distinct incrementing/decrementing values.
The color-schema for positive, negative or Zero values are described by component specific and data attribute based CSS rules; there is no reason for layout related scripting overhead ...
function incrementBoundItemScore() {
const { outputControl: ctrl, currentValue, incrementValue } = this;
ctrl.textContent = ctrl.dataset.currentValue = this.currentValue = (currentValue + incrementValue);
}
function decrementBoundItemScore() {
const { outputControl: ctrl, currentValue, decrementValue } = this;
ctrl.textContent = ctrl.dataset.currentValue = this.currentValue = (currentValue + decrementValue);
}
function initializeScoreItem(rootNode) {
const incrementControl = rootNode.querySelector('[data-increase]');
const decrementControl = rootNode.querySelector('[data-decrease]');
const outputControl = rootNode.querySelector('[data-output]');
const incrementValue = parseFloat(incrementControl.dataset.value, 10);
const decrementValue = parseFloat(decrementControl.dataset.value, 10);
const initialValue = parseFloat(outputControl.dataset.initialValue, 10);
const scoreItem = {
outputControl,
currentValue: initialValue,
incrementValue,
decrementValue,
}
outputControl.textContent = outputControl.dataset.currentValue = initialValue;
incrementControl
.addEventListener('click', incrementBoundItemScore.bind(scoreItem));
decrementControl
.addEventListener('click', decrementBoundItemScore.bind(scoreItem));
}
function initialize() {
document
.querySelectorAll('[data-score-item-component]')
.forEach(initializeScoreItem);
}
initialize();
body {
zoom: .8;
margin: 0;
}
ul, li {
list-style: none;
}
ul {
margin: 0;
}
fieldset {
padding: 0px 10px;
}
.score-group {
margin: 4px 0;
}
.score-item {
margin: 0 0 5px 0;
}
.score-item legend {
font-weight: bold;
}
.score-item strong {
position: relative;
top: -2px;
font-weight: normal;
font-size: small;
text-transform: uppercase
}
[data-output][data-current-value] {
display: inline-block;
width: 3em;
text-align: center;
font-weight: bold;
color: green;
}
[data-output][data-current-value="0"] {
color: #222;
}
[data-output][data-current-value^="-"] {
color: red;
}
<section class="score-board">
<!--
<h3>Input below the quantity of each tile in the end of the game:</h3>
//-->
<ul>
<li class="score-item">
<fieldset data-score-item-component>
<legend>Forest</legend>
<div class="score-group">
<button
type="button"
data-decrease
data-value='-1'
class="btn decrease"
>-</button>
<output
name="forest-score"
data-output
data-initial-value="9"
></output>
<button
type="button"
data-increase
data-value='1'
class="btn increase"
>+</button>
</div>
<strong>Soma</strong>
</fieldset>
</li>
<li class="score-item">
<fieldset data-score-item-component>
<legend>Town</legend>
<div class="score-group">
<button
type="button"
data-decrease
data-value='-2'
class="btn decrease"
>-</button>
<output
name="town-score"
data-output
data-initial-value="0"
></output>
<button
type="button"
data-increase
data-value='2'
class="btn increase"
>+</button>
</div>
<strong>Soma</strong>
</fieldset>
</li>
<li class="score-item">
<fieldset data-score-item-component>
<legend>Production</legend>
<div class="score-group">
<button
type="button"
data-decrease
data-value='-5'
class="btn decrease"
>-</button>
<output
name="production-score"
data-output
data-initial-value="-10"
></output>
<button
type="button"
data-increase
data-value='5'
class="btn increase"
>+</button>
</div>
<strong>Soma</strong>
</fieldset>
</li>
<li class="score-item">
<fieldset data-score-item-component>
<legend>Factory</legend>
<div class="score-group">
<button
type="button"
data-decrease
data-value='-2'
class="btn decrease"
>-</button>
<output
name="factory-score"
data-output
data-initial-value="-5"
></output>
<button
type="button"
data-increase
data-value='1'
class="btn increase"
>+</button>
</div>
<strong>Soma</strong>
</fieldset>
</li>
</ul>
</section>
yes, with event delegation
this way:
const scoreDiv = document.querySelector('div.scoreDiv') // the parent Div
scoreDiv.onclick = e => // get all clicks everywhere upon this parent Div
{
if (!e.target.matches('div.scoreItem > button.btn ')) return // ignore other clicks
let countEl = e.target.closest('div.scoreItem').querySelector('span.value')
, newVal = +countEl.textContent + (e.target.matches('.decrease') ? -1 : +1)
;
countEl.style.color = (newVal > 0) ? 'green' : (newVal < 0) ? 'red' : '#222'
countEl.textContent = newVal;
}
span.value {
display : inline-block;
width : 5em;
text-align : right;
padding-right : .5em;
font-weight : bold;
}
<div class="scoreDiv">
<h3>Input below the quantity of each tile in the end of the game:</h3>
<div class="scoreItem">
<h4>Forest</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueForest">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Town</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueTown">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Production</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueProduction">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Factory</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueFactory">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
</div>
Explanations about
if (!e.target.matches('div.scoreItem > button.btn')) return
First of all the event handler scoreDiv.onclick = e => concern everything inside
<div class="scoreDiv">
// everything inside
</div>
So this get any click event in this space is processed by this arrow function.
It could be a click:
on the H3 element
, or one of the span elements
, or any the H4 elements
, everything !
, even the spaces between any elements.
the event [e] have diffrents properties
e.currentTarget --> is a reference to the caller element (here it is scoreDiv [div.scoreItem])
e.target --> is a reference to the element where the click happen
for this job we need to do only increment / decrement operations.
that's mean we have to ignore any click event witch is not on the plus or minus buttons.
This 8 buttons are : <button class="btn decrease">-</button> or <button class="btn increase">-</button>
All this buttons correspond to CSS = div.scoreItem > button.btn
In javascript the code for testing that is
e.target.matches('div.scoreItem > button.btn')
will return a boolean value (true or false)
There is now a strategy: Instead of making a big
if ( e.target.matches('div.scoreItem > button.btn') )
{
//...
// with many lines of code
//until the closing
}
// and then quit the function
and because this is a function we use a Logical NOT (!)
to make a direct return from function, coded like that:
if (!e.target.matches('div.scoreItem > button.btn')) return
The main interest is to quickly free the event manager in case of another element (present in scoreDiv) have is own click eventHandler.
I looked up how to change the color directly via css and luckily Peter Seliger showed that.
I also added in css an output::before {content: attr(data-value)} allowing to directly attribute this value on the display, without JS code
This further simplifies the javascript code.
(I also took the liberty of changing the interface a little to lighten it up completely, which is of no interest for this demonstration)
const scoreBoard = document.querySelector('#score-board')
scoreBoard.onclick = e =>
{
if (!e.target.matches('#score-board button')) return
let countEl = e.target.closest('fieldset')
.querySelector('output[data-value]')
countEl.dataset.value = +countEl.dataset.value
+ (+e.target.dataset.increase)
}
body, textarea, input {
font-family : Helvetica, Arial sans-serif;
font-size : 12px;
}
#score-board fieldset {
width : 20em;
margin : .5em 1em;
}
#score-board legend {
font-size : 1.4em;
padding : 0 .7em;
}
#score-board output {
display : inline-block;
font-size : 1.4em;
width : 5em;
text-align : right;
padding-right : .5em;
color : green;
font-weight : bold;
border-bottom : 1px solid grey;
margin : 0 .8em 0 .2em;
}
#score-board output::before {
content : attr(data-value)
}
#score-board output[data-value="0"] {
color: #222;
}
#score-board output[data-value^="-"] {
color: red;
}
<section id="score-board">
<fieldset>
<legend>Forest</legend>
<output data-value="-10"></output>
<button data-increase="+1">𑁕</button>
<button data-increase="-1">𑁒</button>
</fieldset>
<fieldset>
<legend>Town</legend>
<output data-value="0"></output>
<button data-increase="+1">𑁕</button>
<button data-increase="-1">𑁒</button>
</fieldset>
<fieldset>
<legend>Production</legend>
<output data-value="-7"></output>
<button data-increase="+1">𑁕</button>
<button data-increase="-1">𑁒</button>
</fieldset>
<fieldset>
<legend>Factory</legend>
<output data-value="5"></output>
<button data-increase="+1">𑁕</button>
<button data-increase="-1">𑁒</button>
</fieldset>
</section>
// set inital value to zero
//let count = 0;
// select value and buttons
const btns = document.querySelectorAll(".btn");
btns.forEach(function (btn) {
btn.addEventListener("click", function (e) {
const styles = e.currentTarget.classList;
const SectionValue = e.currentTarget.parentNode.querySelector('span');
var count = Number( SectionValue.innerHTML );
if (styles.contains("decrease")) {
count--;
} else {
count++;
}
if (count > 0) {
SectionValue.style.color = "green";
} else if (count < 0) {
SectionValue.style.color = "red";
} else {
SectionValue.style.color = "#222";
}
SectionValue.innerHTML = count;
});
});
<div class="scoreDiv">
<h3>Input below the quantity of each tile in the end of the game:</h3>
<div class="scoreItem">
<h4>Forest</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueForest">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Town</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueTown">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Production</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueProduction">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
<div class="scoreItem">
<h4>Factory</h4>
<button class="btn decrease">-</button>
<span class="value" id="valueFactory">0</span>
<button class="btn increase">+</button>
<h4>SOMA</h4>
</div>
</div>

How to make a calculator using JavaScript events?

I'm trying to make a calculator in javascript, but I'm having trouble understanding how to create variables that will store targeted DOM elements, input/outputs and how to add event listeners to retrieve data from all buttons when they are clicked.
(This I Can Change if so needs be)
I want to use function(event)to display the value of the button
(number or operation) on the screen. I also want to use event.target.dataset.num
to return the value and it should be stored as a new variable added to screen
value.
My code so far is:
//3.
//Changing colors of opertion colors
//Multiply Color
const colorMultiply = document.getElementById('multiply')
colorMultiply.style.backgroundColor = "green"
//Divide Color
const colorDivide = document.getElementById('divide')
colorDivide.style.backgroundColor = "red"
//subtract color
const colorSubtract = document.getElementById('subtract')
colorSubtract.style.backgroundColor="blue"
//add color
const colorAdd = document.getElementById('add')
colorAdd.style.backgroundColor="yellow"
//change font of numbers to blue (I did it like this incase anyone wants to color of a single number)
//Makes it easier
const number1 = document.getElementById('number1')
number1.style.color="blue"
const number2 = document.getElementById('number2')
number2.style.color="blue"
const number3 = document.getElementById('number3')
number3.style.color="blue"
const number4 = document.getElementById('number4')
number4.style.color="blue"
const number5 = document.getElementById('number5')
number5.style.color="blue"
const number6 = document.getElementById('number6')
number6.style.color="blue"
const number7 = document.getElementById('number7')
number7.style.color="blue"
const number8 = document.getElementById('number8')
number8.style.color="blue"
const number9 = document.getElementById('number9')
number9.style.color="blue"
const number0 = document.getElementById('number0')
number0.style.color="blue"
const decimal = document.getElementById('decimal')
decimal.style.color="blue"
//Changing color of the clear button
const clear = document.getElementById('clear')
clear.style.color="white"
clear.style.backgroundColor="black"
// Then we want to insert `memoryStoreButton` before the `clear` button:
var memoryStoreButton = document.createElement("BUTTON");
memoryStoreButton.innerHTML = "MS";
clear.before(memoryStoreButton); //puts button before clear
// Then we want the `memoryClearButton` before `memoryStoreButton`
var memoryClearButton = document.createElement("BUTTON");
memoryClearButton.innerHTML = "MC";
memoryStoreButton.before(memoryClearButton);//puts button before clear
// and finally, the `memoryRestoreButton` before `memoryClearButton`
var memoryRestoreButton = document.createElement("BUTTON");
memoryRestoreButton.innerHTML = "MR";
memoryClearButton.before(memoryRestoreButton);//puts button before clear
const buttonClick = document.querySelector(".btn8 btn-grey");
/*
buttonClick.addEventListener('click', function(event){
})
*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.calculator8 {
flex: 0 0 40%;
}
.screen8 {
width: 100%;
font-size: 7rem;
padding: 0.5rem;
background: rgb(41,41,56);
color: white;
border:none;
}
.buttons8 {
display: flex;
flex-wrap: wrap;
transition: all 0.5s linear;
}
button {
flex:0 0 25%;
border: 1px solid black;
padding: 0.25rem 0;
transition: all 2s ease;
}
.btn-grey {
background: rgb(224,224,224);
}
.btn8 {
font-size: 4rem;
}
<section class="calculator8">
<h1> Calculator 8 </h1>
<form>
<input type="text" name="" id="numberBox" class="screen8">
</form>
<div class="buttons8">
<!-- operation buttons -->
<button id="multiply" type="button" class="btn8 btn-mul" data-num="*">*</button>
<button id="divide" type="button" class="btn8 btn-div" data-num="/">/</button>
<button id="subtract" type="button" class="btn8 btn-sub" data-num="-">-</button>
<button id="add" type="button" class="btn8 btn-add" data-num="+">+</button>
<!-- number buttons -->
<button id="decimal" type="button" class="btn8 btn-grey" data-num=".">.</button>
<button id="number9" type="button" class="btn8 btn-grey" data-num="9">9</button>
<button id="number8" type="button" class="btn8 btn-grey" data-num="8">8</button>
<button id="number7" type="button" class="btn8 btn-grey" data-num="7">7</button>
<button id="number6" type="button" class="btn8 btn-grey" data-num="6">6</button>
<button id="number5" type="button" class="btn8 btn-grey" data-num="5">5</button>
<button id="number4" type="button" class="btn8 btn-grey" data-num="4">4</button>
<button id="number3" type="button" class="btn8 btn-grey" data-num="3">3</button>
<button id="number2" type="button" class="btn8 btn-grey" data-num="2">2</button>
<button id="number1" type="button" class="btn8 btn-grey" data-num="1">1</button>
<button id="number0" type="button" class="btn8 btn-grey" data-num="0">0</button>
<button id="equals" type="button" class="btn8 btn-grey">=</button>
<button id="clear" type="button" class="btn8 btn-grey">C</button>
</div>
</section>
Well, I have remade your calculator in a simple but yet clear way, so you can now deal with each button press with one event handler that gives you the button that was pressed. now you have a good start point, happy coding :)
document.querySelector(".buttons8").onclick = function(e) {
if(e.target.nodeName === "BUTTON") {
console.log(`${e.target.textContent} is pressed`);
//do something
}
}
* {
box-sizing: border-box;
}
.calculator8 {
width: 300px;
}
.buttons8 {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.buttons8 button {
width: 75px;
height: 60px;
font-size: 150%;
}
.screen8 {
width: 100%;
height: 80px;
background-color: #333;
}
.b_blue {
background-color: blue;
}
.b_red {
background-color: red;
}
.b_yellow {
background-color: yellow;
}
.b_green {
background-color: green;
}
.b_lgray {
background-color: #ddd;
}
.b_vlgray {
background-color: #eee;
}
.b_black {
background-color: black;
}
.t_white {
color: white;
}
<section class="calculator8">
<h1>Calculator 8</h1>
<input type="text" class="screen8" disabled>
<div class="buttons8">
<!-- operation buttons -->
<button class="b_green">*</button>
<button class="b_red">/</button>
<button class="b_blue">-</button>
<button class="b_yellow">+</button>
<!-- number buttons -->
<button class="b_lgray">.</button>
<button class="b_lgray">9</button>
<button class="b_lgray">8</button>
<button class="b_lgray">7</button>
<button class="b_lgray">6</button>
<button class="b_lgray">5</button>
<button class="b_lgray">4</button>
<button class="b_lgray">3</button>
<button class="b_lgray">2</button>
<button class="b_lgray">1</button>
<button class="b_lgray">0</button>
<button class="b_lgray">=</button>
<!-- other buttons -->
<button class="b_vlgray">MR</button>
<button class="b_vlgray">MC</button>
<button class="b_vlgray">MS</button>
<button class="b_black t_white">C</button>
</div>
</section>

How to make buttons change colors using only JavaScript?

I'm trying to make it when my mouse hovers over my buttons, it will change the color to black, and then when the mouse is off the button, it will change back to the same colors as before. I want my color change to be done in javascript instead of CSS, just because I'm trying to get an understanding of events and event handlers.
JS:
//Changing colors of operation colors
//Multiply Color
const colorMultiply = document.getElementById('multiply')
colorMultiply.style.backgroundColor = "green" //Makes Color Green
//Divide Color
const colorDivide = document.getElementById('divide')
colorDivide.style.backgroundColor = "red"//Makes Color Red
//subtract color
const colorSubtract = document.getElementById('subtract')
colorSubtract.style.backgroundColor="blue"//Makes Color Blue
//add color
const colorAdd = document.getElementById('add')
colorAdd.style.backgroundColor="yellow"//Makes Color Yellow
//change font of numbers to blue (I did it like this incase anyone wants to color of a single number)
//Makes it easier for you to change a colour of one button
const number1 = document.getElementById('number1')
number1.style.color="blue"
const number2 = document.getElementById('number2')
number2.style.color="blue"
const number3 = document.getElementById('number3')
number3.style.color="blue"
const number4 = document.getElementById('number4')
number4.style.color="blue"
const number5 = document.getElementById('number5')
number5.style.color="blue"
const number6 = document.getElementById('number6')
number6.style.color="blue"
const number7 = document.getElementById('number7')
number7.style.color="blue"
const number8 = document.getElementById('number8')
number8.style.color="blue"
const number9 = document.getElementById('number9')
number9.style.color="blue"
const number0 = document.getElementById('number0')
number0.style.color="blue"
const decimal = document.getElementById('decimal')
decimal.style.color="blue"
//Changing color of the clear button
const clear = document.getElementById('clear')
clear.style.color="white"
clear.style.backgroundColor="black"
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Then we want to insert `memoryStoreButton` before the `clear` button:
var memoryStoreButton = document.createElement("BUTTON");
memoryStoreButton.innerHTML = "MS";
clear.before(memoryStoreButton); //puts button before clear
// Then we want the `memoryClearButton` before `memoryStoreButton`
var memoryClearButton = document.createElement("BUTTON");
memoryClearButton.innerHTML = "MC";
memoryStoreButton.before(memoryClearButton);//puts button before clear
// and finally, the `memoryRestoreButton` before `memoryClearButton`
var memoryRestoreButton = document.createElement("BUTTON");
memoryRestoreButton.innerHTML = "MR";
memoryClearButton.before(memoryRestoreButton);//puts button before clear
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//What number buttons are pressed
var numButton = document.querySelectorAll(".btn8");
var showNum = document.querySelector(".screen8");
numButton.forEach(function(button){
button.addEventListener('click', function(event){
if(event.target.innerHTML == "C"){
return showNum.value = "";
} else if (event.target.innerHTML == "=") {
return;
}
let view = event.target.dataset.num;
showNum.value += view;
});
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//When equal is pressed it calculates the numbers, and if no numbers were entered there will be a error mesage
var equalButton = document.querySelector("#equals")
equalButton.addEventListener('click', function(event){
if(showNum.value == ""){
return alert("Please Enter a Value"); // If no numbers are being displayed, error alert.
}
showNum.value = showNum.value + "=" + eval(showNum.value);
});
//Align test to the right of screen
document.getElementById("numberBox").style.textAlign = "right";
////////////////////////////////////////////////////////////////////////////////////////////////////////////
document.getElementsByTagName("BUTTON").addEventListener("mouseover", mouseOver);
document.getElementsByTagName("BUTTON").addEventListener("mouseout", mouseOut);
function mouseOver() {
document.getElementsByTagName("BUTTON").style.color = "black";
}
function mouseOut() {
document.getElementsByTagName("BUTTON").style.color = "grey";
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> Calculator 8 </title>
<script src="fp.js" defer></script>
<link rel="stylesheet" href="fp.css">
</head>
<body>
<section class="calculator8">
<h1> Calculator 8 </h1>
<form>
<input type="text" name="calcScreeng" id="numberBox" class="screen8">
</form>
<div class="buttons8">
<!-- operation buttons -->
<button id="multiply" type="button" class="btn8 btn-mul" data-num="*">*</button>
<button id="divide" type="button" class="btn8 btn-div" data-num="/">/</button>
<button id="subtract" type="button" class="btn8 btn-sub" data-num="-">-</button>
<button id="add" type="button" class="btn8 btn-add" data-num="+">+</button>
<!-- number buttons -->
<button id="decimal" type="button" class="btn8 btn-grey" data-num=".">.</button>
<button id="number9" type="button" class="btn8 btn-grey" data-num="9">9</button>
<button id="number8" type="button" class="btn8 btn-grey" data-num="8">8</button>
<button id="number7" type="button" class="btn8 btn-grey" data-num="7">7</button>
<button id="number6" type="button" class="btn8 btn-grey" data-num="6">6</button>
<button id="number5" type="button" class="btn8 btn-grey" data-num="5">5</button>
<button id="number4" type="button" class="btn8 btn-grey" data-num="4">4</button>
<button id="number3" type="button" class="btn8 btn-grey" data-num="3">3</button>
<button id="number2" type="button" class="btn8 btn-grey" data-num="2">2</button>
<button id="number1" type="button" class="btn8 btn-grey" data-num="1">1</button>
<button id="number0" type="button" class="btn8 btn-grey" data-num="0">0</button>
<button id="equals" type="button" class="btn8 btn-grey">=</button>
<button id="clear" type="button" class="btn8 btn-grey">C</button>
</div>
</section>
</body>
</html>
CSS:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.calculator8{
flex: 0 0 40%;
}
.screen8{
width: 100%;
font-size: 5rem;
padding: 0.5rem;
background: rgb(41,41,56);
color: white;
border:none;
}
.buttons8{
display: flex;
flex-wrap: wrap;
transition: all 0.5s linear;
}
button{
flex:0 0 25%;
border: 1px solid black;
padding: 0.25rem 0;
transition: all 2s ease;
}
.btn-kground: rgb(224,224,224);
}
.btn8{
font-size: 4rem;
}
If you want to use JavaScript instead of CSS, you'll need to write event handlers for each button. One event handler will fire when a mouse is over the button ('mouseover'), the other event handler will fire when a mouse leaves the button ('mouseout').
This function will add event handlers to a single button:
function addButtonHandlers(btn) {
// make gray button on mouseover
btn.addEventListener('mouseover', () => {
btn.style.backgroundColor = 'gray';
btn.style.color = 'white';
});
// make white button on mouseout
btn.addEventListener('mouseout', () => {
btn.style.backgroundColor = 'white';
btn.style.color = 'black';
});
}
A working example:
function addButtonHandlers(btn) {
// make gray button on mouseover
btn.addEventListener('mouseover', () => {
btn.style.backgroundColor = 'gray';
btn.style.color = 'white';
});
// make white buton on mouseout
btn.addEventListener('mouseout', () => {
btn.style.backgroundColor = 'white';
btn.style.color = 'black';
});
}
const testBtn = document.getElementById('testbtn');
addButtonHandlers(testBtn);
button {
margin: 1rem;
padding: 1rem;
border: none;
color: black;
background-color: white;
}
<button id='testbtn'>Test Button</button>
Documentation on mouse events and addEventListener().
Lets say the id of the button is calcButton, you would do this:
<html>
<body>
<button id = "calcButton"></button>
<style>
#calcButton {
color: red;
}
#calcButton:hover {
color: black;
}
</style>
</body>
</html>
Use that, but change the colours to what you want.

How to change class in button when you click on it

I have two buttons: without background and green, I need them to change when i click on them (from green to that one with dashed border-bottom)
Here is my html:
<div class="btns">
<button type="button" class="btn btn-success">ΠœΡƒΠΆ</button>
<button type="button" class="btn btn-link btn-simple">Π–Π΅Π½</button>
</div>
I've written script just like this :
$('.btn').click(function() {
var $this = $(this);
if ($this.hasClass('btn-success')) {
$this.removeClass().addClass('btn-simple');
} else if ($this.hasClass('btn-simple')) {
$this.removeClass('btn-simple').addClass('btn-success');
}
});
but it doesn't work.
and here is what I added to css file:
.btn-simple {
border-bottom: 1px dashed #000;
color: #000;
}
nothing else because these are bootstrap buttons.
you should add code in document.ready method.
$(document).ready(function () {
$('.btn').click(function () {
var $this = $(this);
if ($this.hasClass('btn-success')) {
$this.removeClass().addClass('btn-simple');
} else if ($this.hasClass('btn-simple')) {
$this.removeClass('btn-simple').addClass('btn-success');
}
});
});
You need to add the class you want to remove, for example: $this.removeClass('btn-success'). In the link below I've made an example.
$('.btn').click(function(){
var $this = $(this);
if (!$this.hasClass('btn-success')) {
$('.btn').removeClass('btn-success')
$this.addClass('btn-success');
}
})
https://codepen.io/jmejia1221/pen/qMwLQP
You were not removing one of the btn-success class. Also, I think you should add btn-link class. Also wrap this entire piece in document.ready
$(document).ready(function () {
$('.btn').click(function() {
var $this = $(this);
if ($this.hasClass('btn-success')) {
$this.removeClass('btn-success').addClass('btn-simple');
} else if ($this.hasClass('btn-simple')) {
$this.removeClass('btn-simple').addClass('btn-link').addClass('btn-success');
}
});
});
Assuming you want to toggle between buttons within a shared container..
/* longer version for demonstration purposes */
$('.btn').click(function() {
var thisParent = $(this).closest('.btns');
$(thisParent).find('.btn-success').addClass('btn-simple')
$(thisParent).find('.btn-success').removeClass('btn-success');
$(this).removeClass('btn-simple');
$(this).addClass('btn-success');
})
/* shorter version
$('.btn').click(function() {
$(this).closest('.btns').find('.btn-success').addClass('btn-simple').removeClass('btn-success');
$(this).removeClass('btn-simple').addClass('btn-success');
})
*/
* { outline: 0; } button { border-style: none; cursor: pointer; padding: 5px; } button::-moz-focus-inner { border: 0; }
/* ignore above */
.btn-simple {
border-bottom: 1px dashed #000;
color: #000;
}
.btn-success {
background-color: hsla(96, 92%, 37%, 1);
border-radius: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btns">
<button type="button" class="btn btn-success">ΠœΡƒΠΆ</button>
<button type="button" class="btn btn-link btn-simple">Π–Π΅Π½</button>
</div>
<div class="btns">
<button type="button" class="btn btn-success">ΠœΡƒΠΆ</button>
<button type="button" class="btn btn-link btn-simple">Π–Π΅Π½</button>
<button type="button" class="btn btn-link btn-simple">Ρ‚Ρ€ΠΈ</button>
</div>
fiddle
https://jsfiddle.net/Hastig/bjkchu5L/

Categories