JavaScript: toggle button group not working correctly - javascript

I tried to implement a toggleable button group into my popup window. It works kinda... but not fully. Heres the code, it is kinda complicated to explain so please enable all buttons in the snippet and then you will see. And yea, i know. The code is very unoptimised, just tried to make it work.
Thanks for any help! :)
document.getElementById("off1").addEventListener("click", function() {
if(document.getElementById("off1")) {
document.getElementById("off1").id = "on";
} else {
document.getElementById("on").id = "off1";
}
});
document.getElementById("off2").addEventListener("click", function() {
if(document.getElementById("off2")) {
document.getElementById("off2").id = "on";
} else {
document.getElementById("on").id = "off2";
}
});
document.getElementById("off3").addEventListener("click", function() {
if(document.getElementById("off3")) {
document.getElementById("off3").id = "on";
} else {
document.getElementById("on").id = "off3";
}
});
document.getElementById("off4").addEventListener("click", function() {
if(document.getElementById("off4")) {
document.getElementById("off4").id = "on";
} else {
document.getElementById("on").id = "off4";
}
});
document.getElementById("off5").addEventListener("click", function() {
if(document.getElementById("off5")) {
document.getElementById("off5").id = "on";
} else {
document.getElementById("on").id = "off5";
}
});
document.getElementById("off6").addEventListener("click", function() {
if(document.getElementById("off6")) {
document.getElementById("off6").id = "on";
} else {
document.getElementById("on").id = "off6";
}
});
document.getElementById("off7").addEventListener("click", function() {
if(document.getElementById("off7")) {
document.getElementById("off7").id = "on";
} else {
document.getElementById("on").id = "off7";
}
});
document.getElementById("off8").addEventListener("click", function() {
if(document.getElementById("off8")) {
document.getElementById("off8").id = "on";
} else {
document.getElementById("on").id = "off8";
}
});
input {
width: 95px;
float:left;
font-size: 12px;
border-radius: 2px;
margin: 5px;
padding: 3px;
}
#off1, #off2, #off3, #off4, #off5, #off6, #off7, #off8 {
background-color: #101820FF;
color: #fff;
border:1px solid white;
}
#on {
background-color: #FEE715FF;
color:#101820FF;
border: 1px solid #FEE715FF;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/popup.css">
</head>
<body>
<div class="item-toggle-group">
<input type="button" id="off1" value="jackets">
<input type="button" id="off2" value="shirts">
<input type="button" id="off3" value="tops/sweaters">
<input type="button" id="off4" value="sweatshirts">
<input type="button" id="off5" value="pants">
<input type="button" id="off6" value="hats">
<input type="button" id="off7" value="bags">
<input type="button" id="off8" value="accessories">
<script src="../js/toggleButton.js"></script>
</div>
</body>
</html>

Use a data attribute to identify if a button is on and classes to identify the buttons.
Html
<input type="button" class="button" value="jackets" data-on="0">
<input type="button" class="button" value="thing2" data-on="0">
<input type="button" class="button" value="thing3" data-on="0">
<input type="button" class="button" value="thing4" data-on="0">
<input type="button" class="button" value="thing5" data-on="0">
Javascript
document.getElementsByClassName("button").addEventListener("click", function() {
if(this.getAttribute("data-on") == "1") {
this.setAttribute("data-on", "0");
} else {
this.setAttribute("data-on", "1");
}
});
CSS
.button {
... css for buttons that are off
}
.button[data-on=1] {
... css for buttons that are on
}
Using classes makes it generic so you can just add buttons on the fly without adding an event listener for that specific button.

Instead of id you can use class so that you can use classList.toggle method to toggle on class on specific button click.
document.querySelectorAll('.toggle').forEach(function(button) {
button.addEventListener('click', function() {
this.classList.toggle('on');
})
})
input {
width: 95px;
float: left;
font-size: 12px;
border-radius: 2px;
margin: 5px;
padding: 3px;
}
.toggle {
background-color: #101820FF;
color: #fff;
border: 1px solid white;
}
.on {
background-color: #FEE715FF;
color: #101820FF;
border: 1px solid #FEE715FF;
}
<div class="item-toggle-group">
<input type="button" id="off1" class="toggle" value="jackets">
<input type="button" id="off2" class="toggle" value="shirts">
<input type="button" id="off3" class="toggle" value="tops/sweaters">
<input type="button" id="off4" class="toggle" value="sweatshirts">
<input type="button" id="off5" class="toggle" value="pants">
<input type="button" id="off6" class="toggle" value="hats">
<input type="button" id="off7" class="toggle" value="bags">
<input type="button" id="off8" class="toggle" value="accessories">
</div>
To remove on class on sibling elements you can create one function that will return sibling nodes of clicked element and remove on class from each of those sibling nodes.
function getSiblings(el, nodes) {
return [...nodes].filter(node => node != el)
}
document.querySelectorAll('.toggle').forEach(function(button) {
button.addEventListener('click', function() {
this.classList.toggle('on');
getSiblings(this, this.parentNode.children).forEach(function(button) {
button.classList.remove('on');
})
})
})
input {
width: 95px;
float: left;
font-size: 12px;
border-radius: 2px;
margin: 5px;
padding: 3px;
}
.toggle {
background-color: #101820FF;
color: #fff;
border: 1px solid white;
}
.on {
background-color: #FEE715FF;
color: #101820FF;
border: 1px solid #FEE715FF;
}
<div class="item-toggle-group">
<input type="button" id="off1" class="toggle" value="jackets">
<input type="button" id="off2" class="toggle" value="shirts">
<input type="button" id="off3" class="toggle" value="tops/sweaters">
<input type="button" id="off4" class="toggle" value="sweatshirts">
<input type="button" id="off5" class="toggle" value="pants">
<input type="button" id="off6" class="toggle" value="hats">
<input type="button" id="off7" class="toggle" value="bags">
<input type="button" id="off8" class="toggle" value="accessories">
</div>

