I have setup a filter list which checkboxes. When the specific checkbox is checked, i need to interact with a class so it hides through JavaScript. Also, if multiple checkboxes are checked, i need to show these items with both the classes. I have this:
HTML:
<div class="categs" id="filters">
<div class="categhead">
<p>Ranking</p>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagchallenger" value="challenger" style="display: none;">
<label for="tagchallenger">Challenger</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagmaster" value="master" style="display: none;">
<label for="tagmaster">Master | Diamond</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagplat" value="plat" style="display: none;">
<label for="tagplat">Platinum | Gold</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagsilver" value="silver" style="display: none;">
<label for="tagsilver">Silver | Bronze</label>
</div>
<script type="text/javascript">
[].forEach.call(document.querySelectorAll('.hide-checkbox'), function(element) {
element.style.display = 'none';
});
</script>
</div>
JavaScript:
var streameach = $('.streampic .row .col-md-4');
function updateContentVisibility(){
var checked = $('#filters :checkbox:checked');
if(checked.length){
streameach.hide();
checked.each(function() {
$("." + $(this).val()).show();
});
} else {
streameach.show();
}
}
$('#filters :checkbox').click(updateContentVisibility);
updateContentVisibility();
}
And then i also have
<div class="streamtag1">...</div>
And
var stream0 = "<? echo $lolarray->streams[0]->channel->name; ?>";
if (stream0 == "riotgames") {
$('streamtag1').addClass('master');
};
Now when the checkbox 'master' is clicked, it hides all the divs, but doesn't show the ones that have the added master class,which should be connected to that checkbox.
I would set it up like the below:
Here's a jsFiddle
function updateContentVisibility() {
$('.hide-checkbox').each(function () {
if ($(this).is(':checked')) {
$('.' + $(this).val()).hide();
} else $('.' + $(this).val()).show();
});
}
$('.hide-checkbox').change(function () {
updateContentVisibility();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagriot" value="riot">
<label for="tagriot">RIOT</label>
<input class="hide-checkbox" type="checkbox" id="tagblue" value="blue">
<label for="tagblue">blue</label>
<input class="hide-checkbox" type="checkbox" id="taggreen" value="green">
<label for="taggreen">green</label>
<input class="hide-checkbox" type="checkbox" id="tagred" value="red">
<label for="tagred">red</label>
</div>
<div class="riot">riot</div>
<br>
<div class="blue">blue</div>
<br>
<div class="green">green</div>
<br>
<div class="red">red</div>
<br>
Given the question description, and some clarification in the comments to that question, I'd suggest the following approach, using jQuery:
// selecting the <input> elements of class-name 'hide-checkbox',
// binding an anonymous function to handle the 'change' event:
$('input.hide-checkbox').on('change', function () {
// selecting all elements whose class-name is equal to the
// <input> element's value, and using the toggle(switch)
// approach, to show if the switch is true (the checkbox is checked)
// and hide if the switch is false (the checkbox is unchecked):
$('.' + this.value).toggle(this.checked);
// triggering the change event, so that the function runs on page-load,
// to hide/show as appropriate:
}).change();
[].forEach.call(document.querySelectorAll('.hide-checkbox'), function(element) {
element.style.display = 'none';
});
$('input.hide-checkbox').on('change', function() {
$('.' + this.value).toggle(this.checked);
}).change();
label {
cursor: pointer;
}
input:checked + label {
color: #f90;
}
#contents div[class] {
border: 1px solid #000;
border-radius: 1em;
padding: 0.5em;
margin: 0 auto 0.5em auto;
width: 80%;
}
#contents div[class]::before {
content: attr(class);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="categs" id="filters">
<div class="categhead">
<p>Ranking</p>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagchallenger" value="challenger" style="display: none;" />
<label for="tagchallenger">Challenger</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagmaster" value="master" style="display: none;" />
<label for="tagmaster">Master | Diamond</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagplat" value="plat" style="display: none;" />
<label for="tagplat">Platinum | Gold</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagsilver" value="silver" style="display: none;" />
<label for="tagsilver">Silver | Bronze</label>
</div>
</div>
<div id="contents">
<div class="challenger"></div>
<div class="master"></div>
<div class="plat"></div>
<div class="silver"></div>
</div>
External JS Fiddle demo, for experiementation.
Or, with plain JavaScript:
// creating a named function to handle the show/hide functionality:
function toggleView() {
// a cached reference to the changed <input>:
var control = this,
// a reference to whether the <input> is checked or not:
check = control.checked,
// retrieving all elements with a class-name equal to the
// <input> element's value:
targets = document.querySelectorAll('.' + control.value);
// using Array.prototype.forEach(), with Function.prototype.call(),
// to iterate over the found elements:
Array.prototype.forEach.call(targets, function (node) {
// setting the display property of each found-element's
// style property; if the checkbox is checked we set
// the display to 'block', if not we set it to 'none':
node.style.display = check ? 'block' : 'none';
});
}
// creating a 'change' event so that we can trigger the function
// to run on page-load:
var changeEvent = new Event('change');
// As above, iterating over the '.hide-checkbox' elements:
Array.prototype.forEach.call(document.querySelectorAll('.hide-checkbox'), function (element) {
// hiding the elements:
element.style.display = 'none';
// binding the named function (toggleView)
// to handle the change event:
element.addEventListener('change', toggleView);
// triggering the change event on each of the
// '.hide-checkbox' elements:
element.dispatchEvent(changeEvent);
});
function toggleView() {
var control = this,
check = control.checked,
targets = document.querySelectorAll('.' + control.value);
Array.prototype.forEach.call(targets, function (node) {
node.style.display = check ? 'block' : 'none';
});
}
var changeEvent = new Event('change');
Array.prototype.forEach.call(document.querySelectorAll('.hide-checkbox'), function (element) {
element.style.display = 'none';
element.addEventListener('change', toggleView);
element.dispatchEvent(changeEvent);
});
label {
cursor: pointer;
}
input:checked + label {
color: #f90;
}
#contents div[class] {
border: 1px solid #000;
border-radius: 1em;
padding: 0.5em;
margin: 0 auto 0.5em auto;
width: 80%;
}
#contents div[class]::before {
content: attr(class);
}
<div class="categs" id="filters">
<div class="categhead">
<p>Ranking</p>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagchallenger" value="challenger" style="display: none;" />
<label for="tagchallenger">Challenger</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagmaster" value="master" style="display: none;" />
<label for="tagmaster">Master | Diamond</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagplat" value="plat" style="display: none;" />
<label for="tagplat">Platinum | Gold</label>
</div>
<div class="categsort">
<input class="hide-checkbox" type="checkbox" id="tagsilver" value="silver" style="display: none;" />
<label for="tagsilver">Silver | Bronze</label>
</div>
</div>
<div id="contents">
<div class="challenger"></div>
<div class="master"></div>
<div class="plat"></div>
<div class="silver"></div>
</div>
External JS Fiddle demmo for experiementation/development.
References:
JavaScript:
Array.prototype.forEach().
document.querySelectorAll().
Event() constructor.
EventTarget.addEventListener().
Event.target.dispatchEvent().
Function.prototype.call().
jQuery:
change().
on().
toggle().
Related
Creating Dynamic new fields seems to clear the already existing fields
Also not trying to have multiple elements with the same id hence why i don't believe appendChild will work. Perhaps you can find a way to do that while creating different IDs?
Any help welcomed =)
var template;
var a = 1;
window.onload = function() {
template = document.querySelector("#wrapper").innerHTML;
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault(); // tell the browser to not send the form
document.getElementById('wrapper').innerHTML += template; // add next segment
document.querySelector("#wrapper > label:last-of-type").innerHTML = "Segment " + (++a) + ":";
});
}
.form-group {
display: inline
}
#wrapper > label {
margin: 0 0 10px 210px;
}
.segment {
display: inline-block;
margin: 0 0 1em
}
.form-group > label {
margin: 0 0 10px 20px;
}
.form-group > input {
width: 15%
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
innerHTML will not include the current value entered IIRC but it's still strange that doing += operation will remove the existing value.
However, insertAdjacentHTML() should work as expected.
var template;
var a = 1;
window.onload = function() {
template = document.querySelector("#wrapper").innerHTML;
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault(); // tell the browser to not send the form
document.getElementById('wrapper').insertAdjacentHTML('beforeend', template); // add next segment
document.querySelector("#wrapper > label:last-of-type").innerHTML = "Segment " + (++a) + ":";
});
}
.form-group {
display: inline
}
#wrapper > label {
margin: 0 0 10px 210px;
}
.segment {
display: inline-block;
margin: 0 0 1em
}
.form-group > label {
margin: 0 0 10px 20px;
}
.form-group > input {
width: 15%
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
Basically, my below code is not 100% correct, you should alter it by yourself following mine.
In the HTML, you can define a hidden div which is your wrapper. In its and nested element ids, you can set a pattern like '$$$'.
<div class="content" id="wrapper$$$" sytle="visibility: hidden;">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
In your javascript, declare a global variable named index and replace index value with '$$$'. It will be increased 1 when you add your template dynamically.
template = document.querySelector("#wrapper").innerHTML;
template = template.replace('$$$', index);
index ++;
...
Problem:
The problem here is with using innerHTML, because innerHTML will always override the HTML of your elements so previously typed values will be cleared, that's why you should use .appendChild().
And your logic for dynamic is correct, you just need to chnage the way you add new fields.
Solution:
I tried to rewrite your code so it uses appendChild() in a smart way using the #wrapper innerHTML as template and updating the id dynamically in the new appended fields.
var template = document.querySelector("#wrapper").innerHTML;
function addFields() {
var wrapper = document.createElement("div");
wrapper.innerHTML = template;
wrapper.querySelector("label:last-of-type").innerHTML = "Segment " + (++a) + ":";
document.getElementById('wrapper').appendChild(wrapper);
}
This code will create a new div everytime, wher we put the template HTML inside it, update the label dynamically referring the label inside our current wrapper div using wrapper.querySelector("label:last-of-type"), then finally append this new div to our element.
Demo:
Here's a working Demo snippet:
var template = document.querySelector("#wrapper").innerHTML;
var a = 1;
function addFields() {
var wrapper = document.createElement("div");
wrapper.innerHTML = template;
wrapper.querySelector("label:last-of-type").innerHTML = "Segment " + (++a) + ":";
document.getElementById('wrapper').appendChild(wrapper);
}
window.onload = function() {
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault();
addFields();
});
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
SOLVED - Thank you all for your time
I'm having a little trouble getting this one right. Basically I have two radio buttons with different values and I need to add and remove the class "active" from div's that pertain to the value of the radio button. See my code below:
HTML:
<li class="field">
<label>choose option:</label>
<label class="radio toggle" gumby-trigger="#phone" for="phoneOrWeb">
<input name="phoneOrWeb" id="phoneOrWeb" value="phone" type="radio">
<span></span> <strong>Phone</strong>
</label>
<label class="radio toggle" gumby-trigger="#web" for="phoneOrWeb">
<input name="phoneOrWeb" id="phoneOrWeb" value="web" type="radio">
<span></span> <strong>Web</strong>
</label>
</li>
<!-- Phone SUB -->
<div class="drawer" id="phone">
<?php include ('formD.php'); ?>
</div>
<!-- /Phone SUB -->
<!-- WEB SUB -->
<div class="drawer" id="web">
<?php include ('formE.php'); ?>
</div>
<!-- /WEB SUB -->
Jquery I attempted:
$("input[name=phoneOrWeb]:radio").click(function () {
if ($('input[name=phoneOrWeb]:checked').val() == "phone") {
$('#web').removeClass('active');
$('#phone').addClass('active');
} else if ($('input[name=phoneOrWeb]:checked').val() == "web") {
$('#web').addClass('active');
$('#phone').removeClass('active');
}
});
Your code is very close. First of all, IDs should always be unique. One element per ID on a page. phoneOrWeb is used twice which is not good. Secondly, if you don't want to do a second jQuery selection, you can just grab the value from the target of the event. This code should work as you expected.
$("input[name=phoneOrWeb]:radio").click(function(ev) {
if (ev.currentTarget.value == "phone") {
$('#web').removeClass('active');
$('#phone').addClass('active');
} else if (ev.currentTarget.value == "web") {
$('#web').addClass('active');
$('#phone').removeClass('active');
}
});
.drawer {
width: 100px;
height: 100px;
background-color: green;
margin: 4px;
}
.drawer.active {
border: 3px solid red;
margin: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="field">
<label>choose option:</label>
<label class="radio toggle" gumby-trigger="#phone" for="phoneInput">
<input name="phoneOrWeb" id="phoneInput" value="phone" type="radio">
<span></span> <strong>Phone</strong>
</label>
<label class="radio toggle" gumby-trigger="#web" for="webInput">
<input name="phoneOrWeb" id="webInput" value="web" type="radio">
<span></span> <strong>Web</strong>
</label>
</li>
<!-- Phone SUB -->
<div class="drawer" id="phone">
Phone!
<!--<?php include ('formD.php'); ?>-->
</div>
<!-- /Phone SUB -->
<!-- WEB SUB -->
<div class="drawer" id="web">
Web!
<!--<?php include ('formE.php'); ?>-->
</div>
<!-- /WEB SUB -->
$("input[name=phoneOrWeb]:radio").change(function () {
if ($(this).val() == "phone") {
$('#web').removeClass('active');
$('#phone').addClass('active');
} else if ($(this).val() == "web") {
$('#web').addClass('active');
$('#phone').removeClass('active');
}
});
Use the change event on the input. The below works.
$("input[name=phoneOrWeb]").change(function () {
if (this.value == "phone") {
$('#web').removeClass('active');
$('#phone').addClass('active');
} else if (this.value == "web") {
$('#web').addClass('active');
$('#phone').removeClass('active');
}
});
Fiddle: https://jsfiddle.net/04uhjuvc/
PS: ids should be unique, you have the same id in both the radio buttons.
You shoud check this one.
How to use radio on change event?
$(document).ready(function() {
$('input[type=radio][name=bedStatus]').change(function() {
if (this.value == 'allot') {
alert("Allot Thai Gayo Bhai");
}
else if (this.value == 'transfer') {
alert("Transfer Thai Gayo");
}
});
});
This depends that the Values of your Radios are equal to the target-element IDs:
$(".radio.toggle").on("click", function() {
$(".drawer").removeClass("active");
$("#"+$(this).val()).addClass("active");
});
You can make use of JQuery toggleClass for this to make it more simple:
$("input[name=phoneOrWeb]:radio").click(function () {
if (this.value == "phone")) {
$('#phone').toggleClass( "active" );
} else if (this.value == "web")) {
$('#web').toggleClass( "active" );
}
});
Try this:
<li class="field">
<label>choose option:</label>
<label class="radio toggle" gumby-trigger="#phone" for="phone-option">
<input id="phone-option" name="phoneOrWeb" value="phone" type="radio">
<span></span> <strong>Phone</strong>
</label>
<label class="radio toggle" gumby-trigger="#web" for="web-option">
<input id="web-option" name="phoneOrWeb" value="web" type="radio">
<span></span> <strong>Web</strong>
</label>
</li>
<div class="drawer" id="phone">phone</div>
<div class="drawer" id="web">web</div>
jQuery script:
<script>
$(document).ready(function () {
$('#phone-option').click(function () {
$('#web').removeClass("active");
$('#phone').addClass("active");
});
$('#web-option').click(function () {
$('#phone').removeClass("active");
$('#web').addClass("active");
});
});
</script>
Alright, I've gone through lot of sources but I've got confused applying them all. I'm new to javascript and jquery.
I have a step by step choices (i got a wizard template). So I wanted to display a text field from the previous step/div when "wedding" radio button is checked.
my html code:
<div id="step-1">
<fieldset>
<input type="radio" id="theme1" name="cake_theme" value="wedding" onchange="see()" />
<input type="radio" id="theme2" name="cake_theme" value="bday" onchange="see()" />
<input type="radio" id="theme3" name="cake_theme" value="occassion" onchange="see()" />
</fieldset>
</div>
<div id="step-2">
Date: <input type="date" name="date_pick"/> //remains
<div class="wed_delivery"> Venue : <input type="text" name="wed_delivery" placeholder="Venue to Delivery"/> //only shows up when "wedding button" is checked
</div>
</div>
<div id="themedisplay" height="100px" width="300px"> </div>
I have in my JS in different file: (working fine)
function see(){
var canvas = document.getElementById('displaycake');
if (document.getElementById('theme1').checked) {
document.getElementById('themedisplay').innerHTML = "Wedding Cake";
}
if (document.getElementById('theme2').checked) {
document.getElementById('themedisplay').innerHTML = "Birthday Cake";
}
if (document.getElementById('theme3').checked) {
document.getElementById('themedisplay').innerHTML = "Occassion Cake";
}
}
I tried putting below the div "step-1"
<script>
$(document).ready(function () {
$(".wed_delivery").hide();
$("#theme1").click(function () { //theme1 is the Wedding Theme
$(".wed_delivery").show();
});
</script>
It doesn't work, is it possible in a Wizard Template?
Thanks in advance, comments each line are appreciated.
This will help you. Point to note.
1: Close your document.ready function properly.
2: Include JQuery if not included.
3: Bind the event with radio buttons and hide/show the text box if the checked radio is/is not wedding radio button
function see(){
var canvas = document.getElementById('displaycake');
if (document.getElementById('theme1').checked) {
document.getElementById('themedisplay').innerHTML = "Wedding Cake";}
if (document.getElementById('theme2').checked) {
document.getElementById('themedisplay').innerHTML = "Birthday Cake";}
if (document.getElementById('theme3').checked) {
document.getElementById('themedisplay').innerHTML = "Occassion Cake";}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="step-1">
<fieldset>
<input type="radio" id="theme1" name="cake_theme" value="wedding" onchange="see()" />
<input type="radio" id="theme2" name="cake_theme" value="bday" onchange="see()" />
<input type="radio" id="theme3" name="cake_theme" value="occassion" onchange="see()" /> </fieldset> </div>
<div id="step-2">
Date: <input type="date" name="date_pick"/> //remains
<div class="wed_delivery"> Venue : <input type="text" name="wed_delivery" placeholder="Venue to Delivery"/> //only shows up when "wedding button" is checked </div>
</div>
<div id="themedisplay" height="100px" width="300px"> </div>
<script>
$(document).ready(function () {
$(".wed_delivery").hide();
$("input[type='radio']").click(function () { //theme1 is the Wedding Theme
if($(this).val() == "wedding")
{
$(".wed_delivery").show();
}
else
{
$(".wed_delivery").hide();
}
});
});
</script>
Establish 2 classes to represent the status of off and on and assign the textbox the .off class initially. When the change event is triggered, then use .addClass() and .removeClass() jQuery methods.
There are too many changes to OP to explain, so I commented details in the Snippet:
SNIPPET
/* Shorthand for $(document).ready(function() { */
$(function() {
/* change event triggered by any radio button */
$(':radio').on('change', function() {
/* $(this) is the function owner,
| in this case it is the specific
| radio button being changed
*/
// Get radio value
var title = $(this).val();
// Get radio data-img
var img = $(this).data('img');
// Get url of background-image
var path = 'http://imgh.us/' + img;
// Set text of figcaption
$('#themeTitle').text(title);
// Set background-image of figure
$('#themeDisplay').css('background', 'url(' + path + ')no-repeat');
// if the checked radio id is 'theme1'...
if ($(this).attr('id') === 'theme1') {
//...status of textbox is on...
$('.wedDelivery').addClass('on').removeClass('off');
} else {
//...otherwise status of textbox is off
$('.wedDelivery').removeClass('on').addClass('off');
}
});
});
.off {
display: none;
}
.on {
display: inline-block;
}
#themeDisplay {
width: 300px;
height: 100px;
}
#themeTitle {
font: 700 16px/1.4 cursive;
color: black;
background: rgba(255, 255, 255, .6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id='step1'>
<legend>Event Themes</legend>
<!--data-img represents the image file name can be manipulated by .attr() or .data()-->
<label>Wedding
<input type="radio" id="theme1" name="cakeTheme" value="Wedding" data-img='wedcake.jpg'>
</label>
<label>Birthday
<input type="radio" id="theme2" name="cakeTheme" value="Birthday" data-img='bdaycake.jpg'>
</label>
<label>Special Occasion
<input type="radio" id="theme3" name="cakeTheme" value="Special Occasion" data-img='speccake.jpg'>
</label>
</fieldset>
<fieldset id="step2">
<legend>Pick-up/Delivery</legend>
<label>Date:
<input type="date" name="datePick">
</label>
<label class='wedDelivery off'>Venue :
<input type="text" name="wedDelivery" placeholder="Venue to Delivery">
</label>
</fieldset>
<figure id="themeDisplay">
<figcaption id='themeTitle'></figcaption>
</figure>
I'm trying to write some JavaScript that could be used throughout my app, and allow a checkbox to show/hide a nearby element.
If I have these elements:
<div class="optionable" style="display: block;">
<div class="row">
<div class="col-md-2">
<input checked="checked" class="form-control"
data-val="true" id="IsActive"
name="IsActive"
onclick="CheckboxOptionsToggle(this);"
type="checkbox" value="true">
</div>
<div class="col-md-8">
Chapter
</div>
</div>
<div class="row options">
<div class="col-md-12">
Some data here...
</div>
</div>
</div>
And this script:
CheckboxOptionsToggle = function (thisCheckbox) {
debugger;
var optionElement = $('.options');
if (thisCheckbox.checked) {
$(thisCheckbox).closest(optionElement).show();
} else {
$(thisCheckbox).closest(optionElement).hide();
}
}
But this isn't working. I would like the checkbox with the onclick="CheckboxOptionsToggle(this);" to trigger the options element in the same optionable div to either show or hide.
What am I doing wrong in my JavaScript/jQuery?
UPDATE: This is my final solution:
$('.optionToggle').on('change', function () {
$(this).closest('.optionable').find('.options').toggle(this.checked);
});
$(document).ready(function () {
var toggleElements = document.body.getElementsByClassName('optionToggle');
for (var i = 0; i < toggleElements.length; i++) {
var thisCheck = $(toggleElements[i]);
thisCheck.closest('.optionable').find('.options').toggle(thisCheck.prop('checked'));
}
});
<div class="optionable" style="display: block;">
<div class="row">
<div class="col-md-2">
<input checked="checked" class="form-control optionToggle"
data-val="true" id="IsActive"
name="IsActive"
type="checkbox" value="true">
</div>
<div class="col-md-8">
Chapter
</div>
</div>
<div class="row options">
<div class="col-md-12">
Some data here...
</div>
</div>
</div>
Be more generic, and stop using inline event handlers
$('[type="checkbox"]').on('change', function() { // or use class to not attach to all
$(this).closest('.optionable').find('.options').toggle(this.checked);
}).trigger('change');
FIDDLE
You can change it like
CheckboxOptionsToggle = function (thisCheckbox) {
debugger;
var optionElement = $('.options');
if (thisCheckbox.checked) {
$(thisCheckbox)..closest('div.optionable').find(optionElement).show();
} else {
$(thisCheckbox)..closest('div.optionable').find(optionElement).hide();
}
}
I would stay away from .closes, because it is so specific, instead I would go with more reusable code like so:
HTML:
<input type="checkbox" id="toggler" data-target-class="some-div" class="toggler" value="myValue" checked> Toggle Me
<div class="some-div">
Some Text within the div.
</div>
JS:
$('#toggler').on('click', function() {
var targetClass = $(this).data('target-class');
$('.' + targetClass).toggle($(this).checked);
});
JSFiddler: https://jsfiddle.net/ro17nvbL/
I am using data element on the checkbox to specifiy which divs to show or hide. This allows me to not only hide/show divs but anything n the page, and not only one instance but as many as needed. Way more flexible - still does the same job.
I have 6 divs with a checkbox each. When I click the delete button the div with the checked checkbox should be deleted. However the deletion is working in an unpredictable way.Here is my jsfiddle. http://jsfiddle.net/mftckzaL/ . Please help!
<div class="0" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="1" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="2" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="3" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="4" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="5" id="res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-
radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<input type="button" value="Delete Selection" name="delete_banner_art" id="delete_banner_art"
class="delete_banner_art">
My JavaScript:
$("#delete_banner_art").click(function () {
checkboxes = document.getElementsByName('resolution');
for (var i = (checkboxes.length - 1); i >= 0; i--) {
if (checkboxes[i].checked == true) {
$("." + i).remove();
}
}
});
If you're using jQuery, use jQuery, and employ its selectors, rather than mixing and matching (badly). To simplify your code (invalid HTML aside), I'd suggest:
$("#delete_banner_art").click(function () {
// we find the inputs of type="checkbox", that are checked:
$('input[type="checkbox"]:checked')
// find the closest ancestor 'div' element:
.closest('div')
// and remove those div elements:
.remove();
});
JS Fiddle demo.
References:
Attribute-equals ([attribute="value"]) selector.
closest().
The ids should be unique, also the for loop should go to i > 0 not i >= 0
http://jsfiddle.net/mftckzaL/2/
for (var i = (checkboxes.length - 1); i > 0; i--) {
if (checkboxes[i].checked == true) {
$("." + i).remove();
}
}
Here is a better way to delete the selected item
http://jsfiddle.net/mftckzaL/5/
$("#delete_banner_art").click(function () {
$('input[type="checkbox"]:checked').parents('div').remove();
});
here
for (var i = (checkboxes.length - 1); i >= 0; i--) {
if (checkboxes[i].checked == true) {
$("." + i).remove();
}
}
when you remove a div, you do not change the classes of the other ones, but the increment is updated to the current number of checkboxes.
you'll be able to remove them all starting from the end up, but it will seem unpredictable if you remove one in the list
See the fixed JSFiddle here:
http://jsfiddle.net/mftckzaL/9/
HTML:
<div class="0 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution" />
</div>
<div class="1 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution" />
</div>
<div class="2 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution" />
</div>
<div class="3 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="4 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<div class="5 res1" style="border:1.5px solid #a1a1a1;width:900px;height:127;border-radius:5px;padding:5px 10px;">
<input type="checkbox" value="res1" name="resolution">
</div>
<input type="button" value="Delete Selection" name="delete_banner_art" id="delete_banner_art" class="delete_banner_art">
JS:
$("#delete_banner_art").click(function () {
$('.res1').children('input:checked').parent().remove();
});
A couple of things however,
In the HTML, I changed the repeated id attributes to classes. ID's by nature, are unique and having more than one on a page may cause problems in the future.
I don't think classes can start with a number.
Pure JS(not any longer)
// this does not have to be resolved every time you click
var checkboxes = document.getElementsByName('resolution');
document.getElementById("delete_banner_art").onclick =function () {
for (var i=0, l=checkboxes.length; i<l; i++) {
// "condition" is equivalent to "condition == true"
if (checkboxes[i].checked) { checkboxes[i].parentNode.remove(); }
}
};
JS Fiddle Demo