Automatically check parent when child is checked [duplicate] - javascript

This question already has answers here:
jquery, find next element by class
(5 answers)
Closed 6 years ago.
When any checkbox with class .child-term is checked, I automatically need to check the preceding checkbox with class .parent-term.
I only want to check the preceding .parent-term class not all the checkboxes that have .parent-class. Same goes for the .child-term class. Any checkbox with .child-term only affects the .parent-term above.
If the .parent-term class was checked from a .sub-term checkbox the .parent-term can remain checked when all the associated .sub-term boxes are unchecked.
I have tried various solutions, but I can't figure it out.
I started a jsfiddle.
<ul class="cpt-terms-checkbox">
<li class="parent-term church" id="category-church"><input id="church"
name="church" type="checkbox" value="church">Church</li>
<li><small>Sub Categories:</small></li>
<li class="child-term elder" id="category-elder"><input id="elder"
name="elder" type="checkbox" value="elder">Elder</li>
<li class="child-term interim-pastor" id="category-interim-pastor">
<input id="interim-pastor" name="interim-pastor" type="checkbox" value=
"interim-pastor">Interim Pastor</li>
<li class="parent-term law-firm" id="category-law-firm"><input id=
"law-firm" name="law-firm" type="checkbox" value="law-firm">Law
Firm</li>
<li><small>Sub Categories:</small></li>
<li class="child-term attorney" id="category-attorney"><input id=
"attorney" name="attorney" type="checkbox" value=
"attorney">Attorney</li>
<li class="child-term attorney" id="category-attorney"><input id=
"attorney" name="attorney" type="checkbox" value=
"attorney">Paralegal</li>
</ul>
Adding to Anoop Joshi's solution . . . I changed .parent() to .parents() so it would move up higher and for those who may run this in Wordpress I wrapped it in an anonymous function.
(function($) {
$(".child-term :input").change(function() {
if (this.checked) {
$(this).parents().prevAll(".parent-term:first").find("input").prop("checked", true);
}
});
})( jQuery );

Use prevAll() to get all the previous nodes with specified selector.
Then you can use the :first selector to get the immediate previous element
$(".child-term :input").change(function() {
if (this.checked) {
$(this).parent().prevAll(".parent-term:first").find("input").prop("checked", true);
}
});
Fiddle

Related

Css selector : how to select elements with certain class name