You should not be modifying the ID of your button elements - once two are turned on, you have two elements with the same ID of 'on'. At this point, when you turn any of them off, only the first element with the ID of 'on' is being set back to the off state (not necessarily the one you clicked to turn off).
Easiest fix is to modify the class of these button elements (not the ID) using:
document.getElementById("off5").className = "on";
Then also change your CSS to style by class, not by ID
.on { /* styles here */ }
not
#on { /* styles here */ }

Use classes instead. Then you only need one function. When you click a button remove the on class from all the elements and then add it to this element
function highlight() {
items.forEach(function(item) {
item.classList.replace('on', 'off');
});
this.classList.replace('off', 'on');
}
var items = document.querySelectorAll(".off");
items.forEach(function(item) {
item.addEventListener("click", highlight);
});
input {
width: 95px;
float:left;
font-size: 12px;
border-radius: 2px;
margin: 5px;
padding: 3px;
}
.off {
background-color: #101820FF;
color: #fff;
border:1px solid white;
}
.on {
background-color: #FEE715FF;
color:#101820FF;
border: 1px solid #FEE715FF;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="item-toggle-group">
<input type="button" class="off" value="jackets">
<input type="button" class="off" value="shirts">
<input type="button" class="off" value="tops/sweaters">
<input type="button" class="off" value="sweatshirts">
<input type="button" class="off" value="pants">
<input type="button" class="off" value="hats">
<input type="button" class="off" value="bags">
<input type="button" class="off" value="accessories">
</div>
</body>
</html>

I'd recommend using element.classList.toggle('toggle-class')
function doToggle(event) {
event.target.classList.toggle('toggled');
}
var toggleInputs = document.getElementsByTagName('input');
for(var index in toggleInputs) {
toggleInputs[index].onclick = doToggle;
}
.toggled {
background: green;
}
<input type="button" value="toggle me 1"><br>
<input type="button" value="toggle me 2"><br>
<input type="button" value="toggle me 3"><br>
<input type="button" value="toggle me 4"><br>
<input type="button" value="toggle me 5"><br>
<input type="button" value="toggle me 6"><br>

Related

How do I animate this JS function that makes a div block/hide onclick of object?

How can I animate this so when the div appears and disappears expands down and retracts up? I thought maybe with css3 animations but when I add transition animations to my CSS it doesn't do anything.
function SearchToggle(){
var off=document.getElementById('SearchContainer');
if (off.style.display == "none") {
off.style.display = "block";
} else {
off.style.display = "none";
}
}
#SearchContainer {
border: none;
outline: none;
display: block;
background-color: silver;
color: #FFF;
margin: 0 0 0 0;
float: left;
width: 400px;
min-width: 400px;
max-width: 400px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
<menu name="WindowMenu" id="WindowMenu" class="WindowMenu">
<span name="WindowIcon-Span" id="WindowIcon-Span" class="WindowIcon-Span">
<img src="ROOT.ASSETS/IMAGES/ICONS/ICON GROUP 1/FAVICON1.64.png" name="WindowIcon-PNG" id="WindowIcon-PNG" class="WindowIcon-PNG" />
</span>
<span name="WindowTitle" id="WindowTitle" class="WindowTitle"> PROTON CORE </span>
<div name="WindowControl-Wrapper" id="WindowControl-Wrapper" class="WindowControlWrapper">
<i name="SearchIcon" id="SearchIcon" class="fa-solid fa-magnifying-glass" onclick="SearchToggle()"></i>
<input type="button" value="" name="WindowControl-1" id="WindowControl-1" class="WindowControl-1" onclick="window.close(true)" />
<input type="button" value="" name="WindowControl-2" id="WindowControl-2" class="WindowControl-2" />
</div>
</menu>
<form name="SearchContainer" id="SearchContainer" class="SearchContainer">
</form>
I tried this instead to try an animate the height transition with CSS but it's ceased to work after changing it to height.
function SearchToggle(){
var off=document.getElementById('SearchContainer');
if (off.style.height == "0px") {
off.style.height = "40px";
} else {
off.style.display = "0px";
}
}
#SearchContainer {
border: none;
outline: none;
background-color: silver;
color: #FFF;
margin: 0 0 0 0;
float: left;
width: 400px;
min-width: 400px;
max-width: 400px;
height: 0px;
//min-height: 40px;
//max-height: 40px;
transition: height 2s;
}
Ok, Here is what I think you want:
var current = "up";
function SearchToggle(){
if(current == "up"){
document.getElementById("WindowMenu").classList.remove("WindowMenuUp")
document.getElementById("WindowMenu").classList.add("WindowMenuDown")
current = "down";
}
else {
document.getElementById("WindowMenu").classList.remove("WindowMenuDown")
document.getElementById("WindowMenu").classList.add("WindowMenuUp")
current = "up";
}
}
.WindowMenuDown {
height: 40px;
transition: 1s;
}
.WindowMenuUp {
height: 0;
transition: 1s;
}
#WindowControl-Wrapper {
overflow: auto;
}
<menu name="WindowMenu" id="WindowMenu" class="">
<span name="WindowIcon-Span" id="WindowIcon-Span" class="WindowIcon-Span">
<img src="ROOT.ASSETS/IMAGES/ICONS/ICON GROUP 1/FAVICON1.64.png" name="WindowIcon-PNG" id="WindowIcon-PNG" class="WindowIcon-PNG" />
</span>
<span name="WindowTitle" id="WindowTitle" class="WindowTitle"> PROTON CORE </span>
<div name="WindowControl-Wrapper" id="WindowControl-Wrapper" class="WindowControlWrapper">
<i name="SearchIcon" id="SearchIcon" class="fa-solid fa-magnifying-glass"></i>
<input type="button" value="" name="WindowControl-1" id="WindowControl-1" class="WindowControl-1" onclick="window.close(true)" />
<input type="button" value="" name="WindowControl-2" id="WindowControl-2" class="WindowControl-2" />
</div>
</menu>
<form name="SearchContainer" id="SearchContainer" class="SearchContainer">
<input type="button" value="Button" onclick="SearchToggle()">
</form>
If you decide to use JQuery as requested, here is a snippet:
#WindowControl-Wrapper {
display: none;
overflow: auto;
}
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body>
<menu name="WindowMenu" id="WindowMenu" class="">
<span name="WindowIcon-Span" id="WindowIcon-Span" class="WindowIcon-Span">
<img src="ROOT.ASSETS/IMAGES/ICONS/ICON GROUP 1/FAVICON1.64.png" name="WindowIcon-PNG" id="WindowIcon-PNG" class="WindowIcon-PNG" />
</span>
<span name="WindowTitle" id="WindowTitle" class="WindowTitle"> PROTON CORE </span>
<div name="WindowControl-Wrapper" id="WindowControl-Wrapper" class="WindowMenuUp">
<input type="button" value="" name="WindowControl-1" id="WindowControl-1" class="WindowControl-1" onclick="window.close(true)" />
<input type="button" value="" name="WindowControl-2" id="WindowControl-2" class="WindowControl-2" />
</div>
</menu>
<form name="SearchContainer" id="SearchContainer" class="SearchContainer">
<input type="button" value="Button" id="button">
</form>
<script type="text/javascript">
<!--
$(document).ready(function(){
var current = "up";
$('#button').on('click',function() {
if(current == "up"){
$('#WindowControl-Wrapper').show(500).slideDown(500);
current = "down"
}
else{
$('#WindowControl-Wrapper').hide(500).slideUp(500);
current = "down"
}
});
})
//-->
</script>
</body>

