I am trying to show a Div that contains a button element, but only when BOTH checkboxes have been "agreed" to.
I have tried to use JS to check this and then set the style display when each checkbox is clicked.
HTML:
<div class="agreement_box">
<input type="checkbox" id="box1" onclick="showMe('submit_btn')">
</div>
<br>
<div class="agreement_box">
<input type="checkbox" id="box2" onclick="showMe('submit_btn')">
</div>
<div id="submit_btn" class="profileSubmit_btn" style="display:none">
<button>
BUTTON
</button>
</div>
JS:
function showMe(box) {
var chbox1 = document.getElementByID("box1");
var chbox2 = document.getElementByID("box2");
var vis = "none";
if (chbox1.checked && chbox2.checked) {
vis = "block";
break;
}
document.getElementById(box).style.display = vis;
}
Fiddle: https://jsfiddle.net/nhykqodp/2/
I'm kinda new to JS and my HTML knowledge is about 10 years out of date at this point. Any help would be appreciated.
Thanks.
If I run your code, it shows:
Uncaught SyntaxError: Illegal break statement
Thats because a break
can only be used inside a loop.
Furthermore, you have a typo, it should be getElementById instead of getElementByID
Note: The d shouldn't be capitalised
Remove the break
Fix the typos:
function showMe(box) {
var chbox1 = document.getElementById("box1");
var chbox2 = document.getElementById("box2");
var vis = "none";
if (chbox1.checked && chbox2.checked) {
vis = "block";
}
document.getElementById(box).style.display = vis;
}
<div class="agreement_box">
<input type="checkbox" id="box1" onclick="showMe('submit_btn')">
</div>
<br>
<div class="agreement_box">
<input type="checkbox" id="box2" onclick="showMe('submit_btn')">
</div>
<div id="submit_btn" class="profileSubmit_btn" style="display:none">
<button>
BUTTON
</button>
</div>
Using an in-line if statement, we can remove the vis variable so we can alter the style right away like so:
function showMe(box) {
const chbox1 = document.getElementById("box1");
const chbox2 = document.getElementById("box2");
document.getElementById(box).style.display = (chbox1.checked && chbox2.checked) ? 'block' : 'none';
}
function showMe(box) {
const chbox1 = document.getElementById("box1");
const chbox2 = document.getElementById("box2");
document.getElementById(box).style.display = (chbox1.checked && chbox2.checked) ? 'block' : 'none';
}
<div class="agreement_box">
<input type="checkbox" id="box1" onclick="showMe('submit_btn')">
</div>
<br>
<div class="agreement_box">
<input type="checkbox" id="box2" onclick="showMe('submit_btn')">
</div>
<div id="submit_btn" class="profileSubmit_btn" style="display:none">
<button>
BUTTON
</button>
</div>
The syntax errors have already been pointed out; for hiding/showing elements these already have an API which is called el.hidden. I recommend you use it.
Aside from that, you shouldn't use inline event handlers like onclick. Instead, use EventTarget.addEventListener().
I've also generalized your code, so that any number of checkboxes can act as toggle for any element, given that element has the id that you define in data-toggle on the checkboxes.
const checkboxes = Array.from(document.querySelectorAll('[data-toggle]'));
function allChecked(toggle) {
return checkboxes.filter(cb => cb.dataset.toggle === toggle).every(cb => cb.checked);
}
for (const checkbox of checkboxes) {
checkbox.addEventListener('change', function() {
document.getElementById(this.dataset.toggle).hidden = !allChecked(this.dataset.toggle);
});
}
<div class="agreement_box">
<input type="checkbox" data-toggle="submit_btn">
</div>
<br>
<div class="agreement_box">
<input type="checkbox" data-toggle="submit_btn">
</div>
<div id="submit_btn" class="profileSubmit_btn" hidden>
<button>
BUTTON
</button>
</div>
Little syntax error just replace document.getElementByID to document.getElementById
Related
I'd like to change the value of a label depending on the status of its checkbox
function private() {
var checkBox = document.getElementById("private");// Get the checkbox
var text = document.querySelector('label[for="private"]');// Get the output text
if (checkBox.checked == true)
{
text.innerHTML = "Public";
} else {
text.innerHTML = "Private";
}
}
<label class="switch">
<input id="private" type="checkbox" onclick="private()" />
<span class="slider"></span>
</label>
<label for="private"></label>
Why doesn't this work?
querySelectorAll returns a nodelist, so you need to specify the element you want like:
function private() {
var checkBox = document.getElementById("private");// Get the checkbox
var text = document.querySelectorAll('label[for="private"]')[0];// Get the output text
if (checkBox.checked == true)
{
text.innerHTML = "Public";
} else {
text.innerHTML = "Private";
}
}
<label class="switch">
<input id="private" type="checkbox" onclick="private()" />
<span class="slider"></span>
</label>
<label for="private"></label>
Or maybe just use querySelector instead which only returns the first match:
function private() {
var checkBox = document.getElementById("private");// Get the checkbox
var text = document.querySelector('label[for="private"]');// Get the output text
if (checkBox.checked == true)
{
text.innerHTML = "Public";
} else {
text.innerHTML = "Private";
}
}
<label class="switch">
<input id="private" type="checkbox" onclick="private()" />
<span class="slider"></span>
</label>
<label for="private"></label>
You need to use querySelector() not querySelectorAll(). By getting all elements, you would have to iterate through the list of items (even though there is only 1).
function private() {
var checkBox = document.getElementById("private");// Get the checkbox
var text = document.querySelector('label[for="private"]');// Get the output text
if (checkBox.checked == true)
{
text.innerHTML = "Public";
} else {
text.innerHTML = "Private";
}
}
<label class="switch">
<input id="private" type="checkbox" onclick="private()" />
<span class="slider"></span>
</label>
<label for="private"></label>
There are three things that I would suggest that will solve your problem:
Pass the event object to your function. This contains everything about the click event, including what element was clicked on. This means you don't have to scour the DOM.
Do not wrap a form control with a label. This is not how labels were intended to work. Instead use something like a section tag.
Form controls and their labels are automatically connected when a for attribute is provided. The other can be found through control.labels[0] or label.htmlFor. This is particularly why you want to adhere to the standard of not wrapping controls with labels
With these adjustments, and the addition of a ternary condition statement to determine what text to display, the code will look like this:
<section class="switch">
<input id="private" type="checkbox" onclick="private(event)" />
<span class="slider"></span>
</section>
<label for="private"></label>
function private(e) {
var checkBox = e.currentTarget,
label = checkBox.labels[0];
label.textContent = checkBox.checked ? "Public" : "Private";
}
Example:
function private(e) {
var checkBox = e.currentTarget,
label = checkBox.labels[0];
label.textContent = checkBox.checked ? "Public" : "Private";
}
<section class="switch">
<input id="private" type="checkbox" onclick="private(event)" />
<span class="slider"></span>
</section>
<label for="private"></label>
I have 3 input checkboxes. Each of them displays a div if checked. Because the three has the same JS I have decided to have just one JS including 3 variables (one per input) but it is not working. Before I had three independent JS and it worked fine.
CODE
document.getElementById()
var cb1 = document.getElementById('checkbox1'); checkbox1.onchange = {
if (checkbox1.checked) {
course1.style.display = 'block';
} else {
course1.style.display = 'none';
};
var cb2 = document.getElementById('checkbox2'); checkbox2.onchange = {
if (checkbox2.checked) {
course2.style.display = 'block';
} else {
course2.style.display = 'none';
};
var cb3 = document.getElementById('checkbox3'); checkbox3.onchange = {
if (checkbox3.checked) {
course3.style.display = 'block';
} else {
course3.style.display = 'none';
};
<form>
<label class="switch">
<input type="checkbox" id="checkbox1"> Course 1
</label>
</form>
<form>
<label class="switch">
<input type="checkbox" id="checkbox2"> Course 2
</label>
</form>
<form>
<label class="switch">
<input type="checkbox" id="checkbox3"> Course 3
</label>
</form>
<br>
<div id ="course1">
Text course 1
</div>
<br>
<div id ="course2">
Text course 2
</div>
<br>
<div id ="course3">
Text course 3
</div>
Fiddle: https://codepen.io/antonioagar1/pen/YOwBeE?editors=1010
After fixing your syntax errors (identation is very imporant, if it was correct in your code you would had see that you have many if statements not closing correclty)
Well, besides those errors, I managed a way to you that you only need a single function to achieve your desired result.
If you see in the HTML part, you'll note that I added some new attributes to checkboxes and divs, called data-idCheck, where the checkbox with data-idCheck will display the div whose have that same attribute.
Check below to see if my code helps you.
var cb1 = document.getElementById('checkbox1');
cb1.onchange = checkChecked;
var cb2 = document.getElementById('checkbox2');
cb2.onchange = checkChecked;
var cb3 = document.getElementById('checkbox3');
cb3.onchange = checkChecked;
function checkChecked(){
let idCheck = this.getAttribute("data-idCheck");
let relatedDiv = document.querySelector("div[data-idCheck='" + idCheck + "']");
if (this.checked) {
relatedDiv.style.display = 'block';
} else {
relatedDiv.style.display = 'none';
}
}
.hiddenDiv{
display: none;
}
<form>
<label class="switch">
<input type="checkbox" id="checkbox1" data-idCheck="1"> Course 1
</label>
</form>
<form>
<label class="switch">
<input type="checkbox" id="checkbox2" data-idCheck="2"> Course 2
</label>
</form>
<form>
<label class="switch">
<input type="checkbox" id="checkbox3" data-idCheck="3"> Course 3
</label>
</form>
<br>
<div id ="course1" class="hiddenDiv" data-idCheck="1">
Text course 1
</div>
<br>
<div id ="course2" class="hiddenDiv" data-idCheck="2">
Text course 2
</div>
<br>
<div id ="course3" class="hiddenDiv" data-idCheck="3">
Text course 3
</div>
This is my main script, that filters div by checkboxes
function change(){
var checkboxes = document.getElementsByClassName('checkbox');
var chekboxInputs = Array.from(checkboxes).map(a => a.querySelector('input'));
var allAreUnselected = chekboxInputs.every(function(elem){
return !elem.checked;
});
if(allAreUnselected){
chekboxInputs.forEach(function(input){
Array.from(document.querySelectorAll("." + input.getAttribute("rel"))).forEach(function(item){
item.style.display = 'block';
});
});
}
else {
chekboxInputs.forEach(function(input){
Array.from(document.querySelectorAll("." + input.getAttribute("rel"))).forEach(function(item){
item.style.display = input.checked ? 'block' : 'none';
});
});
}
}
change();
This is my html file. In this html there are checkboxes and dives
<div class="filter">
<div class="checkbox">
<label><input type="checkbox" rel="canada" onchange="change()"/>Canada</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="china" onchange="change()"/>China</label>
</div>
</div>
<div class="result">
<div class="canada">
<h1>Canada</h1>
<h2>Jason</h2>
</div>
<div class="china">
<h1>China</h1>
<h2>Ni</h2>
</div>
</div>
But the script filters only one value(in my case - city). How can I add another filters to class of div. For example
<div class="checkbox">
<label><input type="checkbox" rel="india" onchange="change()"/>India</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="programming" onchange="change()"/>Programming</label>
</div>
by the adding another value to class
<div class="india programming">...</div>
Adding multiple CSS classes could work, but your current code will overwrite a previous setting of style.display making it sometimes go from none to block, even though the none setting was the right setting.
Here is the code you could use, based on the first example you gave, and an additional result that has both classes "canada" and "china":
function change(){
let results = Array.from(document.querySelectorAll('.result > div'));
// Hide all results
results.forEach(function (result) {
result.style.display = 'none';
});
// Filter results to only those that meet ALL requirements:
Array.from(document.querySelectorAll('.filter input[rel]:checked'), function (input) {
const attrib = input.getAttribute('rel');
results = results.filter(function (result) {
return result.classList.contains(attrib);
});
});
// Show those filtered results:
results.forEach(function (result) {
result.style.display = 'block';
});
}
change();
<div class="filter">
<div class="checkbox">
<label><input type="checkbox" rel="canada" onchange="change()"/>Canada</label>
</div>
<div class="checkbox">
<label><input type="checkbox" rel="china" onchange="change()"/>China</label>
</div>
</div>
<div class="result">
<div class="canada">
<h1>Canada</h1>
<h2>Jason</h2>
</div>
<div class="china">
<h1>China</h1>
<h2>Ni</h2>
</div>
<div class="canada china">
<h1>China and Canada</h1>
<h2>Ni Jason</h2>
</div>
</div>
Note that I assume the rel attribute can only reference one CSS class.
How can I modify this code. Can I use one evenlistner there to implement the same result. What is the best practice in this case. Can I use here data atribute, or querySelector better. codepen
const myCheck = document.getElementById("check");
const myCheck2 = document.getElementById("check2");
const dib = document.getElementById("dib");
function change() {
if (myCheck2.checked) {
myCheck.checked = false;
dib.style.display = "block";
}
else{
dib.style.display = "none";
myCheck.checked = true;
}
}
function func2() {
if (this.checked) {
myCheck2.checked = false;
dib.style.display = "none";
}
else {
dib.style.display = "block";
myCheck2.checked = true;
}
}
myCheck2.addEventListener('click', change);
myCheck.addEventListener('click', func2);
<input type="checkbox" id="check" >
<input type="checkbox" id="check2" checked="checked" >
<div id="dib">Text</div>
Two improvements you could make to your existing code without changing the logic at all would be to use meaningful names for your functions, and to fix the indenting. But anyway...
If I've understood your existing code, the idea is that when either checkbox is checked the other should be automatically unchecked (in which case why not use radio buttons?), and the associated div should be displayed only if the second checkbox is checked? If so, you could combine the code into a single function as follows:
const myCheck = document.getElementById("check");
const myCheck2 = document.getElementById("check2");
const dib = document.getElementById("dib");
function cbChanged() {
(this === myCheck ? myCheck2 : myCheck).checked = !this.checked;
dib.style.display = myCheck2.checked ? "block" : "none";
}
myCheck2.addEventListener('click', cbChanged);
myCheck.addEventListener('click', cbChanged);
<input type="checkbox" id="check" >
<input type="checkbox" id="check2" checked="checked">
<div id="dib">Text</div>
Notice that the above still binds two event listeners, but to the same function.
Below is a more generic version that uses a container around the checkboxes and their associated div so that you could have multiple copies of that on the page all handled by one event listener wired up with a similar amount of JS to the previous version:
function cbChanged(e) {
const showCB = this.querySelector(".show");
const hideCB = this.querySelector(".hide");
(e.target === hideCB ? showCB : hideCB).checked = !e.target.checked;
this.querySelector("div").style.display = showCB.checked ? "block" : "none";
}
const containers = document.querySelectorAll(".container");
Array.prototype.forEach.call(containers, function(el) {
el.addEventListener('click', cbChanged);
});
<div class="container">
<input type="checkbox" class="hide" >
<input type="checkbox" class="show" checked="checked">
<div>Text One</div>
</div>
<div class="container">
<input type="checkbox" class="hide" >
<input type="checkbox" class="show" checked="checked">
<div>Text Two</div>
</div>
<div class="container">
<input type="checkbox" class="hide" >
<input type="checkbox" class="show" checked="checked">
<div>Text Three</div>
</div>
I am trying to only display the divs that are selected in the checkboxes. This is working fine. I want to make it so that every time the user enters a character in the search box, the list of items is check, so if the user enters "div 4" and all divs are checked, then upon entering the "4", all will disappear except for the substring containing 4.
I want to do this with no submit button, dynamically.
How can I do this?
My code so far is like this :
<html>
<head>
<script type="text/javascript">
<!--
function dynamicSearch() {
document.getElementById('search').value
}
function showMe (it, box) {
var vis = (box.checked) ? "block" : "none";
document.getElementById(it).style.display = vis;
}
//-->
</script>
</head>
<body>
<form>
<label for="search">Search:</label>
<input type="text" name="search" id="search" onkeyup="dynamicSearch()"/>
<input type="checkbox" name="modtype" value="value1" onclick="showMe('div1', this)" />value1
<input type="checkbox" name="modtype" value="value2" onclick="showMe('div2', this)" />value2
<input type="checkbox" name="modtype" value="value3" onclick="showMe('div3', this)" />value3
<input type="checkbox" name="modtype" value="value4" onclick="showMe('div4', this)" />value4
<input type="checkbox" name="modtype" value="value5" onclick="showMe('div5', this)" />value5
<div class="row" id="div1" style="display:none">Show Div 1</div>
<div class="row" id="div2" style="display:none">Show Div 2</div>
<div class="row" id="div3" style="display:none">Show Div 3</div>
<div class="row" id="div4" style="display:none">Show Div 4</div>
<div class="row" id="div5" style="display:none">Show Div 5</div>
</form>
</body>
</html>
Here's something I just hacked together. It needs fleshing out but I think it shows the basic idea.
function dynamicSearch() {
var val = document.getElementById('search').value;
if (val == '')
val = '-1';
var srch = new RegExp(val, "gi");
var els = document.getElementsByClassName('row');
for (var idx in els) {
if (idx != parseInt(idx))
continue;
var el = els[idx];
if (typeof(el.innerHTML) !== 'undefined') {
console.log(el.innerHTML);
if (srch.test(el.innerHTML)) {
el.style.display = 'block';
} else {
el.style.display = 'none';
}
}
}
}
you can make a function, which would watch for document.getElementById('search').value and bind this function to onkeyup event if the search input element.