I have an idea to add a dynamic css style by changing my label and make my input elements show differently when item.areaNo changes. I successfully gave my label element class='1', but css class did not understand my selector.I really need to know how to set the correct one.
<ol class="cabin fuselage">
<li class="row row--1">
<ol class="seats" type="A">
<li class="seat"><input type="checkbox" id="01-01" />
<label for="01-01">01-01</label></li>
<li class="seat"><input type="checkbox" id="02-01" /> <label
for="02-01">02-01</label></li>
this is my jsp,
.seat label.1{background: #50bdc9;}
and my css,
both reference to https://codepen.io/siiron/pen/MYXZWg BY Ronny Siikaluoma
$.getJSON("gametransfer.controller", function(json) {
$.each(Object.values(json), function(i, item) {
console.log(item)
var aa = '#' + item.seatNo;
if ($('.seat>input').is(aa)) {
if (item.attr == true) {
$(aa).prop('disabled', true);
}
$(aa).siblings('label').addClass('1');
}/*end of outer if */
});
});
solved :all of those attempts failed and return with all of the item.areaNo in first label elements.
You need find no. of a child (li.seat) then you can use for loop then find label one by one and put different CSS for each label. I hope it's work.

Remove "checked" from radio when a checkbox is unchecked

I have a checkbox (#FBmngCH) that reveals a set of radio buttons (name=adManage) when clicked. When the checkbox is unclicked, the radio button that was previously selected still remains checked. I would like to have the checked status of the radio button removed once the checkbox is unchecked.
This is being used in a form, so if the user changes their mind about selecting that service, I would like the details about that service to be wiped also (so the value of the selected radio will not end up in the PHP and ultimately the email). I hope this makes sense.
I have given this some considerable time and am not seeming to get this to work correctly. The last set of if-statements is the part of the code that I wrote. Not sure if I am missing something, selecting something wrong, or what. Any help with this would be highly appreciated. Thanks!
HTML
<li>
<input type="checkbox" class="cbox" name="FBchecks[]" value="Facebook Ad MGMT" id="FBmngCH">
<label for="test">Facebook Ad Management</label>
<ul id="FBmngList">
<li>
<input type="radio" name="adManage" value="Ad Management 1" id="adMan1">
<label for="adMan1">Ad Fund - 1</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 2" id="adMan2">
<label for="adMan2">Ad Fund - 2</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 3" id="adMan3">
<label for="adMan3">Ad Fund - 3</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 4" id="adMan4">
<label for="adMan4">Ad Fund - 4</label>
</li>
<div id="FBADerror" class="acctError"></div>
</ul>
</li>
JS
$FBmngCH = $("#FBmngCH");
$FBmngList = $("#FBmngList");
//hide FB Management List
$FBmngList.hide();
//on FB Management select
$FBmngCH.click(function() {
//toggle FB Management List
$FBmngList.toggle();
});
$FBadValid = false;
$FBADerror = $("#FBADerror");
//if FB Ad Management is checked
if ($FBmngCH.attr('checked')) function validateFB() {
$("input[name=adManage]").each(function () { //LoopingthroughradioButtons
// "this" is the current element(radio) in the loop
if ($(this).is(':checked')) {
$FBadValid = true; //Radio Button is Checked);
}
if ($FBadValid.attr = true ) {
$FBADerror.empty();
}
});
};
if ($FBmngCH.blur($FBadValid.attr = false)) {
$FBADerror.append("<li> Please select a Facebook Ad plan. </li>");
//appends error to document
}
if ($FBmngCH.blur($FBmngCH.not('checked'))) {
$("input[name=adManage]").each(function () {
if ($(this).is(':checked')) {
$("input[name=adManage]").removeAttr('checked');
}
});
//remove checks from radios
};
$("input[name=adManage]").click(validateFB);
Maybe I am not understanding your requirements, but can't you just test for this in your checkbox event routine and uncheck the checked radio button:
$FBmngCH.click(function () {
//toggle FB Management List
$FBmngList.toggle();
if (!$FBmngList.attr('checked')) {
$FBmngList.find('input:checked').attr('checked', false);
}
});
See this Fiddle.
You have few errors in your code:
if ($FBmngCH.blur($FBadValid.attr = false)) {
This is not correct syntax. It should be:
$FBmngCH.blur(function(){
if ($FBadValid === false) {
}
});
Basically, since your're toggling the whole radios section and willing to remove their :checked property without checking any conditions, you do not need for loops or if($(this).is(':checked')) statements. Just remove :checked propery from all the radios. You can also show the error message on each check-box click, without if conditions, because the whole section is hidden anyways.
You should end up with very short code, like this:
$FBmngCH = $("#FBmngCH");
$FBmngList = $("#FBmngList").hide();
$FBADerror = $("#FBADerror");
$FBmngCH.click(function() {
// no need for loops and if's there. Radios and the message are hidden.
$FBmngList.toggle();
$FBADerror.html("<li> Please select a Facebook Ad plan. </li>");
$("input[name=adManage]").prop('checked', false);
});
$("input[name=adManage]").click(function(){
// no need for loops there. Radios and the message are hidden.
// Also, no need for if($(this).is(':checked')){. Since it's a click handler, something has to be :checked on radio click.
$FBADerror.empty();
});
DEMO

detecting if a checkbox is ticked inside a target div with jQuery

I have the following markup, below the closing span tag is a number list items.
<div class="header_block">
<span class="background_flag_container">
<input id="block_background" type="checkbox" name="block_background">
<span class="background_flag_text">Has Banner Background</span>
</span>
...
</div>
This is my jQuery. What I am looking to do is check if the one and only checkbox, with a name of 'block_background' is checked. There are a number of 'block_background' checkboxes on the page, but there will only ever be one within $(this) which is the .header_block div.
$(this).find(".background_flag_container input:checkbox[name='block_background']").each(function(){
if ($(this).checked) {
console.log('is checked');
}
});
How can I check if it's checked?
You can use is(':checked') to check if something is selected
$(this).find(".background_flag_container input:checkbox[name='block_background']").each(function(){
if ($(this).is(':checked')) {
console.log('is checked');
}
});
Although seeing that the checkbox has the id block_background which should be unique. You could just do this:
if ($('#block_background').is(':checked')) {
console.log('is checked');
}
$("input#block_background]").is(':checked')

input:radio click function isn't triggering in IE / Firefox

I have a form with multiple inputs / radio buttons.
I also have a series of Yes & No radio buttons. When the "Yes" radio button is checked, I have some data slide down beneath.
HTML:
<div class="item seperator first clearfix">
<label>test</label>
<div class="radioWrap">
<label class="yes">
<input class="homepageContent" name="homepageContent" type="radio" value="yes" />
</label>
<label class="no">
<input class="homepageContent" name="homepageContent" type="radio" value="no" checked />
</label>
</div>
</div>
<div class="extrasInner">
<div class="item clearfix">
<label for="theContent">Your Content:</label>
<textarea id="theContent" name="theContent"></textarea>
</div>
</div>
<div class="extrasOuter hide clearfix">
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
The jQuery:
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parent().parent().parent().next().slideDown();
$(this).parent().parent().parent().next().next().slideDown();
} else {
$(this).parent().parent().parent().next().slideUp();
$(this).parent().parent().parent().next().next().slideUp();
}
});
Question 1) This works absolutely fine in Google Chrome, but not in Firefox and IE. It doesn't seem to recognise the click function?
Solved: I had a function within one of my files that removes the value from input fields on focus and this was stripping the value of the radio buttons as well in IE / Firefox (but not chrome!).
Question 2) Is my DOM traversing for the slideUp / slideDown an acceptable way of achieving what I'm trying to do? Are there any disadvantages to how I'm doing it and can it be improved?
Answer to #1
As Anthony Grist pointed out, there doesn't seem to be an issue with the click function.
Answer to #2
Your DOM traversal seem a bit unnecessary. In fact, your DOM structure is in need of rearrangement.
Using a checkbox instead of radio buttons. A checkbox only accepts two values: true or false, or in your case, yes or no. It seems more suitable.
Encapsulate your extras inner and extras outer divs inside your item div instead of having it next to the checkbox. This way, you make it easier to traverse within the item.
Also, you should read up on the different types of traverse functions JQuery has:
.parent() / .parents()
.children()
.closest()
.next()
.prev()
.siblings()
.find()
and many more.
Knowing all of these traverse functions, you'll most likely never ever do parent().parent().parent()... again. :)
Here's a JSFiddle example | Code
HTML
<ul>
<li class='item'>
<label>
<input class="homepageContent" name="homepageContent" type="checkbox" value="yes" />
Item 1
</label>
<div class='extras'>
<div class='inner'>
<label>
Your Content:<textarea name="content"></textarea>
</label>
</div>
<div class='outer'>
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
</div>
</li>
</ul>
Javascript
$("input:checkbox").click(function() {
var $this = $(this),
$item = $(this).closest(".item");
if($this.is(':checked')){
$(".extras", $item).slideDown();
}else{
$(".extras", $item).slideUp();
}
});
CSS
.extras{
display: none;
}
Value of the radio button will always be same, no matter it is checked or not. If you want to know the particular radio button is checked or not then use this code. Based on the status of the radio button do your stuff.
var value = $(this).attr('checked')
That is working for me in FF (jsfiddle), although the DOM looks a little convoluted (I'm guessing because it's missing a lot of your other CSS/resources).
I think you can simplify the jQuery selectors a lot. Generally, using simple ID or class selectors will make the your page much more performant (and simpler!)
$('.homepageContent').click(function() {
var value = $(this).val();
if (value == 'yes') {
$('.extrasInner').slideDown();
$('.extrasOuter').slideDown();
} else {
$('.extrasInner').slideUp();
$('.extrasOuter').slideUp();
}
});
Hopefully doing something like this makes it work cross browser better too.
try this way
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
EDIT
​
and also a point
wrap your code inside
$(document).ready(function(){});
like this
$(document).ready(function(){
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
});