Change color of button while filtering data

I have spent a good amount of time researching this question, but i cannot seem to find an answer.
I am simply trying to change the color of my buttons as i click on them. Currently, the buttons register, but does not recognize a change in the background color. The code goes through and filters data as well, hence the extra additional function. I know this is extremely simple, but I cant seem to identify the button background and change it!
CSS:
.button {
position: relative;
width: 70px;
padding: 5px 5px;
margin-right: 3px;
margin-bottom: 3px;
cursor: pointer;
text-align: center;
font-size: .65em;
border: .5px solid #e0e0e0;
float: left;
-moz-border-radius: 3px;
border-radius: 3px;
background: rgb(255, 255, 255);
}
.button:hover {
background: #e0e0e0;
}
.button.current {
background: #242424;
color: #fff;
}
HTML:
<div class="buttons">
<div a href="#" data-placement="bottom" data-val="1" id="option" name="updateButton" type="button" value="Update" class="button" onclick="buttonClick('b1')">Button 1</div>
<div a href="#" id="option" class="button" data-val="2" type="button" value="Update" onclick="buttonClick('b2')">Button 2</div>
<div a href="#" id="option" class="button" data-val="3" type="button" value="Update" onclick="buttonClick('b3')">Button 3</div>
<div a href="#" id=option class="button" data-val="3" type="button" value="Update" onclick="buttonClick('b4')">Button 4</div>
</div>
Javascript:
// Shared function
function filterData() {
var newData = _(site_data).filter(function(site) {
return site[buildingType] < minYear;
});
displaySites(newData);
return newData.length;
}
function buttonClick(filterField) {
if (filterField !== undefined) {
//console.info('Changing building filter to', filterField);
buildingType = filterField;
}
//console.info('Applying filter');
filterData();
//click to change color of button background
var backgroundColor = document.getElementById('option')
function buttonClick(backgroundColor) {
if (backgroundColor.onclick == true) {
option.style.backgroundColor = "#0fe417";
} else {
option.style.backgroundColor = "#0029ff";
}
}
}
i just pass the element to the function and change the background color:
[Update with color reset!!]
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="http://kithomepage.com/inga/jquery.validate.min.js"></script>
<div class="buttons">
<div a href="#" data-placement="bottom" data-val="1" id="option" name="updateButton" type="button" value="Update" class="button" onclick="buttonClick('b1',this)">Button 1</div>
<div a href="#" id="option" class="button" data-val="2" type="button" value="Update" onclick="buttonClick('b2',this)">Button 2</div>
<div a href="#" id="option" class="button" data-val="3" type="button" value="Update" onclick="buttonClick('b3',this)">Button 3</div>
<div a href="#" id=option class="button" data-val="3" type="button" value="Update" onclick="buttonClick('b4',this)">Button 4</div>
</div>
<style> .button {
position: relative;
width: 70px;
padding: 5px 5px;
margin-right: 3px;
margin-bottom: 3px;
cursor: pointer;
text-align: center;
font-size: .65em;
border: .5px solid #e0e0e0;
float: left;
-moz-border-radius: 3px;
border-radius: 3px;
background: rgb(255, 255, 255);
}
.button:hover {
background: #e0e0e0;
}
.button.current {
background: #242424;
color: #fff;
}
</style>
<script>
// Shared function
function filterData() {
//just comment for hide a error
//var newData = _(site_data).filter(function(site) {
// return site[buildingType] < minYear;
//});
//displaySites(newData);
//return newData.length;
}
function buttonClick(filterField,element) {
element.style.backgroundColor ="red"
var backgroundColor = document.getElementById('option');
buttonClickColor(backgroundColor,element);
if (filterField !== undefined) {
//console.info('Changing building filter to', filterField);
buildingType = filterField;
}
//console.info('Applying filter');
filterData();
//click to change color of button background
function buttonClickColor(backgroundColor,element) {
//reset color
Array.from(document.getElementsByClassName("button")).forEach(function (button,index){
button.style.backgroundColor = "white";
})
if (backgroundColor.onclick == true) {
element.style.backgroundColor = "#0fe417";
} else {
element.style.backgroundColor = "#0029ff";
}
}
}
</script>
const buttons = [...document.querySelectorAll(".button")];
buttons.forEach(item => {
item.addEventListener("click", e => {
console.log(e.target.dataset.val)
buttons.forEach(item => {
item.classList.remove("current");
});
e.target.classList.add("current");
filterData(); //and other code...
});
});
use e.target.dataset instead buttonClick('b2')

