WordPress: Allow to only check one checkbox in a fieldset - javascript

I'm using Gravity Forms and the quiz add-on to build a survey.
Every question should have only one accepted answer. But all answers should be "correct".
The quiz add-on works in a different way. It allows only one correct answer for radio buttons. I couldn't limit checkboxes to only one answer.
So I guess I have to work with custom JavaScript to allow only one answer or checked box per fieldset.
The fieldset for a question looks like this:
<fieldset id="field_3_1" class="gfield" data-field-class="gquiz-field">
<legend class="gfield_label gfield_label_before_complex">Question 1</legend>
<div class="ginput_container ginput_container_checkbox">
<div class="gfield_checkbox" id="input_3_1">
<div class="gchoice gchoice_3_1_1">
<input class="gfield-choice-input" name="input_1.1" type="checkbox" value="gquiz21dc402fa" id="choice_3_1_1">
<label for="choice_3_1_1" id="label_3_1_1">Answer 1</label>
</div>
<div class="gchoice gchoice_3_1_2">
<input class="gfield-choice-input" name="input_1.2" type="checkbox" value="gquiz3414cb0c0" id="choice_3_1_2">
<label for="choice_3_1_2" id="label_3_1_2">Answer 2</label>
</div>
<div class="gchoice gchoice_3_1_3">
<input class="gfield-choice-input" name="input_1.3" type="checkbox" value="gquiz21d0214b9" id="choice_3_1_3">
<label for="choice_3_1_3" id="label_3_1_3">Answer 3</label>
</div>
</div>
</div>
</fieldset>
It's not clear how many fieldsets/questions are present at the end. So I need a flexible solution.
I found some JS Code here:
$(function () {
$('input[type=checkbox]').click(function () {
var chks = document.getElementById('<%= chkRoleInTransaction.ClientID %>').getElementsByTagName('INPUT');
for (i = 0; i < chks.length; i++) {
chks[i].checked = false;
}
if (chks.length > 1)
$(this)[0].checked = true;
});
});
But I'm not sure how to adapt it for my use case

