I have these HTML elements:
<div>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="1100" class="myCars">
</div>
</form>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="0011" class="myCars">
</div>
</form>
</div>
Here are my checkboxes:
var elem = $('.myCars');
var car = ['car1', 'car2', "car3", "car4"];
var container = '<ul class="cars">';
for (i = 0; i < car.length; i++) {
container += '<li>' +
'<label class="container ' + car[i] + '">' +
'<input type="checkbox">' +
'<span class="checkmark"></span>' +
'</label>' +
'</li>';
}
container += '</ul>'
elem.closest('div').append(container);
After configuring the checkboxes I want to go through all inputs and set checkboxes as checked where input values are 1
I have tried this:
$('.myCars').each(function() {
var arr = $(this).val()
var array = arr.split('')
// array values:
Array(4)["1", "1", "0", "0"]
Array(4)["0", "0", "1", "1"]
$('.myCars').prop('checked', function(index) {
return +array[index] === 1;
});
})
How can I make it work?
You can code a checkbox to be pre-selected when the page loads using the checked boolean attribute. You simply have to add the word checked within the opening tag of the input element. Here's an example of a checkbox toggled on by default: HTML.
The value property sets or returns the value of the value attribute of a checkbox. For checkboxes, the contents of the value property do not appear in the user interface. The value property only has meaning when submitting a form.
One possible answer to your question is:
// select the .myCars elements, and bind the anonymous function
// of the on() method as the event-handler for the 'input'
// event:
$('.myCars').on('input', function() {
// retrieve the entered value, and then use String.prototype.trim()
// to remove leading/trailing white-space:
let enteredValue = $(this).val().trim(),
// convert that String into an Array, using
// String.prototype.split('') (as in your own posted code), then
// use Array.prototype.map() to iterate over every Array value
// with a call to the Number() function to convert the entered
// values to Numbers:
valueArray = enteredValue.split('').map(Number);
// navigate to the closest ancestor <div> element:
$(this).closest('div')
// find the <input type="checkbox"> elements:
.find('input[type=checkbox]')
// update the 'checked' property using the anonymous function,
// here we pass in the index of the current element:
.prop('checked', function(index) {
// we return the assessment of whether the array-value at
// the current index is exactly equal to 1 (if true this
// checks the check-box, if false it unchecks the box, or
// leaves it unchecked); this is why we used the call to
// Array.prototype.map(Number) earlier:
return valueArray[index] === 1;
});
// triggering the 'input' event so the checkboxes are updated
// on page load:
}).trigger('input');
var elem = $('.myCars');
var car = ['car1', 'car2', "car3", "car4"];
var container = '<ul class="cars">';
for (i = 0; i < car.length; i++) {
container += '<li>' +
'<label class="container ' + car[i] + '">' +
'<input type="checkbox">' +
'<span class="checkmark"></span>' +
'</label>' +
'</li>';
}
container += '</ul>'
elem.closest('div').append(container);
$('.myCars').on('input', function() {
let enteredValue = $(this).val().trim(),
valueArray = enteredValue.split('').map(Number);
$(this).closest('div').find('input[type=checkbox]').prop('checked', function(index) {
return valueArray[index] === 1;
});
}).trigger('input');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="1010" class="myCars">
</div>
</form>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="0011" class="myCars">
</div>
</form>
</div>
JS Fiddle demo.
An alternative to the above is the following, using just the plain DOM API. Note that in this approach I've made use of a <template>
element, rather than creating a string of HTML and also wrapped the entirety of your <form>
elements in one <form>
:
// using let, rather than var, as personal preference in this
// case; using document.querySelectorAll() to retrieve a
// non-live NodeList of the elements matching the supplied
// CSS selector:
let elems = document.querySelectorAll('.myCars'),
car = ['car1', 'car2', "car3", "car4"],
// using `document.createElement()` to create the <ul>:
container = document.createElement('ul');
// retrieving the content of the <template> element, accessed
// via its id (using a CSS selector), and the content property:
template = document.querySelector('#carCheckboxes').content,
// creating an InputEvent:
inputEvent = new Event('input'),
// defining the function to handle updates to the checkboxes,
// passing in the Event Object (here referred to as 'e'):
updateCheckmarks = (e) => {
// e.currentTarget is the element to which the event-listener
// is bound:
let source = e.currentTarget,
// here we retrieve the value of the current element,
// use String.prototype.trim() to remove the leading/
// trailing white-space, use String.prototype.split('')
// to convert the String to an Array of characters, and
// and finally a call to Array.prototype.map(Number)
// (as above) to convert the array-entries into numbers:
value = source.value.trim().split('').map(Number),
// here we find the check-boxes, navigating to the
// closest ancestor <div>:
checkmarks = source.closest('div')
// and finding the <input type="checkbox"> elements within:
.querySelectorAll('input[type=checkbox]');
// using Array.prototype.forEach() to iterate over that Array;
// check: the (user defined name for) the current <input> element,
// index: the (user defined name for) the index of the current
// <input> in the Array over which we're iterating:
checkmarks.forEach(function(check, index) {
// here we set the checked property to true/false,
// depending on the following assessment:
check.checked = value[index] === 1;
});
};
// iterating over the car Array, using Array.prototype.forEach():
car.forEach(function(el) {
// cloning the content template, including descendant elements
// using Node.cloneNode(true):
let model = template.cloneNode(true);
// appending that cloned node to the container:
container.appendChild(model);
})
// iterating over the elems Array:
elems.forEach(
// using an Arrow function; 'el' is the (user defined name
// for) the current element of the Array of elements:
(el) => {
// appending a cloned container Node to the closest
// ancestor <div> element:
el.closest('div').appendChild(container.cloneNode(true));
// binding the updateCheckmarks() function as the
// event-handler for the 'input' event:
el.addEventListener('input', updateCheckmarks);
// firing the inputEvent (created earlier) on the
// the current element, in order to trigger the
// function on page-load:
el.dispatchEvent(inputEvent);
});
let elems = document.querySelectorAll('.myCars'),
car = ['car1', 'car2', "car3", "car4"],
container = document.createElement('ul');
template = document.querySelector('#carCheckboxes').content,
inputEvent = new Event('input'),
updateCheckmarks = (e) => {
let source = e.currentTarget,
value = source.value.trim().split('').map(Number),
checkmarks = source.closest('div').querySelectorAll('input[type=checkbox]');
checkmarks.forEach(function(check, index) {
check.checked = value[index] === 1;
});
};
car.forEach(function(el) {
let model = template.cloneNode(true);
container.appendChild(model);
})
elems.forEach(
(el) => {
el.closest('div').appendChild(container.cloneNode(true));
el.addEventListener('input', updateCheckmarks);
el.dispatchEvent(inputEvent);
});
<template id="carCheckboxes">
<li>
<label>
<input type="checkbox"><span class="checkmark"></span>
</label>
</li>
</template>
<div>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="1010" class="myCars">
</div>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="0011" class="myCars">
</div>
</form>
</div>
With regards to your question, in comments, to another answer:
[How] can [I] use
onClick
to change each checkbox value? [Because] when [I] do that the values of checkboxes in all inputs are changing.
This is possible using:
// while this code - in my example - runs after the <input>
// elements are created, and appended to the DOM, we're
// binding the event-handler, using the on() method, to
// already-existing elements; so here we select the <form>
// element, and bind the anonymous function of the on()
// method as the 'change' event-handler:
$('form').on('change', function(e) {
// caching variables:
let form = $(this),
valuesInput = form.find('.myCars'),
// finding the <input type="checkbox"> elements within
// the <form> element:
checkboxValues = form.find('input[type=checkbox]')
// using map() - the jQuery method - to iterate over
// the collection to form an Array-like Object:
.map(function(index, el) {
// here we return 1 (if the current element is checked),
// or 0 if it is not checked:
return el.checked ? 1 : 0;
// using the get() method to convert the Array-like Object
// into an Array:
}).get()
// using join() to convert that array into a String, passing
// in an empty string ('') to act as the joining characters
// (if no argument is passed the default is a comma):
.join('');
// updating the value of the <input class="myCars"> element:
valuesInput.val(checkboxValues);
// firing the 'change' event on page-load so that the value of
// the text-input reflects the checked/unchecked state of the
// checkboxes:
}).trigger('change');
let elem = $('.myCars'),
car = ['car1', 'car2', "car3", "car4"],
container = '<ul class="cars">';
for (i = 0; i < car.length; i++) {
container += '<li>' +
'<label class="container ' + car[i] + '">' +
'<input type="checkbox">' +
'<span class="checkmark"></span>' +
'</label>' +
'</li>';
}
container += '</ul>'
elem.closest('div').append(container);
$('.myCars').on('input', function() {
let enteredValue = $(this).val().trim(),
valueArray = enteredValue.split('').map(Number);
$(this).closest('div').find('input[type=checkbox]').prop('checked', function(index) {
return valueArray[index] === 1;
});
}).trigger('input');
$('form').on('change', function(e) {
let form = $(this),
valuesInput = form.find('.myCars'),
checkboxValues = form.find('input[type=checkbox]').map(function(index, el) {
return el.checked ? 1 : 0;
}).get().join();
valuesInput.val(checkboxValues);
}).trigger('change');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="" class="myCars">
</div>
</form>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="0011" class="myCars">
</div>
</form>
</div>
References:
Array.prototype.forEach()
.Array.prototype.join()
.Array.prototype.map()
.HTMLTemplateElement
.HTMLTemplateElement.content
.Node.cloneNode()
.Number()
.String.prototype.split()
.String.prototype.trim()
.<template>
.closest()
.find()
.get()
.map()
.on()
.prop()
.trigger()
.val()
.You could it this way, I followed your logic and didn't change the basic code :
var car = ['car1', 'car2', "car3", "car4"];
$('.myCars').each(function() {
var arr = $(this).val()
var array = arr.split('')
var container = '<ul class="cars">';
for (i = 0; i < car.length; i++) {
var checked = array[i] == 1 ? 'checked' : ''
container += '<li>' +
'<label class="container ' + car[i] + '">' +
'<input type="checkbox"' + checked + ' >' +
'<span class="checkmark"></span>' +
'</label>' +
'</li>';
}
container += '</ul>'
$(this).closest('div').append(container);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="1100" class="myCars">
</div>
</form>
<form>
<div class="form-group">
<label class="control-label"></label>
<input type="text" value="0011" class="myCars">
</div>
</form>
</div>
Basically while going through each input, you create the container while putting checked
on each field having 1, as your seem to have wanted the logic to be around that :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With