Javascript Calculator- Math Sign & Infinity

I'm trying to create a calculator with basic operators. So far I have a good deal of it running but I'm attempting to write a button to change the math sign from positive and negative and back. I 'm also unsure how to make dividing by zero show Error instead of infinity. I'm aware the math sign in my code currently does nothing, I 'm not sure how to go about it.
function clearDisplay() {
var display = document.getElementById('display');
display.value = '0';
storedNum = '0';
calculationFinished = true;
operation = operations.none;
}
function clearPreviousResult() {
var display = document.getElementById('display');
if (calculationFinished) {
display.value = '0';
calculationFinished = false;
}
}
function numInput(digit) {
var display = document.getElementById('display');
clearPreviousResult(); // Get rid of a 0 if it's the only thing in there.
// This particular way of doing it lets you enter a 0 and have it show up, as well as leaving a 0 for the decimal point to snuggle up to
if (display.value === '0') display.value = '';
display.value += digit;
}
function insertDecimal() {
var display = document.getElementById('display');
clearPreviousResult();
if (display.value.indexOf('.') === -1) display.value += '.';
}
operations = {
// no-op. Takes the right side, and just returns it. Since the right side is the display value, and calculate() sets display.value, this effectively makes calculate() say "display.value = +display.value".
none: function(left, right) { return right; }, // Math ops.
add: function(left, right) { return left + right; },
subtract: function(left, right) { return left - right; },
multiply: function(left, right) { return left * right; },
divide: function(left, right) { return left / right; },
};
function setOperation(command) {
var display = document.getElementById('display');
calculate();
storedNum = display.value;
if (operations.hasOwnProperty(command))
operation = operations[command];
}
function calculate() {
var display = document.getElementById('display');
display.value = operation(+storedNum, +display.value);
calculationFinished = true;
operation = operations.none;
}
if ('addEventListener' in window)
window.addEventListener('load', clearDisplay);
else
window.attachEvent('onload', clearDisplay);
body {
background-color: lightgrey;
}
#container {
position: relative;
width: 300px;
height: 320px;
border: 2px solid grey;
border-radius: 4px;
background-color: navy;
padding: 20px;
margin: 50px auto;
box-shadow: 3px 2px 2px 1px black;
}
input[type=button] {
background: lightgrey;
width: 20%;
font-size: 20px;
font-weight: 900;
font: white;
margin: 2%;
border-radius: 4px;
box-shadow: 0px 0px 2px 1px black;
outline: none;
}
#container .operator {
width: 45%;
}
input[type=text] {
position: relative;
display: block;
height: 40px;
width: 93%;
border: 2px solid black;
border-radius: 5px;
box-shadow: 0px 0px 1px black;
margin: 5px 5px -2px 5px;
text-align: right;
outline: none;
font-size: 25px;
font-weight: bold;
padding-right: 5px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<script>
</script>
</head>
<body>
<form class="calcForm" name="calculator">
<input type="text" class="calcDisplay" id="display" />
<div class="calcRow">
<input type="button"
class="calcButton"
value="7"
onclick="numInput('7')" />
<input type="button"
class="calcButton"
value="8"
onclick="numInput('8')" />
<input type="button"
class="calcButton"
value="9"
onclick="numInput('9')" />
<input type="button"
class="calcButton"
value="+"
onclick="setOperation('add')" />
</div>
<div class="calcRow">
<input type="button"
class="calcButton"
value="4"
onclick="numInput('4')" />
<input type="button"
class="calcButton"
value="5"
onclick="numInput('5')" />
<input type="button"
class="calcButton"
value="6"
onclick="numInput('6')" />
<input type="button"
class="calcButton"
value="-"
onclick="setOperation('subtract')" />
</div>
<div class="calcRow">
<input type="button"
class="calcButton"
value="1"
onclick="numInput('1')" />
<input type="button"
class="calcButton"
value="2"
onclick="numInput('2')" />
<input type="button"
class="calcButton"
value="3"
onclick="numInput('3')" />
<input type="button"
class="calcButton"
value="x"
onclick="setOperation('multiply')" />
</div>
<div class="calcRow">
<input type="button"
class="calcButton"
value="0"
onclick="numInput('0')" />
<input type="button"
class="calcButton"
value="."
onclick="insertDecimal('.')" />
<input type="button"
class="calcButton"
value="+/-"
onclick="setOperation()" />
<input type="button"
class="calcButton"
value="/"
onclick="setOperation('divide')" />
</div>
<div class="calcRow">
<input type="button"
class="calcButton"
value="C"
onclick="clearDisplay()" />
<input type="button"
class="calcButton"
value="="
onclick="calculate()" />
</div>
</form>
</body>
</html>
In math, to flip a number's sign, you can multiply (or divide) it by -1, so:
/* you shouldn't redeclare "display" in the body of
every function, just declare the one and reuse it */
var display = document.getElementById('display');
function flipSignOperation() {
display.value *= -1;
}
To prevent a division by 0, you can change the body of operations["divide"] to this:
return right !== 0 ? left / right : "Error!";
I am using JavaScript's Conditional Ternary Operator. If you wanted to do it in a simpler way (but the first one's 1 line while this is 5):
if(right !== 0) {
return left / right;
} else {
return "Error!";
}
P.S it's a wonder your question hasn't been downvoted to the depths of Tartarus by now.

