jQuery multi select widget with a selectable optgroup - javascript

I am looking for a jQuery widget that looks like the following:
It allows you to have several groups for example:
Group 1
- Sub 1 1
- Sub 1 2
- Sub 1 3
Group 2
- Sub 2 1
Group 3
- Sub 3 1
- Sub 3 2
Clicking on Group 1 for example, will select everything inside, and clicking it again will deselect.
And also you should be able to collapse the groups for better navigation. Like seen in the image (the small arrow on the left side)
Is there a widget like this out there?
Thanks

The JQuery:
$(document).ready ( function ()
{
$('.parent').click(function () {
var set = false;
if ($(this).is(':checked'))
set = true;
$(this).parent().find('ul li').each( function () {
var Input = $(this).find('input');
Input.attr('checked', set);
});
});
$('span').click(function () {
if ($(this).text() == '-')
$(this).html('+');
else
$(this).html('-');
$(this).parent().find('ul li').each( function () {
$(this).slideToggle();
});
});
});
The html:
<ul>
<li>
<span>-</span><input type="checkbox" value="a" class="parent" /> a
<ul>
<li><input type="checkbox" value="a1" /> a1</li>
<li><input type="checkbox" value="a2" /> a2</li>
</ul>
</li>
<li>
<span>-</span><input type="checkbox" value="b" class="parent" /> b
<ul>
<li><input type="checkbox" value="b1" /> b1</li>
<li><input type="checkbox" value="b2" /> b2</li>
</ul>
</li>
</ul>
Cheers
EDIT: Added collapse.

This little jsfiddle I put together should do what you want:
http://jsfiddle.net/RdaCy/
To add more groups / sub_groups just change the id numbers accordingly :), If there is any aspect you would like me to change or if you need a further hand just tell me :)

Related

Issue with 'click' function in 'each' loop

