I have two version of the same code.
When I added it in the code snippet from this page it's working pretty well. However, for some reason I cannot get it working it working in my computer.
Take a look in my Dropbox version to get some idea. It's the same coding I'm using in both cases. It's supposed to check a parent checkbox if the child checkbox is checked and vice-versa.
Do you guys have some idea why is it happening?
$('input[type=checkbox]').click(function () {
$(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
var sibs = false;
$(this).closest('ul').children('li').each(function () {
if($('input[type=checkbox]', this).is(':checked')) sibs=true;
})
$(this).parents('ul').prev().prop('checked', sibs);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="tree" id="tree">
<li>
<input type="checkbox" name="account_settings" value="yes">Account Settings
<!-- AND SHOULD CHECK HERE -->
<ul>
<li>
<input type="checkbox" name="one" value="one">AS One</li>
<li>
<input type="checkbox" name="two" value="two">AS Two</li>
<li>
<input type="checkbox" name="user_roles" value="user_roles">Users & Roles
<!-- SHOULD CHECK HERE -->
<ul>
<li>
<input type="checkbox" name="user_role" value="add">Add</li>
<li>
<input type="checkbox" name="user_role" value="delete">Delete</li>
<!-- CHECK HERE -->
</ul>
</li>
</ul>
</li>
<li>
<input type="checkbox" name="rl_module" value="yes">RL Module</li>
<li>
<input type="checkbox" name="rl_module" value="yes">Accounting
<ul>
<li>
<input type="checkbox" name="vat" value="yes">VAT</li>
<li>
<input type="checkbox" name="bank_account" value="yes">Banking
<ul>
<li>
<input type="checkbox" name="view" value="yes">View</li>
<li>
<input type="checkbox" name="crud" value="yes">CRUD</li>
</ul>
</li>
</ul>
</li>
</ul>
Have you tried putting your script after the body? (You can leave the script tag where it loads the jQuery in the head)
I used your code and just put your script after the body and it worked just fine.I had that issue aswell where the script wouldn't work when placed before the body.Let me know if it worked out for you.
The reason for the above snippet not working is "events not getting attached" to the element. Try opening the debugger tool here in the page and to one in the dropbox, you will find there is no events attached to the Dropbox's element.
You can use on to attach the events to overcome this situation.
$('input[type=checkbox]').on('click',function () {
$(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
var sibs = false;
$(this).closest('ul').children('li').each(function () {
if($('input[type=checkbox]', this).is(':checked')) sibs=true;
})
$(this).parents('ul').prev().prop('checked', sibs);
});
Related
I have html code of dropdown choice with checkbox like this:
<ul id="channelFieldUL" class="dropdown-menu channelFieldUL">
<li class="sourceFieldRecordClass" onclick="goNext("account")">
<a class>
<label>
<input type="checkbox" value="account" class="apiFieldRecord" id="account0">" account "
</label>
</a>
</li>
...
//another li
<ul>
then the function :
function goNext(source){
//content
}
what i want to ask is, what do i need to put in the function to get all the <ul> option, and then uncheck the other options beside selected option?
P.S: i tried using .parent() or .closest, but it doesnt work (maybe because wrong usage)
you can use query selector to get the all the li elements inside ul element
like
let lis = document.getElementById('channelFieldUL').getElementsByTagName('li');
you can select the specific input of li element and can check and uncheck them like this
document.getElementById("checkbox").checked = true;
// Uncheck
document.getElementById("checkbox").checked = false;
This should work:
$('.apiFieldRecord').change(function() {
if (this.checked) {
$('.apiFieldRecord').not(this).prop('checked', false);
$(this).prop('checked', true);
}
})
li {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="channelFieldUL" class="dropdown-menu channelFieldUL">
<li class="sourceFieldRecordClass">
<a class>
<label>
<input type="checkbox" value="account" class="apiFieldRecord" id="account1">account 1
</label>
</a>
</li>
<li class="sourceFieldRecordClass">
<a class>
<label>
<input type="checkbox" value="account" class="apiFieldRecord" id="account2">account 2
</label>
</a>
</li>
<li class="sourceFieldRecordClass">
<a class>
<label>
<input type="checkbox" value="account" class="apiFieldRecord" id="account3">account 3
</label>
</a>
</li>
<ul>
Posted a question on about the same project in the morning. After battling it for a while came up with a bit different approach.
Trying to build a filter. And the idea is that a filter checkboxes have matching id's with filtered items classes. So, once a filter item clicked, filtration is applied to item class. Classes (except for inditem) and ids are dynamic
simplified html of it
<div class="itemswrap">
<div class="inditem dynamic1"></div>
<div class="inditem dynamic2"></div>
<div class="inditem dynamic3"></div>
<div class="inditem dynamic2"></div>
</div>
<ul class="subnav">
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic1" />
<label for="dynamic1">whatever label</label>
</li>
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic2" />
<label for="dynamic1">whatever label</label>
</li>
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic3" />
<label for="dynamic1">whatever label</label>
</li>
</ul>
js
$(".lifilter").each(function() {
var filter1 = $(this).find('.filtercheck').attr('id');
if ( $(this).find('.filtercheck').attr('checked') ) {
$(this).find('.filtercheck').click(function(){
$('.' + filter1).removeClass('checkeditem').hide();
});
}
else
{
$(this).find('.filtercheck').click(function(){
$('.inditem').hide();
$('.' + filter1).addClass('checkeditem');
});
}
});
and this one marked as important not to be hidden when extra items are added into filtration
.checkeditem {display:block !important}
Initial filtration works fine. But when I click on checked item the associated div does not hide.
Do you mean something like
var $filters = $('.filtercheck').change(function() {
var $items = $('.inditem').hide();
var filters = $filters.filter(':checked').map(function() {
return '.' + this.id;
}).get();
if (filters.length) {
$items.filter(filters.join()).show();
} else {
$items.show();
}
});
.checkeditem {
display: block !important
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="itemswrap">
<div class="inditem dynamic1">dynamic1</div>
<div class="inditem dynamic2">dynamic2</div>
<div class="inditem dynamic3">dynamic3</div>
<div class="inditem dynamic2">dynamic2</div>
</div>
<ul class="subnav">
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic1" />
<label for="dynamic1">whatever label</label>
</li>
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic2" />
<label for="dynamic1">whatever label</label>
</li>
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="dynamic3" />
<label for="dynamic1">whatever label</label>
</li>
</ul>
The problem with the code is that the event handler attaches the second click event on the first successful case. This means that the "click" on the checkbox is being given the "addclass" case, and all subsequent clicks are being handled by that handler instead of the intended one.
Using the same HTML. I created this:
$(document).ready(function() {
$(".filtercheck").click(function(){
$('.inditem').hide();
var filter1 = $(this).attr('id');
$('.' + filter1).toggleClass('checkeditem');
});
});
which I think is the intended behavior? Instead of individually attaching click handlers, I simply attached a single handler to all of them. It would be fairly easy to do something like
$(this).prop()
to determine if the currently clicked on item had was active or not. For this simple example, I opted to just use a class toggle to illustrate the point.
I'm trying to make something a bit like this:
This is my code: http://jsfiddle.net/928Dj/19/
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
});
I'm trying to make it degradable so without javascript they can submit the form to adjust the results, but with javascript they can just click the text of the desired result.
Question A
How can I make it so by them clicking the text alone, with javascript enabled, it not only selects the radio button but also submit the form.
Question B
Is my code the right approach to achieve this desired outcome?
Replace the radio buttons with submit buttons.
<input type="submit" name="status" value="Status 1">
i think google uses <a> tag instead <input> and (but i'm not sure) catches the click and makes a ajax call to update only the result (without any form)... like: http://jsfiddle.net/928Dj/25/
HTML, change <input> in <a>:
Status 1
JS
$('ul.opt a').click(function(e){
e.preventDefault();
$(this).parents(".opt").find("a").removeClass("active");
$(this).addClass("active");
$.get($(this).attr("href"),function(res){
//do something with response
});
});
On <a> click the JS simply perform search.action (or other search service) with sortDate=status1 like parameter via AJAX, for sort the result.
You can concat the sorting parameters status=status1&date=date1 for multiple sorting.
I don't know if there are any ways to perform the submit without using javascript (and without reload all page).
I've updated your fiddle with submit buttons that are hidden if javascript is enabled.
<div>
<form action="/echo/html/">
<ul id="filter">
<li> Any status ▾
<ul class="opt">
<li>
<label>
<input type="radio" name="status" />Status 1</label>
</li>
<li>
<label>
<input type="radio" name="status" />Status 2</label>
</li>
<li>
<input type="submit" value="submit"/>
</li>
</ul>
</li>
<li> Any date ▾
<ul class="opt">
<li>
<label>
<input type="radio" name="date" />Date 1</label>
</li>
<li>
<label>
<input type="radio" name="date" />Date 2</label>
</li>
<li>
<input type="submit" value="submit"/>
</li>
</ul>
</li>
</ul>
</form>
</div>
<div id="results">
Filtered results go here
</div>
<script>
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
$('#filter li input[type=submit]').hide();
});
$('#filter input[type=radio]').click(function() {
var $form = $(this).closest('form');
$('#results').html('filtering...');
$.post($form.attr('action'),$form.serialize(),function(response) {
if ( response ) {
$('#results').html(response);
} else {
$('#results').html('no results found');
}
});
});
</script>
I'm trying to add a class to a div (.checkbox) when clicking on the label that follows from it. It doesn't seem to be working at all though and I don't know why.
Below is the javascript and the basic form layout that I have set up.
JS
$('#filter ul label').click(function() {
if ($(this).prev('.checkbox').hasClass('checked')) {
$(this).prev('.checkbox').removeClass('checked');
} else {
$(this).prev('.checkbox').addClass('checked');
}
});
HTML
<form id="filter">
<div>
Service <span></span>
<ul>
<li>
<div class="checkbox"></div>
<label for="new-build">
<input type="checkbox" name="new-build" id="new-build">
New Build
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="extensions">
<input type="checkbox" name="extensions" id="extensions">
Extensions
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="refurbishments">
<input type="checkbox" name="refurbishments" id="refurbishments">
Refurbishments
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="fit-out">
<input type="checkbox" name="fit-out" id="fit-out">
Fit Out
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="maintenance">
<input type="checkbox" name="maintenance" id="maintenance">
Maintenance
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="design-build">
<input type="checkbox" name="design-build" id="design-build">
Design & Build
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="listed-building">
<input type="checkbox" name="listed-building" id="listed-building">
Fit Out
</label>
</li>
</ul>
</div>
<input type="submit">
</form>
Any help would be greatly appreciated, I'm assuming it is something really simple that I'm missing completely.
Thank you.
Your solution works perfectly fine. Please make sure that you included jQuery and put your javascript in a
$(document).ready(function() {
});
block.
It seems like the click event is not fired when writing the markup like you did. You can bind your function to the change event of the checkbox instead. This should work as expected:
$('#filter input[type=checkbox]').change(function() {
var $div = $(this).parent().prev('.checkbox');
if ($div.hasClass('checked')) {
$div.removeClass('checked');
} else {
$div.addClass('checked');
}
});
Check Fiddle for demo: http://jsfiddle.net/g3v4F/3/
I think you have a problem with the order of code. At the time your JavaScript code is executed the DOM elements are not there because they come after the JS.
Move the JS behind the HTML or use the jQuery(document). ready(function () {...}) construct (recommended).
http://api.jquery.com/ready/
This worked for me:
$('#filter ul label').click(function() {
var $cb = $(this).prev('.checkbox');
$cb.toggleClass('checked', !$cb.hasClass('checked'));
});
Working JSFiddle
JS should be either below your HTML or wrapped in document.ready
$(function(){
// your JS here
});
I have 2 problems
1.First i need to allow only one div open , so when div question1 is show
div question2 and all other should hide, actually its not case in my poor code :).
2.Second problem , I achieve to made a code with an addclass when "is checked", but actually i duplicate all the code for each div .. Perhaps someone have a better elegant option to merge the code and avoiding duplicate code..
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$(".checkbox").toggle(10);
});
$('#test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question').addClass("question-active");
} else {
$('div.question').removeClass("question-active");
}
});
$(".checkbox2").hide();
$(".question2").show();
$('.question2').click(function(){
$(".checkbox2").toggle(10);
});
$('#test2').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question2').addClass("question-active");
} else {
$('div.question2').removeClass("question-active");
}
});
Here is my code : http://jsfiddle.net/5C3p9/3/
Thanks for help
Regards
If you want to keep your HTML markup as it is, this should work:
// The ^= selector is used to select the elements which have the
// property starting with the text provided.
// ie: class starting with checkbox
$("div[class^='checkbox']").hide();
$("div[class^='question']").show();
$("div[class^='question']").click(function () {
// This way you are able to close the clicked one itself
$("div[class^='checkbox']").not($(this).next()).hide();
$(this).next("div[class^='checkbox']").toggle(10);
});
$("ul[id^='test']").change(function () {
// You can use the .toggleClass() method giving the class name
// and a boolean (add/remove) as parameters
$(this)
.parents()
.prev("div[class^='question']")
.toggleClass("question-active", $("input[type='checkbox']:checked").length != 0);
});
Demo: http://jsfiddle.net/5C3p9/7/
EDIT: I've put some comments in the code.
Some minor dom changes
<div class="quest question"></div>
<div class="ans checkbox">
<ul id="test">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
<div class="quest question2"></div>
<div class="ans checkbox2">
<ul id="test2">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
then
$(".quest").show();
$(".ans").hide();
$('.quest').click(function(){
$(this).next().toggle(10);
});
$('.ans').change(function(){
var $ans = $(this).closest('.ans');
$ans.prev().toggleClass('question-active', $ans.find('input:checkbox:checked').length > 0)
});
Demo: Fiddle
I made some modifications to your code. What I did is that I added some HTML-classes and made the javascript more general and traverse the HTML instead of pointing straight to the element.
Here's the jsFiddle: http://jsfiddle.net/E595w/1/
The new HTML:
<div class="question"></div>
<div class="checkbox">
<ul id="test" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
<div class="question"></div>
<div class="checkbox">
<ul id="test2" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
And here's the resulting Javascript:
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$('.checkbox').hide();
$(this).next(".checkbox").toggle(10);
});
$('.test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$(this).parents('.checkbox').prev('div.question').addClass("question-active");
} else {
$(this).parents('.checkbox').prev('div.question').removeClass("question-active");
}
});
EDIT: Updated with code to answer your #1 question. See updated link to jsFiddle.
put to all your questions same class .question
if you want to differentiate between questions, use ids instead
also, put to to all answers container .checkbox
then use this function which will work for questions , no matter how many you have
$('.question').click(function(){
$(".checkbox").hide();
$(this).next(".checkbox").show(10);
});