Javascript calculator. How to stop multiple operands?

I have been working on a calculator as a learning project for myself. It is working fine except I cannot figure out how to stop people from adding app breaking inputs such as 1++-*/4. I have tried various things like splitting my current display into an array and comparing it to another array with all the operators. I have also tried if(output.includes(input){ blah blah }.
I tried adding an extra else if to the getbuttonpress which went something like this else if(input == "*" || input == "+" || input == "/" || input = "-"){do something}
It didn't really work out for me.
Could someone please explain some different methods that I could use to resolve the issue?
Here is my code:
var resultDisplayed = false;
function getButtonPress() {
var input = this.value;
if (input == "=") {
console.log("bang");
getResult();
} else if (resultDisplayed && input < 10) {
document.getElementById("output").innerHTML = input;
resultDisplayed = false;
} else {
document.getElementById("output").innerHTML += input;
console.log(input);
resultDisplayed = false;
}
}
window.onload = function() {
[].slice.call(document.getElementsByClassName("button")).forEach(function(e) {
e.addEventListener('click', getButtonPress);
});
};
function getResult() {
var result = document.getElementById("output").innerHTML;
var resultCalculated = eval(result);
console.log(resultCalculated);
document.getElementById("output").innerHTML = resultCalculated;
resultDisplayed = true;
}
/* Fonts from Google Fonts - more at https://fonts.google.com */
#import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
#import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
body {
background-color: white;
font-family: "Open Sans", sans-serif;
font-size: 18px;
color: #444;
text-align: center;
}
h1 {
font-family: "Merriweather", serif;
font-size: 32px;
}
#calculator {
width: 250px;
height: 400px;
position: absolute;
background-color: grey;
padding: 15px;
box-shadow: 5px 5px 5px 5px;
margin: auto;
}
.button {
width: 19%;
height: 70px;
box-shadow: 1px 1px 1px 1px;
border: 1px solid black;
display: inline-block;
margin: 5px;
}
.buttonContainer {
width: 95%;
margin: auto;
margin-top: 10px;
}
#screen {
width: 90%;
height: 15%;
background-color: green;
margin: auto;
color: white;
text-align: right;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Calculator</h1>
<div id="calculator">
<div id="screen">
<h1 id="output">0</h1>
</div>
<div class="buttonContainer">
<button class="button" value="7">
<h1 class = "number">7</h1>
</button>
<button class="button" value="8">
<h1 class = "number">8</h1>
</button>
<button class="button" value="9">
<h1 class = "number">9</h1>
</button>
<button class="button" value="+">
<h1 class = "number">+</h1>
</button>
<button class="button" value="4">
<h1 class = "number">4</h1>
</button>
<button class="button" value="5">
<h1 class = "number">5</h1>
</button>
<button class="button" value="6">
<h1 class = "number">6</h1>
</button>
<button class="button" value="-">
<h1 class = "operator">-</h1>
</button>
<button class="button" value="1">
<h1 class = "number">1</h1>
</button>
<button class="button" value="2">
<h1 class = "number">2</h1>
</button>
<button class="button" value="3">
<h1 class = "number">3</h1>
</button>
<button class="button" value="*">
<h1 class = "operator">*</h1>
</button>
<button class="button" value=".">
<h1 class = "operator">.</h1>
</button>
<button class="button" value="0">
<h1 class = "number">0</h1>
</button>
<button class="button" value="=">
<h1 class = "operator">=</h1>
</button>
<button class="button" value="/">
<h1 class = "operator">/</h1>
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Add the below code to your getButtonPress function
It will check whether both the current input and previous entry are operators.
If yes, it will replace the previous operator with new one
var element=document.getElementById("output");
if (/[+-\/*]/.test(this.value) && /[+-\/*]$/.test(element.innerHTML)) {
element.innerHTML = element.innerHTML.replace(element.innerHTML[element.innerHTML.length - 1], '');
}
var resultDisplayed = false;
function getButtonPress() {
var input;
var element=document.getElementById("output");
if (/[+-\/*]/.test(this.value) && /[+-\/*]$/.test(element.innerHTML)) {
element.innerHTML = element.innerHTML.replace(element.innerHTML[element.innerHTML.length - 1], '');
}
input = this.value;
if (input == "=") {
console.log("bang");
getResult();
} else if (resultDisplayed && input < 10) {
document.getElementById("output").innerHTML = input;
resultDisplayed = false;
} else {
document.getElementById("output").innerHTML += input;
resultDisplayed = false;
}
}
window.onload = function() {
[].slice.call(document.getElementsByClassName("button")).forEach(function(e) {
e.addEventListener('click', getButtonPress);
});
};
function getResult() {
var result = document.getElementById("output").innerHTML;
var resultCalculated = eval(result);
console.log(resultCalculated);
document.getElementById("output").innerHTML = resultCalculated;
resultDisplayed = true;
}
/* Fonts from Google Fonts - more at https://fonts.google.com */
#import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
#import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
body {
background-color: white;
font-family: "Open Sans", sans-serif;
font-size: 18px;
color: #444;
text-align: center;
}
h1 {
font-family: "Merriweather", serif;
font-size: 32px;
}
#calculator {
width: 250px;
height: 400px;
position: absolute;
background-color: grey;
padding: 15px;
box-shadow: 5px 5px 5px 5px;
margin: auto;
}
.button {
width: 19%;
height: 70px;
box-shadow: 1px 1px 1px 1px;
border: 1px solid black;
display: inline-block;
margin: 5px;
}
.buttonContainer {
width: 95%;
margin: auto;
margin-top: 10px;
}
#screen {
width: 90%;
height: 15%;
background-color: green;
margin: auto;
color: white;
text-align: right;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Calculator</h1>
<div id="calculator">
<div id="screen">
<h1 id="output">0</h1>
</div>
<div class="buttonContainer">
<button class="button" value="7">
<h1 class = "number">7</h1>
</button>
<button class="button" value="8">
<h1 class = "number">8</h1>
</button>
<button class="button" value="9">
<h1 class = "number">9</h1>
</button>
<button class="button" value="+">
<h1 class = "number">+</h1>
</button>
<button class="button" value="4">
<h1 class = "number">4</h1>
</button>
<button class="button" value="5">
<h1 class = "number">5</h1>
</button>
<button class="button" value="6">
<h1 class = "number">6</h1>
</button>
<button class="button" value="-">
<h1 class = "operator">-</h1>
</button>
<button class="button" value="1">
<h1 class = "number">1</h1>
</button>
<button class="button" value="2">
<h1 class = "number">2</h1>
</button>
<button class="button" value="3">
<h1 class = "number">3</h1>
</button>
<button class="button" value="*">
<h1 class = "operator">*</h1>
</button>
<button class="button" value=".">
<h1 class = "operator">.</h1>
</button>
<button class="button" value="0">
<h1 class = "number">0</h1>
</button>
<button class="button" value="=">
<h1 class = "operator">=</h1>
</button>
<button class="button" value="/">
<h1 class = "operator">/</h1>
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Added try catch statement.
It may not be the best solution. You should build some kind of parser, but this will also work very well.
var resultDisplayed = false;
//1++-*/4
function getButtonPress() {
var input = this.value;
if (input == "=") {
//console.log("bang");
getResult();
} else if (resultDisplayed && input < 10) {
document.getElementById("output").innerHTML = input;
resultDisplayed = false;
} else {
document.getElementById("output").innerHTML += input;
//console.log(input);
resultDisplayed = false;
}
}
window.onload = function() {
[].slice.call(document.getElementsByClassName("button")).forEach(function(e) {
e.addEventListener('click', getButtonPress);
});
};
function getResult() {
try{
var result = document.getElementById("output").innerHTML;
var resultCalculated = eval(result);
console.log(resultCalculated);
document.getElementById("output").innerHTML = resultCalculated;
resultDisplayed = true;
}catch(e){
console.log("Invalid expression");
document.getElementById("output").innerHTML = 0;
}
}
/* Fonts from Google Fonts - more at https://fonts.google.com */
#import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
#import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
body {
background-color: white;
font-family: "Open Sans", sans-serif;
font-size: 18px;
color: #444;
text-align: center;
}
h1 {
font-family: "Merriweather", serif;
font-size: 32px;
}
#calculator {
width: 250px;
height: 400px;
position: absolute;
background-color: grey;
padding: 15px;
box-shadow: 5px 5px 5px 5px;
margin: auto;
}
.button {
width: 19%;
height: 70px;
box-shadow: 1px 1px 1px 1px;
border: 1px solid black;
display: inline-block;
margin: 5px;
}
.buttonContainer {
width: 95%;
margin: auto;
margin-top: 10px;
}
#screen {
width: 90%;
height: 15%;
background-color: green;
margin: auto;
color: white;
text-align: right;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Calculator</h1>
<div id="calculator">
<div id="screen">
<h1 id="output">0</h1>
</div>
<div class="buttonContainer">
<button class="button" value="7">
<h1 class = "number">7</h1>
</button>
<button class="button" value="8">
<h1 class = "number">8</h1>
</button>
<button class="button" value="9">
<h1 class = "number">9</h1>
</button>
<button class="button" value="+">
<h1 class = "number">+</h1>
</button>
<button class="button" value="4">
<h1 class = "number">4</h1>
</button>
<button class="button" value="5">
<h1 class = "number">5</h1>
</button>
<button class="button" value="6">
<h1 class = "number">6</h1>
</button>
<button class="button" value="-">
<h1 class = "operator">-</h1>
</button>
<button class="button" value="1">
<h1 class = "number">1</h1>
</button>
<button class="button" value="2">
<h1 class = "number">2</h1>
</button>
<button class="button" value="3">
<h1 class = "number">3</h1>
</button>
<button class="button" value="*">
<h1 class = "operator">*</h1>
</button>
<button class="button" value=".">
<h1 class = "operator">.</h1>
</button>
<button class="button" value="0">
<h1 class = "number">0</h1>
</button>
<button class="button" value="=">
<h1 class = "operator">=</h1>
</button>
<button class="button" value="/">
<h1 class = "operator">/</h1>
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
The final else in getButtonPress has to look like this:
else {
var operators = ["+", "-", "*", "/", "."],
lastCharacter = document.getElementById("output").innerHTML[document.getElementById("output").innerHTML.length - 1];
if(!operators.includes(lastCharacter) || !operators.includes(input)){
document.getElementById("output").innerHTML += input;
console.log(input);
resultDisplayed = false;
}
}
Intuitively,
!operators.includes(lastCharacter) || !operators.includes(input)
can be thought of as the logical expression
operators.includes(lastCharacter) → ¬operators.includes(input)
which means “if the last character is an operator, the next input isn’t an operator”. if this is the case, the symbol is added to the output screen, otherwise it isn’t.
This still won’t prevent you from entering numbers like 2.5.6 or ending the expression with an operator, but this solves the described problem.
another option, delete 0 in start and delete operands in last character when getResult() called
var resultDisplayed = false;
function getButtonPress() {
var input = this.value,
output = document.getElementById("output");
if(input == "=") {
//console.log("bang");
getResult();
}
else if(resultDisplayed && input < 10) {
output.innerHTML = input;
resultDisplayed = false;
}
else {
//console.log(input);
var currentValue = output.innerHTML;
// start with 0 + digit, delete it
if((currentValue+input).match(/^0\d/)){
input = input;
}
// end with +-*/ delete it
else if(currentValue.match(/[-\+\*\/]$/) && input.match(/[-\+\*\/]/)) {
input = currentValue.slice(0, -1) +''+ input;
}
else{
input = currentValue + input
}
output.innerHTML = input;
resultDisplayed = false;
}
}
[].slice.call(document.getElementsByClassName("button")).forEach(function(e) {
e.addEventListener('click', getButtonPress);
});
function getResult() {
var result = document.getElementById("output").innerHTML;
if(result.match(/[-\+\*\/]$/))
result = result.slice(0, -1);
var resultCalculated = eval(result);
console.log(resultCalculated);
document.getElementById("output").innerHTML = resultCalculated;
resultDisplayed = true;
}
#import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
#import url('https://fonts.googleapis.com/css?family=Merriweather:400,700');
body {
background-color: white;
font-family: "Open Sans", sans-serif;
font-size: 18px;
color: #444;
text-align: center;
}
h1 {
font-family: "Merriweather", serif;
font-size: 32px;
}
#calculator {
width: 250px;
height: 400px;
position: absolute;
background-color: grey;
padding: 15px;
box-shadow: 5px 5px 5px 5px;
margin: auto;
}
.button {
width: 19%;
height: 70px;
box-shadow: 1px 1px 1px 1px;
border: 1px solid black;
display: inline-block;
margin: 5px;
}
.buttonContainer {
width: 95%;
margin: auto;
margin-top: 10px;
}
#screen {
width: 90%;
height: 15%;
background-color: green;
margin: auto;
color: white;
text-align: right;
overflow: hidden;
}
<h1>Calculator</h1>
<div id="calculator">
<div id="screen">
<h1 id="output">0</h1>
</div>
<div class="buttonContainer">
<button class="button" value="7">
<h1 class="number">7</h1>
</button>
<button class="button" value="8">
<h1 class="number">8</h1>
</button>
<button class="button" value="9">
<h1 class="number">9</h1>
</button>
<button class="button" value="+">
<h1 class="number">+</h1>
</button>
<button class="button" value="4">
<h1 class="number">4</h1>
</button>
<button class="button" value="5">
<h1 class="number">5</h1>
</button>
<button class="button" value="6">
<h1 class="number">6</h1>
</button>
<button class="button" value="-">
<h1 class="operator">-</h1>
</button>
<button class="button" value="1">
<h1 class="number">1</h1>
</button>
<button class="button" value="2">
<h1 class="number">2</h1>
</button>
<button class="button" value="3">
<h1 class="number">3</h1>
</button>
<button class="button" value="*">
<h1 class="operator">*</h1>
</button>
<button class="button" value=".">
<h1 class="operator">.</h1>
</button>
<button class="button" value="0">
<h1 class="number">0</h1>
</button>
<button class="button" value="=">
<h1 class="operator">=</h1>
</button>
<button class="button" value="/">
<h1 class="operator">/</h1>
</button>
</div>
</div>
Here is the Code that will not accept multiple operands
function calc(opr)
{
var a2=0;
var a1 = cal.display.value;
a2 = a1.charAt(a1.length-1);
if(a2 == '/' || a2 == '+' || a2 == '-' || a2 == '*')
{
cal.display.value = a1.substring(0,a1.length-1);
cal.display.value += opr;
}
else
{
cal.display.value+= opr;
}
}
Whenever you click any operand button you need to take the last val from the input and see if its one of the operands, if it is skip like below.
$('#button-plus').click(function() {
var lastChar = $('#disp').val().slice(-1);
var firstChar = $('#disp').val().slice(0);
if (lastChar == '*' || lastChar == '-' || lastChar == '+' || lastChar == '/' || lastChar == '.' || lastChar == '(' || lastChar == '%'){
// DO NOTHING
}
else if (firstChar == '0'){
// DO NOTHING
}
else {
addChar(this.form.display, '+');
}
$('#disp').removeClass("result");
dotCount = 0;
});

