Detect order in which checkboxes are clicked - javascript

I am trying to make a page that allows users to select 8 checkboxes from a total of 25.
Im wondering, how to detect the exact order in which they check them. I am using a plain html front page that will be verified by a form action pointing to a php page.
Im trying to get a result like (checkbox1,checkbox2,checkbox6,checkbox3,checkbox7,etc) for eight checkboxes, and the exact order in which they were clicked.
I think I have found what I am looking for,Im not too sure, but Im having trouble implementing it.
This is what I have so far, I guess my question is, what type of php do I need to gather this info once a user has submitted the form.
For the form I have:
<form id="form1" name="form1" method="post" action="check_combination.php">
<label id="lblA1"></label>
<input name="checkbox1" type="checkbox" value="a1" onclick="setChecks(this)"/> Option 1
<label id="lblA2"></label>
<input name="checkbox1" type="checkbox" value="a2" onclick="setChecks(this)"/> Option 2
<label id="lblA3"></label>
<input name="checkbox1" type="checkbox" value="a3" onclick="setChecks(this)"/> Option 3
<label id="lblA4"></label>
<input name="checkbox1" type="checkbox" value="a4" onclick="setChecks(this)"/> Option 4
</form>
For the Javascript I have:
<script type="text/javascript">
<!--
//initial checkCount of zero
var checkCount=0
//maximum number of allowed checked boxes
var maxChecks=8
function setChecks(obj){
//increment/decrement checkCount
if(obj.checked){
checkCount=checkCount+1
}else{
checkCount=checkCount-1
}
//if they checked a 4th box, uncheck the box, then decrement checkcount and pop alert
if (checkCount>maxChecks){
obj.checked=false
checkCount=checkCount-1
alert('you may only choose up to '+maxChecks+' options')
}
}
//-->
</script>
<script type="text/javascript">
<!--
$(document).ready(function () {
var array = [];
$('input[name="checkbox1"]').click(function () {
if ($(this).attr('checked')) {
// Add the new element if checked:
array.push($(this).attr('value'));
}
else {
// Remove the element if unchecked:
for (var i = 0; i < array.length; i++) {
if (array[i] == $(this).attr('value')) {
array.splice(i, 1);
}
}
}
// Clear all labels:
$("label").each(function (i, elem) {
$(elem).html("");
});
// Check the array and update labels.
for (var i = 0; i < array.length; i++) {
if (i == 0) {
$("#lbl" + array[i].toUpperCase()).html("first");
}
if (i == 1) {
$("#lbl" + array[i].toUpperCase()).html("second");
}
}
});
});
//-->
</script>
I have gotten the part that only allows 8 checkboxes to be checked, but Im stuck as to what I need to do to actually parse the data once it has been submitted to a page with a name like check_combination.php.
I would appreciate any help

create a hidden input field with the order
update this input field when something changes
you'll have the order ready to be processed by PHP

Related

How to confirm that all checkbox are checked before doing something?

My goal is If all checkbox are check the person can go further if not it will go to an excuse page.
I found this in jQuery:
$("input[type='checkbox'].itemCheck").change(function(){
var a = $("input[type='checkbox'].itemCheck");
if(a.length == a.filter(":checked").length){
console.log("Je vais sur la formulaire");
}
});
I tried it and it works but I need it in vanilla js so I tried to convert it but I just can't find out how to accomplish this.
I tried other logic to make it work but I can't figure how.
<input type="checkbox" name="verif" class="checkbox itemCheck">
<input type="checkbox" name="age" class="checkbox itemCheck">
<input type="checkbox" name="employed" class="checkbox itemCheck">
The vanilla JavaScript version of that jQuery code would be: (Added comments so you can understand what is happening)
// gets all the inputs on the page with type = "checkbox"
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
// loops through each checkbox
for (var i = 0; i < checkboxes.length; i++) {
// add an change event listener to each checkbox
checkboxes[i].addEventListener('change', function() {
// gets the checkboxes that are ticked (or "checked")
var checkboxes_ticked = document.querySelectorAll('input[type="checkbox"]:checked');
// check if the length of ticked checkboxes matches with the total checkboxes on the page
if (checkboxes_ticked.length === checkboxes.length) {
// all checkboxes where ticked! display your message
console.log("Je vais sur la formulaire");
}
});
}
Good luck.

