I'm trying to get checked checkboxes in an array but I want them to be ordered in the order they are selected.
For example, I have 3 checkboxes—
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck[]">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck[]">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck[]">
—and I selected Check 2 then Check 3 then Check 1.
I want result to be in array like this ('2','3','1')
I use this function but it's not get them to order
var list = new Array();
$('input[name="mycheck"]:checked').each(function() {
list.push([$(this).val()]);
});
console.log(list);
CodePudding user response:
You can use this way
var list = new Array();
$('input').on("click", function (e) {
if ($(this).is(':checked')) {
list.push([$(this).val()]);
}
console.log(list);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck">
Hope it will be work :)
CodePudding user response:
Added class .chx
to each checkbox since it's the easiest way to access a group of tags -- I can't think of a reason why you shouldn't. Basically you need to use an event handler to pickup values that are derived from the user interacting with the checkboxes.
Details are commented in example
// Define an empty array
let checks = [];
// Bind each checkbox to the change event
$('.chx').on('change', function() {
// If the changed checkbox is checked
if (this.checked) {
// Add the checkbox's value to the array
checks.push( $(this).val());
} else {
// Otherwise add a negative value of the checkbox to the array
checks.push(-$(this).val());
}
console.log(checks);
});
/* Added the negative numbers because there's two states a checkbox is in
and if it's important to know the order of what was checked then it's
probably important to know what state each one is in as well.
*/
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" class='chx' value="1" name="mycheck[]">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" class='chx' value="2" name="mycheck[]">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" class='chx' value="3" name="mycheck[]">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
CodePudding user response:
This answer assumes values are unique.
When checked, push the value to an array. When unchecked, remove it from the array.
const selections = [];
$('[name="mycheck[]"]').on('change', function (){
// if checked, add it to the array
if (this.checked) {
selections.push(this.value);
} else {
// if not checked, remove the value from the array
const index = selections.indexOf(this.value);
if (index > -1) selections.splice(index, 1);
}
console.log(selections);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck[]">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck[]">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck[]">
CodePudding user response:
Using jQuery on()
method to capture the Javascript change
event, when the the state of a checkbox changes, and the push()
method to add the checkbox value to the list
array if checked, or the grep()
method to remove checkbox values for checkboxes that, upon change, are unchecked.
var list = new Array();
$('input').on("change", function(e) {
let boxval = $(this).val();
if ($(this).is(':checked')) {
list.push(boxval);
}
else {
list = $.grep(list, function(item) {
return boxval !== item;
});
}
console.log(list);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck">
And for good measure, a vanilla Javascript version which...
...uses querySelectorAll()
to collect the target checkboxes then forEach()
to iterate the collection in order to add a change
event listener to each. Upon the change
event the checkbox value is push()
'ed to the list
array if the checked state of the checkbox is true
, and, alternatively, remove the checkbox value from the list
array if the checked state of the checkbox is false
. Array method filter
is used to remove unchecked boxes from the list
array.
var list = [];
document.querySelectorAll('input[name="mycheck"]').forEach(function (box) {
box.addEventListener("change", function (evt) {
let boxval = evt.target.value;
if ( true === box.checked ) {
list.push(boxval);
}
else {
list = list.filter(function(val) {
return boxval !== val;
});
}
console.log(list);
});
});
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck">
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck">
CodePudding user response:
Be careful about state in general: User interaction is only one way to change state, and often there are more kinds of interaction possible than you can imagine.
Things often overlooked are state being set programmatically, for example via a “check all” checkbox, and keyboard interaction.
So in general it is better to listen on change
than on click
, and to work with the actual state when creating the final list. To symbolise that I created a button.
Also, you’d need to take into account that users can uncheck and check again.
The approach here is to track the order in which each checkbox was checked, and then finally sort the actually checked checkboxes by their position in that kind of log.
const checkedLog = [];
$('input[type="checkbox"]').on("change", function(e) {
if (this.checked) {
checkedLog.push(this.value);
}
// only track order in which they were checked, not unchecked
});
$('button').on('click', function() {
// get all actually checked values
const vals = [];
$('input:checked').each(function() {
vals.push(this.value);
})
// sort actually checked values by last log entry
const reverseLog =
vals.sort((a, b) => checkedLog.lastIndexOf(a) - checkedLog.lastIndexOf(b));
console.log(vals);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="check-1">check 1</label>
<input type="checkbox" id="check-1" value="1" name="mycheck">
<label for="check-2">check 2</label>
<input type="checkbox" id="check-2" value="2" name="mycheck" checked>
<label for="check-3">check 3</label>
<input type="checkbox" id="check-3" value="3" name="mycheck">
<button>get sorted values</button>
This is using Array’s sort method and using the log of check events to compare which checkbox should come first.
lastIndexOf
is used because the last time the box got checked counts.
You could also remove checkboxes from the log once they get unchecked, then lastIndex()
would suffice.
Should there be one box checked that did not trigger a change
event, lastIndexOf()
would return -1 and that value would be first in the list.