Keeping check boxes selected - javascript

I am working on a html page that can be used to keep track on what you have watched by manual clicking check boxes so you know what episode you are on. My problem is keeping the box checked after leaving the page and returning to it, I have been trying to use cookies but none have worked so far. I am using this on Google Chrome and not sure if this makes a difference.
<h2>Season 1</h2>
<ul>
<li><input type="checkbox" id="option1"/>Episode 1</li>
<li><input type="checkbox" id="option2"/>Episode 2</li>
<li><input type="checkbox" id="option3"/>Episode 3</li>
<li><input type="checkbox" id="option4"/>Episode 4</li>
<li><input type="checkbox" id="option5"/>Episode 5</li>
<li><input type="checkbox" id="option6"/>Episode 6</li>
</ul>
This is the Javascript code I used:
<script>
function handleButtonClick(button){
if ($(button).text().match("Check all")){
$(":checkbox").prop("checked", true)
} else {
$(":checkbox").prop("checked", false)
};
updateButtonStatus();
}
function updateButtonStatus(){
var allChecked = $(":checkbox").length === $(":checkbox:checked").length;
$("button").text(allChecked? "Uncheck all" : "Check all");
}
function updateCookie(){
var elementValues = {};
$(":checkbox").each(function(){
elementValues[this.id] = this.checked;
});
elementValues["buttonText"] = $("button").text();
$.cookie('elementValues', elementValues, { expires: 7, path: '/' })
}
function repopulateFormELements(){
var elementValues = $.cookie('elementValues');
if(elementValues){
Object.keys(elementValues).forEach(function(element) {
var checked = elementValues[element];
$("#" + element).prop('checked', checked);
});
$("button").text(elementValues["buttonText"])
}
}
$(":checkbox").on("change", function(){
updateButtonStatus();
updateCookie();
});
$("button").on("click", function() {
handleButtonClick(this);
updateCookie();
});
$.cookie.json = true;
repopulateFormELements();
</script>
Here is a link to the full document: http://jsfiddle.net/r4gqqd0c/
Thanks for the help.