How can I validate more than one checkbox on submission?

I have two sets of checkboxes, named pizzaBase and pizzaTopping. I want to validate my form so that on submission at-least 1 base and topping must be selected.
function main() {
var form = document.getElementById('formname');
form.addEventListener('submit', validate);
}
function validate(event) {
var form = document.getElementById('formname');
if(!form.pizzaBase.checked) {
alert("select a base");
event.preventDefault();
}
else if(!form.pizzaTopping.checked) {
alert("select topping");
event.preventDefault();
}
else {
return true;
}
}
Problems
Only first if statement works.
Form submits true if checkbox is checked and then unchecked before
submission.
Doesn't validate, doesn't work.
Where am I going wrong?
Thank you GG for pointing out JS is working, I have HTML below if someone wouldn't mind correcting me. I basically have two identical versions of the below code, one for bases and the other toppings.
**
HTML
**
<section>
<h2> Bases </h2>
<p><input type="checkbox" name="pizzaBase" data-price="1.00" data-human-desc = "Small" value="Small"> Small (£1.00) </p>
<p><input type="checkbox" name="pizzaBase"data-price="1.50" data-human-desc = "Medium" value="Medium"> Medium (£1.50) </p>
<p><input type="checkbox" name="pizzaBase" data-price="2.50" data-human-desc = "Large"value="Large"> Large (£2.50) </p>
<p><input type="checkbox" name="pizzaBase" data-price="3.50" data-human-desc = "XLarge"value="XLarge"> XLarge (£3.50) </p>
</section>
Not sure if I should ask a separate question here, but this is my messy HTML. Is it the sections? I was trying to split each set of check boxes (bases, toppings) into two separate sections so used this tag.
Any ideas?
When you have multiple inputs with the same name, form.elementName will be an array-like list of elements.
The list won't have a checked property. Each item within it will.
You need to loop over the list and check to see if any of the elements are checked.
function areAnyChecked(list) {
for (var i = 0; i < list.length; i++) {
if (list[i].checked) {
return true;
}
}
return false;
}
if(! areAnyChecked(form.pizzaBase)) {
...

jQuery - serializeArray() is not getting the value of the checked checkbox

I have a checkbox in a form that acts as a flag.
In order to do it, I added a hidden input element so that if the checkbox is not checked, something will still be saved
<form action="">
...
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes">
...
</form>
The problem I am having is that when I
check the checkbox
then run jQuery.serializeArray() on the form
the value set for the foo element is "no"
Object { name="foo", value="no"}
Shouldn't serializeArray() emulate browser behaviour? If so, shouldn't it return "yes" if checkbox is checked?
I am using jQuery v1.10.2
In a short word: No. The serializeArray method only returns the checkbox in the case it is checked. Thus, it will ignore it as long as it remains unchecked.
In case you checked it, though, it wiill return the value of your input directly.
Check out the demo at http://api.jquery.com/serializearray/ .
Using serializeArray on a form with multiple inputs of the same name returns more than one object for each element (if checked). This means that the following HTML will return the following object. So the data in question is there and is available. Because of this I'm assuming that you're attempting to either manipulate the data to be in 1 object or you're posting it to a server which is only taking into account the data from the first value with that key. You just need to make sure that any checkbox element takes precedence.
Returned Object:
[
{
name:"foo",
value:"no"
},
{
name:"foo2",
value:"no"
},
{
name:"foo2",
value:"yes"
}
]
HTML:
<form>
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes" />
<input type="hidden" name="foo2" value="no" />
<input type="checkbox" name="foo2" value="yes" checked />
</form>
JS:
console.log($('form').serializeArray());
DEMO
Another way you can do this is get rid of the hidden fields and before you submit the form go through each unchecked checkbox and check if there is any data in the serializeArray with the same name. If not just add it in there as a off.
$('#submit').on('click', function(){
var arr = $('form').serializeArray(),
names = (function(){
var n = [],
l = arr.length - 1;
for(; l>=0; l--){
n.push(arr[l].name);
}
return n;
})();
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, names) === -1){
arr.push({name: this.name, value: 'off'});
}
});
console.log(arr);
});
DEMO
Using the same name for multiple fields is problematic at best and there is no standardized way that front end systems, or back end systems, will handle it.
The only reason to use the same name is if you are trying to pass some kind of a default value, like you are in the case below, where you are doing a simple yes/no.
What you want, to emulate the browser, is serialize method, not the serializeArray.
I added the form to a page -- from my console:
JSON.stringify(f.serializeArray());
"[{"name":"foo","value":"no"}]"
NO checkmark
JSON.stringify(f.serialize());
""foo=no""
Checkmark
JSON.stringify(f.serialize());
""foo=yes&foo=no""
If your back end system gets confused and is picking up the wrong value, reverse the order of your checkmark and hidden element.
FACT: jQuery serializeArray() does not include unchecked checkboxes that probably we DO need them sent to server (no problem for radios though).
SOLUTION: create a new serialize:
//1. `sel` any collection of `form` and/or `input`, `select`, `textarea`
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes
function serialize(sel) {
var arr,
tmp,
i,
$nodes = $(sel);
// 1. collect form controls
$nodes = $nodes.map(function(ndx){
var $n = $(this);
if($n.is('form'))
return $n.find('input, select, textarea').get();
return this;
});
// 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1
// or, we end up with "on" when checked
$nodes.each(function(ndx, el){
if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
if((el.value === undefined) || (el.value == ''))
el.value = 1;
}
});
// 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
arr = $nodes.serializeArray();
tmp = [];
for(i = 0; i < arr.length; i++)
tmp.push(arr[i].name);
// 4. include unchecked checkboxes
$nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
if(tmp.indexOf(this.name) < 0){
arr.push({name: this.name, value: ''});
}
});
return arr;
}
The reason we assigned empty string to unchecked checkboxes is because a checked one will submit it's value to server which is set in html and can be a zero!!!
So, an empty value denotes a unchecked checkbox.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
<input type="email" placeholder="email" name="email"><br>
<input type="text" placeholder="firstname" name="firstname"><br>
<input type="text" placeholder="lastname" name="lastname"><br>
<input type="number" placeholder="zip_code" name="zip_code"><br>
<input type="checkbox" name="general" value="true"> general<br>
<input type="checkbox" name="marketing" value="true"> marketing<br>
<input type="checkbox" name="survey" value="true"> survey<br>
<button type="submit">save</button>
</form>
<script>
$(document).ready(function() {
$('#formReg').on('submit', function(e){
// validation code here
e.preventDefault();
var values = {};
$.each($('#formReg').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, values) === -1){
values[this.name] = $(this).prop('checked')
}
});
console.log(values)
});
});
</script>
serializeArray doesn't return unchecked checkbox. I try this instead of serializeArray:
$('input, select, textarea').each(
function(index){
var input = $(this);
alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') +
'Value: ' + input.val());
}
);