This script will make each checkbox per fieldset exclusive.
jQuery(function($) {
$('fieldset input[type="checkbox"]').on('change', function() {
// Set the checkbox just checked.
let just_checked = $(this);
// Get all of the checkboxes in the fieldset.
let all_checkboxes = just_checked.closest('fieldset').find('input[type="checkbox"]');
$.each(all_checkboxes, function(i, v) { // Loop through each of the checkboxes.
if (just_checked.prop('id') === $(v).prop('id')) {
// Check the one just checked.
$(v).prop('checked', true);
} else {
// Uncheck the others.
$(v).prop('checked', false);
}
})
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset id="field_3_1" class="gfield" data-field-class="gquiz-field">
<legend class="gfield_label gfield_label_before_complex">Question 1</legend>
<div class="ginput_container ginput_container_checkbox">
<div class="gfield_checkbox" id="input_3_1">
<div class="gchoice gchoice_3_1_1">
<input class="gfield-choice-input" name="input_1.1" type="checkbox" value="gquiz21dc402fa" id="choice_3_1_1">
<label for="choice_3_1_1" id="label_3_1_1">Answer 1</label>
</div>
<div class="gchoice gchoice_3_1_2">
<input class="gfield-choice-input" name="input_1.2" type="checkbox" value="gquiz3414cb0c0" id="choice_3_1_2">
<label for="choice_3_1_2" id="label_3_1_2">Answer 2</label>
</div>
<div class="gchoice gchoice_3_1_3">
<input class="gfield-choice-input" name="input_1.3" type="checkbox" value="gquiz21d0214b9" id="choice_3_1_3">
<label for="choice_3_1_3" id="label_3_1_3">Answer 3</label>
</div>
</div>
</div>
</fieldset>
An alternative solution could be to use radio buttons, and use css to make them look like checkboxes. But UX says that checkboxes shouldn't be used as radio buttons, and vice versa. For whatever that's worth.

Related

Appending checkboxes labels of a form into a <p> element

I have been trying to do this for a few hours but couldn't succeed. So I decided to ask help here.
So, I have a form:
<form id="ecommerce-form">
<input type="checkbox" id="seopremium" name="option-ecommerce" value="seopremium">
<label for="seopremium" class="lead">SEO premium</label>
<input type="checkbox" id="moyenpaiement" name="option-ecommerce" value="moyenpaiement">
<label for="moyenpaiement" class="lead">Configuration paiements</label>
<input type="checkbox" id="facturation" name="option-ecommerce" value="facturation">
<label for="facturation" class="lead">Facturation simplifiée</label>
<input type="checkbox" id="avisclients" name="option-ecommerce" value="avisclients">
<label for="avisclients" class="lead">Avis clients</label>
<input type="checkbox" id="additionnalsecurity" name="option-ecommerce" value="additionnalsecurity">
<label for="additionnalsecurity" class="lead">Sécurité supplémentaire</label>
<input type="checkbox" id="basketoptions" name="option-ecommerce" value="basketoptions">
<label for="basketoptions" class="lead">Panier avec options</label>
</form>
And I'm trying to print the label's text of checkboxes that are checked automatically into a Paragraph:
<p class="recap-option"><strong>Options:</strong></p><p class="options-selected"></p>
So if everything is checked the Paragraph would be:
<p class="recap-option"><strong>Options:</strong></p><p class="options-selected">SEO premium, Configuration paiements, facturation simplifiée, Avis clients, Sécurité supplémentaire, Panier avec options</p>
Or in clear:
Options: SEO premium, Configuration paiements, facturation simplifiée, Avis clients, Sécurité supplémentaire, Panier avec options
I found a few solutions here for problems that seemed relatively similar but I wasn't able to adapt the code for my own needs.
http://jsfiddle.net/5ryy9krn/2/
So the goal is simply appending what is between each into the paragraph element.
Thanks in advance for any help.
You need to fetch the label element and use its value to append into the selected-area.
And on uncheck, also follow the same procedure to remove the unchecked element from the selected-area
You can define the onChange function in the following way to achieve the expected behavior.
$('input[type="checkbox"]').on('change', function() {
if ($(this).is(':checked')) {
var elements = $(this).parent('div');
const checkedItem = elements.find("label").text();
$('#seleted-rows').append(`<p name="${checkedItem}">${checkedItem}</p>`);
} else {
var elements = $(this).parent('div');
const uncheckedItem = elements.find("label").text();
$('#seleted-rows').find(`p[name="${uncheckedItem}"]`).remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="pb-5 devis-invisible" id="devis-ecommerce">
<form id="ecommerce-form">
<div class="row pb-5">
<div class="col-4">
<input type="checkbox" id="seopremium" name="option-ecommerce" value="seopremium">
<label for="seopremium" class="lead">SEO premium</label>
</div>
<div class="col-4">
<input type="checkbox" id="moyenpaiement" name="option-ecommerce" value="moyenpaiement">
<label for="moyenpaiement" class="lead">Configuration paiements</label>
</div>
<div class="col-4">
<input type="checkbox" id="facturation" name="option-ecommerce" value="facturation">
<label for="facturation" class="lead">Facturation simplifiée</label>
</div>
</div>
<div class="row">
<div class="col-4">
<input type="checkbox" id="avisclients" name="option-ecommerce" value="avisclients">
<label for="avisclients" class="lead">Avis clients</label>
</div>
<div class="col-4">
<input type="checkbox" id="additionnalsecurity" name="option-ecommerce" value="additionnalsecurity">
<label for="additionnalsecurity" class="lead">Sécurité supplémentaire</label>
</div>
<div class="col-4">
<input type="checkbox" id="basketoptions" name="option-ecommerce" value="basketoptions">
<label for="basketoptions" class="lead">Panier avec options</label>
</div>
</div>
</form>
</div>
<div>
<p>Selected Items</p>
<div id="seleted-rows">
</div>
</div>
You seem to want something like this:
var labels = document.querySelectorAll("input:checked ~ label);
labels.foreach(function(label) {
console.log(label.textContent);
});
It isn't clear to me which paragraph you want these labels added to, so I used console.log and left it for you to put the label.texContent into your paragraph(s)
You have to gather all input[type=checkbox]:checked and the labels.
Using your example this could be done with:
var nodelistChecked = document.querySelectorAll("#ecommerce-form input[type=checkbox]:checked");
// nodelistChecked now contains a Node-list with all checked input elements
With this result you can gather the text from the labels with an Array.prototype.map function call. The result from a querySelectorAll()-call is a Nodelist and doesn't know forEach/map/or other Array-like function-calls, so you have to call it and convert it with map to an array.
var arrLabelText =
Array.prototype.map.call(nodelistChecked, function(node) {
return (document.querySelector('label[for='+node.id+']')
|| document.createElement('label')).textContent;
});
// arrLabelText contains an array with all selected labels
// the || new element is used, to avoid errors if no label is found
After this you can display the value in the element you want to display it:
document.querySelector("p.options-selected").innerText = arrLabelText.join(', ');
When you use jQuery it is a a bit shorter and it avoids some error-checking (like no label found):
function fillSelectedOptions() {
$("p.options-selected").text(
Array.prototype.slice.call( // depending on the jQuery version, this might be required
$("#ecommerce-form input[type=checkbox]:checked")
.map(function(i,node) { /* jQuery returns the index first */
return $('label[for="'+node.id+'"]').text()
})
).join(', ')
);
}
$("#ecommerce-form input[type=checkbox]").each(function(i, node) {
$(node).on('change', fillSelectedOptions);
});

Add/Remove values to field from checkbox values in Javascript

I have two fields: one is a checkbox (built with Scala), one is an input/text field. I am trying to add and remove values from the checkbox to the input field. I am trying to take multiple values and string together with a comma.
Here are my HTML fields:
<div class="column column1">
#for(service <- servicesList) {
<label><input type="checkbox" name="selectServices" value=#service.name><span>#service.name</span></label>
}
</div>
<input name="services" id="services">
I am using jQuery in a tag to try to record the onchange event:
$(document).ready(function(){
var $services = $('#services');
var $selectServices = $('#selectServices');
$selectServices.change(function(){
for (var i = 0, n = this.length; i < n; i++) {
if (this[i].checked) {
$services.val($services.val() + this[i].value);
}
else {
$services.val($services.val().replace(this[i].value, ""));
}
}
});
});
However, it seems that this will not "fire" when checking and unchecking the checkbox. I do not receive any errors or messages, so I am guessing it is not working or the code is incorrect.
I appreciate the help!
Try this example, you don't have to search and replace all the time, just set a new value:
$(function() {
$('input[name=selectServices]').on('change', function() {
$('#services').val($('input[name=selectServices]:checked').map(function() {
return this.value;
}).get());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="column column1">
<label>
<input type="checkbox" name="selectServices" value='1'><span>1</span>
</label>
<label>
<input type="checkbox" name="selectServices" value='2'><span>2</span>
</label>
<label>
<input type="checkbox" name="selectServices" value='3'><span>3</span>
</label>
<label>
<input type="checkbox" name="selectServices" value='4'><span>4</span>
</label>
</div>
<input name="services" id="services">
does the $(function() {} go into the $(document).ready(function(){}?
No, it is short-hand or equivalent for the same.
This is just an addition on #Halcyon his answer so you can create a nicer list, in stead of the replace method. #Halcyon is most definitely the correct answer why your check boxes aren't working. This is just a better solution handling values.
$(document).ready(function(){
var $services = $('#services');
var $selectServices = $('.selectServices');
$selectServices.change(function(){
updateServices();
});
function updateServices() {
var allVals = [];
$('.selectServices:checked').each(function() {
allVals.push($(this).val());
});
$services.val(allVals);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="column column1">
<label><input class="selectServices" type="checkbox" name="selectServices[]" value="Foo"><span>Foo</span></label>
<label><input class="selectServices" type="checkbox" name="selectServices[]" value="Bar"><span>Bar</span></label>
<label><input class="selectServices" type="checkbox" name="selectServices[]" value="FooBar"><span>FooBar</span></label>
</div>
<input name="services" id="services">
$('#selectServices') selects by id, there are no elements with that id. Ids must be unique so you can't use them in this case. I also wouldn't recommend using name because input elements should have unique names. You can use class:
<label><input type="checkbox" class="selectServices" ...
Then use .selectServices in jQuery. And:
var $selectServices = $('.selectServices');
$selectServices.change(function(){
if (this.checked) {
$services.val($services.val() + this.value);
} else {
$services.val($services.val().replace(this.value, ""));
}
});
Your code will fire if you add ID's to your inputs:
<input type="checkbox" name="selectServices" id="selectServices" value="" />
and
<input name="services" id="services" type="text" />

Javascript check bootstrap checkbox by id

I have the following form :
<form class="form-inline" role="form">
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox">
<label>
<input type="checkbox" name="discounting" onchange='handleChange(this);' id='check11' > Show only price-discounted products
</label>
</div>
</div>
</div>
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox" id='check21'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
</div>
</div>
</form>
I'd like to be able to check the second checkbox automatically with JavaScript once I check the first one. I tried using the following script :
<script>
function handleChange(cb) {
if(cb.checked == true) {
alert('Message 1');
document.getElementById("check21").checked = true;
} else {
alert('Message 2');
var x = document.getElementById("check21").disabled= false;
}
}
</script>
But it doesn't work since I think with bootstrap is a question of classes.
The problem as Didier pointed out is that you have two elements with the same ID:
<div class="checkbox" id='check21'>
and
<input type="checkbox" name="discounting" onchange='' id='check21'>
The call to document.getElementById('check21') will probably (because the behavior is undefined) return the first one, which in this case is the <div> element, not the checkbox.
You must not use the same ID on two HTML elements, so you need to change the ID on one or the other of them.
http://jsfiddle.net/uywaxds5/2/
I included boostrap as an external reference.
<div class="checkbox" id='check22'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
Fixing the duplicate id seems to work.
If it does not works, the issue might be in another part of your code.
Use a different name for the second radio button
<input type="checkbox" name="discounting21">
There can only be one selected radio button belonging to the same group(ie. name).

check/uncheck bootstrap checkboxes with jQuery

I've made another post yesterday and had no success with it. I will try now to reorder de idea and to ask again since I can't find the solution for this (I'm a newbie and I'm trying really hard).
The thing is that I'm working with this template based on Bootstrap, and this is the code that I can see directly from one of the files and that I'm using on my project:
html snippet:
<div class="hide" id="states">
<div class="control-group">
<label class="control-label">Seleccione</label>
<div class="controls">
<label class="checkbox span4">
<input type="checkbox" value="all" id="allstates" name="all"/>Todas
</label>
<label class="checkbox span4">
<input class="states" type="checkbox" value="Caba" id="" name="st[]"/>Ciudad Autónoma de Buenos Aires
</label>
<label class="checkbox span4">
<input class="states" type="checkbox" value="Buenos Aires" id="" name="st[]"/> Buenos Aires
</label>
<label class="checkbox span4">
<input class="states" type="checkbox" value="Catamarca" id="" name="st[]"/> Catamarca
</label>
</div>
</div>
</div>
After lot of searching I have founded when inspecting it that my code looks like this (snippet):
<div class="controls">
<label class="checkbox span4">
<div class="checker" id="uniform-allstates">
<span>
<input type="checkbox" value="all" id="allstates" name="all">
</span>
</div>Todas
</label>
<label class="checkbox span4">
<div class="checker">
<span>
<input class="states" type="checkbox" value="Caba" id="" name="st[]">
</span>
</div> Ciudad Autónoma de Buenos Aires
</label>
<label class="checkbox span4">
<div class="checker">
<span>
<input class="states" type="checkbox" value="Buenos Aires" id="" name="st[]">
</span>
</div> Buenos Aires
</label>
<label class="checkbox span4">
<div class="checker">
<span>
<input class="states" type="checkbox" value="Catamarca" id="" name="st[]">
</span>
</div> Catamarca
</label>
</div>
As you can see, another div and another span are added (seriously don't know why or how) so I'm guessing now it's some DOM problem the one I'm having.
This is snippet of my js file:
$('#allstates').click(function() {
$('.checkbox').find('span').addClass('checked');
});
So this function selects ALL the checkboxes I have (even though the ones that I don't want because they belong to another category).
I want to know why the div and span are added and how to select only the checkboxes that I want.
For that I've been trying code like this but no success:
test 1
$('#allstates').click(function() {
if ($(this).is(':checked')) {
$('span input').attr('checked', true);
} else {
$('span input').attr('checked', false);
}
});
test2
$('#allstates').click(function() {
$(".states").prop("checked",$("#allstates").prop("checked"))
});
and so other ones that I erased.
NOTE: No js errors are being displayed when inspecting
Also it is important to add prop to true on selecting checkboxes:
$("#checkAll").click(function(){
var check = $(this).prop('checked');
if(check == true) {
$('.checker').find('span').addClass('checked');
$('.checkbox').prop('checked', true);
} else {
$('.checker').find('span').removeClass('checked');
$('.checkbox').prop('checked', false);
}
});
Since I mentioned that this function checked all the checkboxes I had (even though the ones that were not supposed to be checked), I've been trying to look for the solution:
$('#allstates').click(function() {
$('.checkbox').find('span').addClass('checked');
});
But this is not what I wanted. I mentioned also that I noticed that the code was "different" when inspecting it (in Chrome with F12). So as #thecbuilder said, it changes in order to add style.
I realized that since code is changing... I had to change the class (checkbox) from which I was starting the "span tag" search, so I change class checkbox to id states and this is the result:
$('#allstates').click(function() {
if($(this).attr("checked")){
$('#states').find('span').addClass('checked');
}else{
$('#states').find('span').removeClass('checked');
}
});
Now it finally works.
I think you are looking for code like:
$(document).ready(function()
{
$("#allstates").on("change", function()
{
var checked = $(this).prop("checked");
$(this).parents(".controls")
.first()
.find("input[type=checkbox]")
.prop("checked", checked);
});
});
JsFiddle Example
When the state of the checkbox with the id allstates changes, get the checkbox value, find the first parent html element with a class called controls and then only update all the checkboxes in that element with the value of checked.
Simple bootstrap checkbox
<label><input type="checkbox" value="">Option 1</label>
When debug in Chrome dev tool, label look like
https://tinker.press/images/bootstrap-checkbox-label-2017-01-17_084755.png
To toogle checkbox state just set true|false on lable.control.checked
label.control.checked = false; //uncheck
label.control.checked = true; //check
Video demo https://youtu.be/3qEMFd9bcd8

javascript add and remove input value

there was a ton of different ways I seen to do this here on stackoverflow. However, I have tried them and can't get it to work.
Here is my current code.
http://jsfiddle.net/tech0925/C9Z8N/5/
Here is the javascript
function printcardCheck() {
if (document.getElementById('print_card').checked) {
document.getElementById('printvoucher-receiver').style.display = 'block';
document.getElementById('printvoucher-receiver').style.padding = '10px 0 0 0';
document.getElementById('print_cards').value = 'Add this value';
}
else document.getElementById('printvoucher-receiver').style.display = 'none';
}
See the fiddle link above.
http://jsfiddle.net/DerekL/Y4YNs/
I believe you want to do something like this. I will change it to native JS later.
<form>
<label>
<input type="radio" name="set1" value="A">A</label>
<label>
<input type="radio" name="set1" value="B">B</label>
<label>
<input type="radio" name="set1" value="C">C</label>
</form>
<div class="more" id="A">Some more options for A</div>
<div class="more" id="B">Some more options for B</div>
<div class="more" id="C">Some more options for C</div>
$("form input").change(function () {
$(".more").removeClass("show")
.filter("#" + $(this).val()).addClass("show");
});
there should only be one tag that id is 'print_card',and you have two,so when getElementById('print_card') will return the first one, that is the radio

Categories