Basically, I have multiple UL's with a class "list". Each of them has multiple radio buttons. I would like to do something with span element upon the last radio option of individual UL's being checked. And undo it after another radio button of that same UL is being checked.
The code essentially works but it is triggering for all of the UL's instead of the one in which the click occurred.
I used alert (which is commented out) to check if I'm getting everything with 'each' and it seems to work fine.
$(document).ready(function() {
$('ul.list').each(function() {
//alert($(this).text());
$("ul.list input[type$='radio']").click(function() {
if ($("li:last-of-type input[type$='radio']").prop("checked")) {
// do something with span
} else {
// do something with span
}
});
});
});
<ul class="list">
<li><input type="radio">Option 1</input>
</li>
<li><input type="radio">Option 2</input>
</li>
<li><input type="radio">Bonus</input><span>Bonus text</span></li>
</ul>
<ul class="list">
<li><input type="radio">Option 1</input>
</li>
<li><input type="radio">Option 2</input>
</li>
<li><input type="radio">Bonus</input><span>Bonus text</span></li>
</ul>
Actually you don't need the loop in this case just attach the click directly to the selector :
$(document).ready(function() {
$("ul.list :radio").click(function() {
if ( $(this).prop("checked") )
{
// do something with span
} else {
// do something with span
}
});
});
NOTE 1 : The input are self-closing tags so thsy should be like :
<input type="radio"/>Option 1
Instead of :
<input type="radio">Option 1</input>
NOTE 2 : Use this keyword to target the clicked element instead :
if( $(this).prop("checked") ){
Hope this helps.
$(document).ready(function() {
$("ul.list :radio").change(function() {
if ( !$(this).is(':last-child') && $(this).is(":checked") )
{
$(this).closest("ul").find('span').show();
}else{
$(this).closest("ul").find('span').hide();
}
});
});
ul.list li>span{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li><input type="radio" name="same_name_1" checked/>Option 1</li>
<li><input type="radio" name="same_name_1" />Option 2</li>
<li><input type="radio" name="same_name_1" />Bonus<br><span>Bonus text</span></li>
</ul>
<ul class="list">
<li><input type="radio" name="same_name_2" checked/>Option 1</li>
<li><input type="radio" name="same_name_2" />Option 2</li>
<li><input type="radio" name="same_name_2" />Bonus<br><span>Bonus text</span></li>
</ul>

Creating a list of items with different tags + filter

I have prepared an example what I would like to produce: link.
I have already looked for something and I have found the way to create a filter but just for one value... In my case I need more values all together combined. So that if I wanted a flat in Prague 1 and for a price less than 6 000 000, it would filter it for me.
How could I achieve it? Thank you very much for response.
Here is the codePen I have created for you with example:
$('#filter').click(function() {
var _typeFilter = $('input[name=type]:checked').val();
var _locationFilter = $('input[name=location]:checked').val();
$('ul li').each(function() {
if ($(this).filter('[type=' + _typeFilter + ']').filter('[location=' + _locationFilter + ']').length > 0)
$(this).show();
else
$(this).hide();
});
});
$('#clear').click(function() {
$('ul li').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div>
<input type="radio" name="type" value="flat" />Flat
<input type="radio" name="type" value="house" />House
</div>
<div>
<input type="radio" name="location" value="city1" />City1
<input type="radio" name="location" value="city2" />City2
<input type="radio" name="location" value="city3" />City3
</div>
Filter
Clear
<ul>
<li location='city1' type='flat' price='500000'>Item1</li>
<li location='city1' type='house' price='300000'>Item2</li>
<li location='city2' type='flat' price='400000'>Item3</li>
</ul>
CodePen link
You should use Jquery to achieve this. Bind parameters with attributes of your
'li' tag and filter them using Jquery.

Jquery Check parent checkboxes in nested ul li

I have a script that will check and uncheck all children checkboxes in a nested list. I am now trying to get it so I can check a low level checkbox and it will check all the parents only back up to the highest level. Here is a JSFiddle
<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>
And the corresponding javascript:
$('input[type=checkbox]').click(function(){
// if is checked
if($(this).is(':checked')){
// check all children
$(this).parent().find('li input[type=checkbox]').prop('checked', true);
// check all parents
$(this).parent().prev().prop('checked', true);
} else {
// uncheck all children
$(this).parent().find('li input[type=checkbox]').prop('checked', false);
}
});
It looks like you want something like this
$('input[type=checkbox]').click(function(){
if(this.checked){ // if checked - check all parent checkboxes
$(this).parents('li').children('input[type=checkbox]').prop('checked',true);
}
// children checkboxes depend on current checkbox
$(this).parent().find('input[type=checkbox]').prop('checked',this.checked);
});
FIDDLE
If you want to check up and down hierarchy - you can do it like this
$('input[type=checkbox]').click(function(){
// children checkboxes depend on current checkbox
$(this).next().find('input[type=checkbox]').prop('checked',this.checked);
// go up the hierarchy - and check/uncheck depending on number of children checked/unchecked
$(this).parents('ul').prev('input[type=checkbox]').prop('checked',function(){
return $(this).next().find(':checked').length;
});
});
FIDDLE
This should do it:
$('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);
});
jsFiddle example
Latest update handles up and down the hierarchy, and siblings.
Just use jquery.parents(). It is somewhat similar to find() except it searches all parents. Something like this might be close to what you are looking for:
$(this).parents('li').each(function() {
$(this).children('input').prop('checked', true);
});
See http://api.jquery.com/parents/ for more information.
EDIT: Alright, here is a solution that works:
http://jsfiddle.net/3y3Pb/12/
EDIT2: And a more streamlined solution here:
http://jsfiddle.net/3y3Pb/14/
Have a JSFiddle: http://jsfiddle.net/3y3Pb/16/
I would recommend adding a parent attribute to the checkboxes. This parent attribute will reference the parent checkbox's id so that you don't have to worry about your structure changing:
$('input type=[checkbox]').change(function () {
$('#' + $(this).attr('parent')).prop('checked', this.checked);
});
Ex:
<input type="checkbox" name="account_settings" value="yes" id="as">Account Settings
<ul>
<li><input type="checkbox" name="one" value="one" parent="as" id="one">AS One</li>
You can use prevAll() also
I have the same issue. In my case there are multiple checkboxes in li with labels, and each checkbox above target have class parent (generated in js)
$(this).parents().prevAll('input:checkbox.parent').each(function () {
$(this).attr('checked', true);
});

Making a checkbox appear at the bottom of the unordered list when checked

http://jsfiddle.net/AGinther/ZF7bD/1/
I am trying to make a list item appear at the bottom of the list when a checkbox is clicked using jQuery, currently I have;
HTML
<ul>
<li><input type="checkbox" id="checkbox-1"><label for="checkbox-1"> Checkbox 1</label></li>
<li><input type="checkbox" id="checkbox-2"><label for="checkbox-2"> Checkbox 2</label></li>
<li><input type="checkbox" id="checkbox-3"><label for="checkbox-3"> Checkbox 3</label></li>
<li><input type="checkbox" id="checkbox-4"><label for="checkbox-4"> Checkbox 4</label></li>
</ul>
Javascript
if ($('input[type="checkbox"]').prop('checked')) {
//Some code goes here...
}
Firstly, you need to include jQuery as a library in your fiddle. Furthermore, your if statement doesn't bind to any events.
You can do this by binding to the click event for checkboxes.
$('input[type="checkbox"]').click(function() {
var $t = $(this);
if ($t.is(':checked')) {
var cb = $t.parent().remove();
$('ul').append(cb);
}
});
Demo: http://jsfiddle.net/ZF7bD/7/

close other div when div1 is show and duplicate code pb jquery

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);
});

Categories