jquery validation

I have a poll with a couple a questions. Here is html code
<form id="pool">
<div class="questions>
<input type="radio" name="sex">Male
<input type="radio" name="sex">Female
</div>
<div class="questions>
<input type="radio" name="hair">Brown
<input type="radio" name="hair">Blonde
</div>
.... a lot of qestions div's
</form>
What to do so after the form is submitted to be sure that there is a checked radio button in all div`s ?
If you know how many groups you have you can just do:
if($('#pool input:radio:checked').length < numGroups){
// At least one group isn't checked
}
Otherwise you need to count the number of groups first. I can't think of any way to do this better then:
var rgroups = [];
$('#pool input:radio').each(function(index, el){
var i;
for(i = 0; i < rgroups.length; i++)
if(rgroups[i] == $(el).attr('name'))
return true;
rgroups.push($(el).attr('name'));
}
);
rgroups = rgroups.length;
if($('#pool input:radio:checked').length < rgroups)
alert('You must fill in all the fields.');
else
alert('Thanks!');
set default values or create handler for submit button and check if some values was checked. If no radio button is checked, show error message and do not submit form ( return false)
Untested code, but this is the idea:
if($('#pool').children().length == $('pool
div').find('#pool input:radio:selected').length) {
//do stuff
}
You can use the jquery validate plugin
from my experience this plugin is very efficient

How to pass a checkbox array from form to results page

Im trying to build a page that will allow a user to select a maximum of 8 out of 20 checkboxes, in a specific order, on a single form.
Im trying to make a page that will only be viewable if the right sequence of checkboxes are clicked, a neat way to let only those who have the checkbox sequence in on a certain part of my website.
What I need to know is, once they select the checkboxes, how can I not only pass it on to a test page to view the data, but also, how to pass the data showing the exact sequence of how the checkboxes were checked.
Example: The check boxes are numbered one from twenty. If they select checkbox1,checkbox4,checkbox2,checkbox7,etc, Id like the data to be passed on in the exact order checked, 1,4,2,7,etc
So far, I have have the form done, Id like to know what I need to add to the javascript in order to pass the variables on exactly as checked.
Here is the Javascript:
<script type="text/javascript">
<!--
//initial checkCount of zero
var checkCount=0
//maximum number of allowed checked boxes
var maxChecks=3
function setChecks(obj){
//increment/decrement checkCount
if(obj.checked){
checkCount=checkCount+1
}else{
checkCount=checkCount-1
}
//if they checked a 4th box, uncheck the box, then decrement checkcount and pop alert
if (checkCount>maxChecks){
obj.checked=false
checkCount=checkCount-1
alert('you may only choose up to '+maxChecks+' options')
}
}
//-->
</script>
<script type="text/javascript">
<!--
$(document).ready(function () {
var array = [];
$('input[name="checkbox"]').click(function () {
if ($(this).attr('checked')) {
// Add the new element if checked:
array.push($(this).attr('value'));
}
else {
// Remove the element if unchecked:
for (var i = 0; i < array.length; i++) {
if (array[i] == $(this).attr('value')) {
array.splice(i, 1);
}
}
}
// Clear all labels:
$("label").each(function (i, elem) {
$(elem).html("");
});
// Check the array and update labels.
for (var i = 0; i < array.length; i++) {
if (i == 0) {
$("#" + array[i].toUpperCase()).html("1");
}
if (i == 1) {
$("#" + array[i].toUpperCase()).html("2");
}
if (i == 2) {
$("#" + array[i].toUpperCase()).html("3");
}
if (i == 3) {
$("#" + array[i].toUpperCase()).html("4");
}
if (i == 4) {
$("#" + array[i].toUpperCase()).html("5");
}
if (i == 5) {
$("#" + array[i].toUpperCase()).html("6");
}
if (i == 6) {
$("#" + array[i].toUpperCase()).html("7");
}
if (i == 7) {
$("#" + array[i].toUpperCase()).html("8");
}
}
});
});
//-->
</script>
Here is an example of the input fields:
<td width="20" align="center" valign="middle"><label id="1"></label><input name="checkbox" type="checkbox" value="1" onclick="setChecks(this)"/></td>
<td width="20" align="center" valign="middle"><label id="2"></label><input name="checkbox" type="checkbox" value="2" onclick="setChecks(this)"/></td>
<td width="20" align="center" valign="middle"><label id="3"></label><input name="checkbox" type="checkbox" value="3" onclick="setChecks(this)"/></td>
<td width="20" align="center" valign="middle"><label id="4"></label><input name="checkbox" type="checkbox" value="4" onclick="setChecks(this)"/></td>
<td width="20" align="center" valign="middle"><label id="5"></label><input name="checkbox" type="checkbox" value="5" onclick="setChecks(this)"/></td>
and so on up to 20
I am a noobie, and I pieced together what I have so far, from various sources.
I am having trouble understanding how to grab the array data from the second snippet of javascript, and passing it along to a php page I need to create that will echo it in order to test to see if it is indeed passing along the variables in the exact order they were clicked.
Any help would be appreciated.
There is a very similar question here that asks for a way to detect the order of selected checkboxes.
Full code in jsFiddle
Select/Unselect the checkbox then click the textarea to see your array.
What I did there is simply add new element on the array when user select a checkbox. If he deselect it will find the index by its value and remove from the array.
Then you can check the length using arrayName.length, if it matches your condition then you can submit.
Just push the IDs of the checkboxes onto an Array, then convert that to a string and post it back. Array[0] will be the first, etc. If Array.length > 7, disable the other checkboxes that are not in the array. That should be simple enough.

Categories