Uncheck a group of checked input type="checkbox" with a single button

I have a #main-container with groups of input type checkboxes. These checkboxes open up button lists when checked.
The #main-container that holds all of this can be closed by a button. The problem I have is how do I make this button that closes #main-container also uncheck any checkboxes that are left checked when the #main-container is closed?
At the bottom I have included the only way I know to do it with Javascript at the moment, but that means making a variable for each checkbox and that checkbox must have a unique ID. I am trying to avoid that.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input checkbox</title>
<style>
body {
margin: 0;
background: beige;
border: 1px solid blue;
}
.main-container {
border: 1px solid red;
width: 25%;
position: relative;
}
.toggle-box {
display: none;
}
label {
margin: 0.2em;
display: block;
text-align: center;
transition: all 1s linear;
border: 1px solid green;
}
.toggle-box + div {
display: none;
margin: 0.2em;
text-align: center;
}
.toggle-box:checked + div {
display: block;
border: 1px solid black;
transition: all 1s linear;
}
button {
display: block;
margin: auto;
width: 100%;
}
</style>
</head>
<body>
<div id="main-container" class="main-container">
<label for="toggle-box">A</label>
<input class="toggle-box" id="toggle-box" type="checkbox" >
<div>
<button type="button">submit</button>
<button type="button">submit</button>
</div>
<label for="toggle-box2">B</label>
<input class="toggle-box" id="toggle-box2" type="checkbox" >
<div>
<button type="button">submit</button>
<button type="button">submit</button>
</div>
<div></div>
<div></div>
<div class="test1"></div>
</div>
<button type="button" onclick="closeMe()">close</button>
<button type="button" onclick="openMe()">open</button>
<script>
function closeMe() {
var $toggleBox = document.getElementById("toggle-box");
$toggleBox.checked = false;
document.getElementById("main-container").style.display = "none";
}
function openMe() {
document.getElementById("main-container").style.display = "block";
}
</script>
</body>
</html>
function closeMe() {
var $toggleBoxes = document.querySelectorAll(".toggle-box");
$toggleBoxes.forEach(function(box){
box.checked = false;
});
document.getElementById("main-container").style.display = "none";
}
document.querySelectorAll return an array of all the matched element (match with a css selector). Then, we loop through all those elements using forEach (you can use a for loop instead if you want).
You can use document.querySelectorAll to select all checkboxes for example:
var cbks = document.querySelectorAll('.toggle-box');
cbks.forEach(function(val){
val.checked = true;
});
You can select all the checkboxes by getElementsByClassName and then iterate over all the check box and set the checked value to false.
var $toggleBoxes = document.getElementsByClassName("toggle-box");
[].forEach.call($toggleBoxes, function(elem) {
elem.checked = false;
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input checkbox</title>
<style>
body {
margin: 0;
background: beige;
border: 1px solid blue;
}
.main-container {
border: 1px solid red;
width: 25%;
position: relative;
}
.toggle-box {
display: none;
}
label {
margin: 0.2em;
display: block;
text-align: center;
transition: all 1s linear;
border: 1px solid green;
}
.toggle-box + div {
display: none;
margin: 0.2em;
text-align: center;
}
.toggle-box:checked + div {
display: block;
border: 1px solid black;
transition: all 1s linear;
}
button {
display: block;
margin: auto;
width: 100%;
}
</style>
</head>
<body>
<div id="main-container" class="main-container">
<label for="toggle-box">A</label>
<input class="toggle-box" id="toggle-box" type="checkbox">
<div>
<button type="button">submit</button>
<button type="button">submit</button>
</div>
<label for="toggle-box2">B</label>
<input class="toggle-box" id="toggle-box2" type="checkbox">
<div>
<button type="button">submit</button>
<button type="button">submit</button>
</div>
<div></div>
<div></div>
<div class="test1"></div>
</div>
<button type="button" onclick="closeMe()">close</button>
<button type="button" onclick="openMe()">open</button>
<script>
function closeMe() {
var $toggleBoxes = document.getElementsByClassName("toggle-box");
[].forEach.call($toggleBoxes, function(elem) {
elem.checked = false;
});
document.getElementById("main-container").style.display = "none";
}
function openMe() {
document.getElementById("main-container").style.display = "block";
}
</script>
</body>
</html>

Categories