If you don't want to use a database to store checkbox status you can use localstorage. An example will be like:
//add this when a checkbox is clicked
$(":checkbox").on("click", function() {
localStorage.setItem($(this).attr("id"), $(this).prop("checked"));
});
//when page loads
$(":checkbox").each(function() {
var status = localStorage.getItem($(this).attr("id"));
$(this).prop("checked", status === "true" ? true : false);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Season 1</h2>
<ul>
<li>
<input type="checkbox" id="option1" />Episode 1</li>
<li>
<input type="checkbox" id="option2" />Episode 2</li>
<li>
<input type="checkbox" id="option3" />Episode 3</li>
<li>
<input type="checkbox" id="option4" />Episode 4</li>
<li>
<input type="checkbox" id="option5" />Episode 5</li>
<li>
<input type="checkbox" id="option6" />Episode 6</li>
</ul>
fiddle
References:
Window.localStorage
Storage.getItem()

Related

multi checkbox on input javascript

When I click on Select, a box opens and we select many options, including father and child.When options are selected
After selection, immediately display the ID numbers on the input. When we click OK, the box will be hidden. I want each of the boxes to be done separately in the input .This is My Html:
<button class="btn-select">Select one ...</button>
<div class="box" style="display:none">
<input type="checkbox" class="checkbox" value="1">Check Box 1
<input type="checkbox" class="checkbox" value="2">Check Box 2
<input type="text" class="input input-1" value="">
<button class="btn-ok">Ok</button>
</div>
<button class="btn-select">Select Two (Father/Children) ...</button>
<div class="box" style="display:none">
<ul class="father">
<li>
<input type="checkbox" class="checkbox" value="1">Part 1
<ul class="children">
<li><input type="checkbox" class="checkbox" value="5">Check Box 5</li>
</ul></li>
<li>
<input type="checkbox" class="checkbox" value="2">Part 2
<ul class="children">
<li><input type="checkbox" class="checkbox" value="7">Check Box 7</li>
<li><input type="checkbox" class="checkbox" value="8">Check Box 8</li>
</ul></li></ul>
<input type="text" class="input input-2" value="">
<button class="btn-ok">Ok</button>
</div>
.
...Select Three...
..Select Four..
..
.
This is My JS (Children and Father):
handleChildren = function() {
var $checkbox = $(this);
var $checkboxChildren = $checkbox.parent();
$checkboxChildren.each(function() {
if ($checkbox.is(":checked")) {
$(this).prop("checked", "checked");
} else {
$(this).removeProp("checked");
}
});
};
handleParents = function(current) {
var $parent = $(current).closest(".children").closest("li").find("> input[type=checkbox]");
if ($parent.parent().find(".children input[type=checkbox]:checked").length > 0) {
$parent.prop("checked", "checked");
} else {
$parent.removeProp("checked");
}
handleParents($parent);
}
$("ul.father").find("input[type=checkbox]").each(function() {
$(input).on("click", handleChildren);
$(input).on("click", function() {
handleParents(this);
});
});
This is My JS:
$(document).on('click', '.btn-ok', function(){
$('.box').hide()
});
$(document).on('click', '.btn-select', function(){
$('.box').hide()
$(this).next().show();
});
$(".checkbox").change(function() {
var text = "";
$(".checkbox:checked").each(function() {
text += $(this).val() + ",";
});
text = text.substring(0, text.length - 1);
$(this).next().val(text);
});
Now an error is shown by the console that says:
Uncaught InternalError: too much recursion
closest file:///var/www/html/jquey.js:1
Your handleParents calls itself unconditionally.

remove li element when checkbox is unchecked

I am dynamically able to add a new li element on checked event of a checkbox. However I am not able to remove the same on the unchecked event.
$(document).ready(function() {
var value;
$(".tmCheckbox").change(function() {
if (this.checked) {
value = $(this).val();
$('.ul_sec').append($('<li>', {
text: value
}));
} else {
// $(this).parent().remove();
}
});
});
HTML CODE:
<h3>MY SELECTION </h3>
<ul class="ul_sec" style="display: block;">
<li><input type="checkbox" name="filter" value="">Random Text 1</li>
<li><input type="checkbox" name="filter" value="">Random Text 2</li>
</ul>
<h3>FILTER</h3>
<ul style="display: block;">
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 1">Random Text 1</li>
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 2">Random Text 2</li>
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 3">Random Text 3</li>
</ul>
Filter out li element based on text content using filter() method and remove it using remove() method.
var $this = this;
$('.ul_sec li').filter(function(){
return $(this).text() == $this.value;
}).remove();
$(document).ready(function() {
var value;
$(".tmCheckbox").change(function() {
var value = $(this).val();
if (this.checked) {
$('.ul_sec').append($('<li>', {
html: this.outerHTML + value
}));
} else {
$('.ul_sec li').filter(function() {
return $(this).text() == value;
}).remove();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>MY SELECTION </h3>
<ul class="ul_sec" style="display: block;">
</ul>
<h3>FILTER</h3>
<ul style="display: block;">
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 1">Random Text 1</li>
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 2">Random Text 2</li>
<li><input class="tmCheckbox" type="checkbox" name="filter" value="Random Text 3">Random Text 3</li>
</ul>
Just use remove() to the target where it is appended
Like this:
$(document).ready(function() {
var value;
$(".tmCheckbox").change(function() {
if (this.checked) {
value = $(this).val();
$('.ul_sec').append($('<li>', {
text: value
}));
} else {
$('.ul_sec li').last().remove();
}
});
});
document.getElementById("yourid").remove(); giving an id to the <li> you just added.

multiple filters based on checkbox and divs id's and classes

The idea is to filter divs by comparing dynamically generated classes for divs and dynamically generated id's for checkboxes, where only divs with classes matching id's of checked checkboxes would show.
First subnav filters everything fine. However, subnav2 dosen't do anything.
Simplified html of it
<div class="itemswrap">
<div class="inditem dynamic1 dynamic12"></div>
<div class="inditem dynamic2 dynamic22"></div>
<div class="inditem dynamic3 dynamic32"></div>
<div class="inditem dynamic2 dynamic42"></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>
<ul class="subnav2">
<li class="lifilter2">
<input type="checkbox" class="filtercheck2" id="dynamic12" />
<label for="dynamic12">whatever label</label>
</li>
<li class="lifilter2">
<input type="checkbox" class="filtercheck2" id="dynamic22" />
<label for="dynamic12">whatever label</label>
</li>
<li class="lifilter2">
<input type="checkbox2" class="filtercheck2" id="dynamic32" />
<label for="dynamic12">whatever label</label>
</li>
</ul>
And the js i've got so far.
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();
}
});
var $filtersb = $('.filtercheck2').change(function() {
var $itemsb = $('.inditem').hide();
var filtersb = $filtersb.filter(':checked').map(function() {
return '.' + this.id;
}).get();
if (filtersb.length) {
$itemsb.filter(filters.join()).show();
} else {
$itemsb.show();
}
});
I see that you fixed it but I had created a jsfiddle for your problem, akin to one I had to face in another project. Basically, you create a string from the checked checkboxes IDs and use that to show only those items that match the elements you checked. If no elements are checked, all items are shown (i.e. no filters are applied).
$("input[type='checkbox']").change(function()
{
var list = "";
$("input[type='checkbox']").each(function()
{
if(this.checked)
{
list = list + '.' + $(this).attr('id');
}
});
if(list !=='')
{
$("div.inditem").hide();
$(list).show();
}
else {
$("div.inditem").show();
}
});

Nested Checkbox : Checked / Unchecked children with parent check

Hi I've got a form with nested Checkbox on three level
With Jquery I need to checked/uncheked all the children when I check a parent level... and of course uncheck the parent if at least one of the children is uncheck
I try but never success that's why I'm calling your help :)
Many thanks to all
My html code :
Demo here : http://jsfiddle.net/SENV8/86/
<fieldset class="floral">
<input type="checkbox" class="familybox cbox">
<label>Level 1</label>
<ul class="valuelist">
<li>
<input type="checkbox" class="cbox mainoption">
<label>Level 2</label>
<ul class="suboption">
<li>
<input type="checkbox" class="cbox">
<label>Level 3</label>
</li>
</ul>
<ul class="suboption">
<li>
<input type="checkbox" class="cbox">
<label>Level 3</label>
</li>
</ul>
</li>
<li>
<input type="checkbox" class="cbox mainoption">
<label>Level 2</label>
<ul class="suboption">
<li>
<input type="checkbox" class="cbox">
<label>Level 3</label>
</li>
</ul>
<ul class="suboption">
<li>
<input type="checkbox" class="cbox">
<label>Level 3</label>
</li>
</ul>
</li>
</ul>
</fieldset>
EDIT :
I'm here with my script:
$('.familybox').change(function() {
var getparent = $(this).closest('fieldset').attr('class');
if($('.'+getparent+' .familybox').is(':checked')){
$('.'+getparent+' .valuelist input:checkbox').prop('checked', true);
} else if($('.'+getparent+' .familybox').not(':checked')) {
$('.'+getparent+' .valuelist input:checkbox').prop('checked', false);
}
});
See I have Implemented your requirement.
It is needed to make some changes in HTML which I have did in JSfiddle.
Total Jquery script is as follow:
<script type="text/javascript">
$(document).ready(function () {
$.extend($.expr[':'], {
unchecked: function (obj) {
return ((obj.type == 'checkbox' || obj.type == 'radio') && !$(obj).is(':checked'));
}
});
$(".floral input:checkbox").live('change', function () {
$(this).next('ul').find('input:checkbox').prop('checked', $(this).prop("checked"));
for (var i = $('.floral').find('ul').length - 1; i >= 0; i--) {
$('.floral').find('ul:eq(' + i + ')').prev('input:checkbox').prop('checked', function () {
return $(this).next('ul').find('input:unchecked').length === 0 ? true : false;
});
}
});
});
</script>
To see live demo:
JSFiddle

Nested parent/child checkboxes - working solution need adjustment help for Bootstrap

I have been looking for a 'complete' solution to nesting parent child checkboxes that change state correctly based on a hierarchy.
Most 'solutions' do not work or only work to one level. They also require you to name the checkboxes in a particular way.
This Stack Overflow discussion covers the main points but also provide a good solution discovered by Rory here.
I have tested it within my development project and it works perfectly standalone. However, I am using Bootstrap 2.x and for checkboxes
I have a JSFiddle which shows the working example code, then my version with a disabled parent checkbox and then the bootsrap code version which does not work.
<!DOCTYPE html>
<body>
<!-- Raw working example from site http://css-tricks.com/indeterminate-checkboxes/ -->
<b>Raw working example</b>
<p>
<ul>
<li>
<input type="checkbox" name="tall" id="tall">
<label for="tall">Tall Things</label>
<ul>
<li>
<input type="checkbox" name="tall-1" id="tall-1">
<label for="tall-1">Buildings</label>
</li>
<li>
<input type="checkbox" name="tall-2" id="tall-2">
<label for="tall-2">Giants</label>
<ul>
<li>
<input type="checkbox" name="tall-2-1" id="tall-2-1">
<label for="tall-2-1">Andre</label>
</li>
<li>
<input type="checkbox" name="tall-2-2" id="tall-2-2">
<label for="tall-2-2">Paul Bunyan</label>
<ul>
<li>
<input type="checkbox" name="tall-2-2-1" id="tall-2-2-1">
<label for="tall-2-2-1">Son</label>
</li>
<li>
<input type="checkbox" name="tall-2-2-2" id="tall-2-2-2">
<label for="tall-2-2-2">Daughter</label>
</li>
</ul>
</li>
</ul>
</li>
<li>
<input type="checkbox" name="tall-3" id="tall-3">
<label for="tall-3">Two sandwiches</label>
</li>
</ul>
</li>
<li>
<input type="checkbox" name="short" id="short">
<label for="short">Short Things</label>
<ul>
<li>
<input type="checkbox" name="short-1" id="short-1">
<label for="short-1">Smurfs</label>
</li>
<li>
<input type="checkbox" name="short-2" id="short-2">
<label for="short-2">Mushrooms</label>
</li>
<li>
<input type="checkbox" name="short-3" id="short-3">
<label for="short-3">One Sandwich</label>
</li>
</ul>
</li>
</ul>
<hr>
<!-- Non Bootstrap Example -->
<b>My initial code example - Is Working</b>
<p>
<ul>
<li>
<input type="checkbox" name="" value="" disabled><strong>Ford</strong>
<ul>
<li>
<input type="checkbox" name="" value="">Fiesta</label>
</li>
<li>
<input type="checkbox" name="" value="">Focus</label>
</li>
<li>
<input type="checkbox" name="" value="">Mondeo</label>
</li>
</ul>
</li>
<li>
<input type="checkbox" name="" value="" disabled><strong>Vauxhall</strong>
<ul>
<li>
<input type="checkbox" name="" value="">Corsa</label>
</li>
<li>
<input type="checkbox" name="" value="">Astra</label>
</li>
<li>
<input type="checkbox" name="" value="">Vectra</label>
</li>
</ul>
</li>
</ul>
<hr>
<!-- Bootstrap Example -->
<b>Bootstrap based code example - Not Working</b>
<p>
<ul>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="" disabled><strong>Ford</strong>
</label>
<ul>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Fiesta</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Focus</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Mondeo</label>
</li>
</ul>
</li>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="" disabled><strong>Vauxhall</strong>
</label>
<ul>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Corsa</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Astra</label>
</li>
<li>
<label class="checkbox">
<input type="checkbox" name="" value="">Vectra</label>
</li>
</ul>
</li>
</ul>
$(function () {
// Apparently click is better chan change? Cuz IE?
$('input[type="checkbox"]').change(function (e) {
var checked = $(this).prop("checked"),
container = $(this).parent(),
siblings = container.siblings();
container.find('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
function checkSiblings(el) {
var parent = el.parent().parent(),
all = true;
el.siblings().each(function () {
return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
});
if (all && checked) {
parent.children('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
checkSiblings(parent);
} else if (all && !checked) {
parent.children('input[type="checkbox"]').prop("checked", checked);
parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
checkSiblings(parent);
} else {
el.parents("li").children('input[type="checkbox"]').prop({
indeterminate: true,
checked: false
});
}
}
checkSiblings(container);
});
});
My understanding is that the code needs to be changed somewhere to use parents or closest. Can someone who is a much better code please help identify where the change needs to happen to get the Bootstrap version working.
Take a look at the free JSTree user control. It is JavaScript-based, open source and allows to be configured for multiple styles of tree views, for example:
Since the checkboxes displayed here are just images, you can replace them by radio buttons easily, and via event handling you can disallow multiple selections so they behave like radio buttons if required.
This is achieved by specifying the "checkbox" plugin as follows (see the snippet I provided below for the complete working code):
$(function () {
$("#demo1")
.jstree({
"themes": {
"theme": "apple","dots": false,"icons": false
},
"plugins": ["themes", "html_data", "checkbox", "sort", "ui"]
});
});
The corresponding HTML structure looks like this, just include it in the body of your page:
<div id="demo1" class="demo" style="height:100px;">
<ul>
<li id="phtml_1"> Root node 1
<ul>
<li id="phtml_2"> Child node 1
</li>
<li id="phtml_3"> Child node 2
</li>
</ul>
</li>
<li id="phtml_4"> Root node 2
</li>
</ul>
</div>
To get the checked values, use this function (assuming you have created a div with id="listForDisplay" as I did in the JSFiddle example):
var $listForDisplay = $("#listForDisplay");
function displayList(data) { // see: https://www.jstree.com/docs/events/
var i, j, r = [];
for (i = 0, j = data.selected.length; i < j; i++) {
r.push(data.instance.get_node(data.selected[i]).text);
}
$listForDisplay.html('Selected: ' + r.join(', '));
}
This code can either be triggered in a click event or you can bind JSTree events like I did. Appending the following to the previous JavaScript snippet does the job:
$("#demo1")
.on('loaded.jstree', function (e, data) {
displayList(data);
})
.on('change_state.jstree', function (e, data) {
displayList(data);
});
Note: When a parent node is selected, the parent name is listed along with the childs. If only the childs are selected, the related parent(s) will not be listed.
You can find more about the options specifying the behaviour of this plugin here.
Runnable code snippet (complete code)
$(function() {
var $demo1 = $("#demo1");
var $listForDisplay = $("#listForDisplay");
function displayList(data) { // see: https://www.jstree.com/docs/events/
var i, j, r = [];
for (i = 0, j = data.selected.length; i < j; i++) {
r.push(data.instance.get_node(data.selected[i]).text);
}
$listForDisplay.html('Selected: ' + r.join(', '));
}
$demo1.jstree({
"themes": {
"theme": "apple",
"dots": false,
"icons": false
},
"plugins": ["themes", "html_data", "checkbox", "sort", "ui"]
});
$demo1.on('loaded.jstree', function(e, data) {
displayList(data);
});
$demo1.on('changed.jstree', function(e, data) {
displayList(data);
});
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
</head>
<body>
<div id="demo1" class="demo" style="height:100px;">
<ul>
<li id="phtml_1"> Root node 1
<ul>
<li id="phtml_2"> Child node 1
</li>
<li id="phtml_3"> Child node 2
</li>
</ul>
</li>
<li id="phtml_4"> Root node 2
</li>
</ul>
</div>
<br/>
<div id="listForDisplay" />
</body>
you can try something like this
$(function () {
$('input[type="checkbox"]').change(function (e) {
var checked = $(this).prop("checked"),
container = $(this).closest("li"),//get closest li instead of parent
siblings = container.siblings();
container.find('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
function checkSiblings(el) {
var parent = el.parent().parent(),
all = true,
parentcheck=parent.children("label");//get the label that contains the disabled checkbox
el.siblings().each(function () {
return all = ($(this).find('input[type="checkbox"]').prop("checked") === checked);
});
//use parentcheck instead of parent to get the children checkbox
if (all && checked) {
parentcheck.children('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
checkSiblings(parent);
} else if (all && !checked) {
parentcheck.children('input[type="checkbox"]').prop("checked", checked);
parentcheck.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
checkSiblings(parent);
} else {
parentcheck.children('input[type="checkbox"]').prop({
indeterminate: true,
checked: false
});
}
}
checkSiblings(container);
});
});
http://jsfiddle.net/Mvs87/2/

Categories