Checkboxes + Jquery hide/show

I have a series of a series of rows and checkboxes to filter them:
<ul>
<li><input id="type-A" type="checkbox" checked="checked"> A</li>
<li><input id="type-B" type="checkbox" checked="checked"> B</li>
<li><input id="type-C" type="checkbox" checked="checked"> C</li>
<li><input id="type-D" type="checkbox" checked="checked"> D</li>
<li><input id="type-E" type="checkbox" checked="checked"> E</li>
<li><input id="type-F" type="checkbox" checked="checked"> F</li>
</ul>
<table>
<tr class="A">filler</tr>
<tr class="B">filler</tr>
<tr class="A B">filler</tr>
<tr class="C D">filler</tr>
<tr class="A F">filler</tr>
<tr class="A E F">filler</tr>
<tr class="F">filler</tr>
<tr class="C D E">filler</tr>
<tr class="A B C D E F">filler</tr>
</table>
I'd like to hide/show rows based on what is checked. Currently I'm using (with the help from this previous question: Use "this" to simplify code (simple jQuery) ):
$(function(){
$("input[id^='type-']").change(function() {
$("."+this.id.replace('type-','')).toggle(this.checked);
}).change();
});
Which toggles what is shown every time a box is clicked and works great if each row only has one class. But they don't. How it's set up now, the order of clicking changes the rows that are shown. So I need to create a function that checks which checkboxes are checked and shows the rows that contain any of them. I'm not opposed to adding a button to make this happen.
I'd appreciate any help (and the direction to resources that could help me learn) you guys could give me!
Modify the function to get a selector for all the checked check boxes.
$(function(){
var $checkboxes = $("input[id^='type-']");
$checkboxes.change(function() {
var selector = '';
$checkboxes.filter(':checked').each(function(){ // checked
selector += '.' + this.id.replace('type-','') + ', ';
// builds a selector like '.A, .B, .C, '
});
selector = selector.substring(0, selector.length - 2); // remove trailing ', '
// tr selector
$('table tr').hide() // hide all rows
.filter(selector).show(); // reduce set to matched and show
}).change();
});
EDIT: see jsfiddle
jQuery has created this function for you! It's called .filter(), and it takes either a selector string, a function, a raw DOM element, or a jQuery object. In your case, I'd pass it a selector string. We can make use of jQuery's :has() selector, which takes a selector and returns the matched elements. So, if you wanted to select all rows (li elements) that contain checked checkboxes, you could do it like this:
$("li").filter(":has(input:checked)");
Or, we could eliminate our call to filter() and simply pass the entire selector to $():
$("li:has(input:checked)");
That will return all li elements that contain any checked checkboxes anywhere among it's descendants, not just it's direct children.
And putting it in the context of your .change() handler:
I'm assuming you want to show tr elements that have the same type as the li elements that contain checked checkboxes, and hide any tr elements that don't. So, we'll make use of the .toggle() function, which toggles the visibility of elements:
$(function(){
$("input[id^='type-']").change(function() {
$("."+this.id.replace('type-','')).toggle(this.checked);
// show any tr elements that have the class relating to the type of the inputs that contain checked checkboxes...
$("li:has(input:checked)").each(function() {
$("tr" + "." + this.id.replace(/type-/, "")).toggle();
});
}).change();
});
$("table tr").hide();
$("input[id^='type-']").each(function() {
element = $(this);
$("table tr").each(function() {
if($(this).hasClass(element.id.replace('type-','')) {
if(element.is(":checked") {
element.show();
}
}
});
}).change();

Categories

Resources