How to check if Checkboxes and ranges are checked/set to max? - javascript

here you can see what I want to implement
Hey I'm stuck at this: I want that the launch button gets enabled after all checkboxes are checked and all ranges are set to max.
But something like this won't work:
while(checkboxes.unchecked && ranges.value !== '100') {
if (checkboxes.checked && ranges.value == '100')
document.getElementById('launch').disabled = false;
}
Any tipps for implementation?

The example below uses the HTMLFormElement interface to reference <form>, <input>, and <button> (<fieldset> and <legend> as well if it was needed), you should notice it's terse syntax compared to the standard HTMLElement interfaces.
Solution
Wrap everthing in a <form> tag if you haven't already. Also assign a [name] shared between all ranges and a different [name] shared between all checkboxes. Reference it, then bind the event handler (ie allFields(e)) to the <form> and listen for the "change" event.
const form = document.forms[0];
form.onchange = allFields;
By default all event handlers pass the Event Object (e, event, evt, etc). Reference the <form> with this keyword coupled with the .elements property. That will result in a HTMLCollection of all <input>, <button>, <fieldset>, and <legend> within <form>.
function allFields(e) {
const io = this.elements;
...
Next, reference all form controls assigned [name="chx"] (all checkboxes) and collect them into a HTMLCollection then convert it into a real array. Do so for all [name="rang"] (all ranges) as well.
const chx = [...io.chx];
const rng = [...io.rng];
Then run each array through the Array method .every() which will return true if all elements in the array are true for a given conditional. The condition for the ranges is .value === '100' and for the checkboxes is .checked === true.
let allChecked = chx.every(c => c.checked === true);
let allMaxRange = rng.every(r => r.value === '100');
Finally compare allChecked and allMaxRange.
if (allChecked === true && allMaxRange === true) {
io.launch.disabled = false;
} else {
io.launch.disabled = true;
}
const form = document.forms[0];
form.onchange = allFields;
function allFields(e) {
const io = this.elements;
const chx = [...io.chx];
const rng = [...io.rng];
let allChecked = chx.every(c => c.checked === true);
let allMaxRange = rng.every(r => r.value === '100');
if (allChecked === true && allMaxRange === true) {
io.launch.disabled = false;
} else {
io.launch.disabled = true;
}
};
input,
button {
display: inline-block;
font-size: 100%;
line-height: 1.15;
}
button {
cursor: pointer;
}
fieldset {
height: max-content;
}
[type="range"] {
width: 80%;
}
[type="checkbox"] {
margin-top: -20px;
}
<form>
<fieldset>
<legend>
<button id='launch' type='button' disabled>Launch</button>
</legend>
<input name='chx' type='checkbox'>
<input name='rng' type='range' value='100'><br>
<input name='chx' type='checkbox' checked>
<input name='rng' type='range' value='100'><br>
<input name='chx' type='checkbox' checked>
<input name='rng' type='range' value='100'><br>
<input name='chx' type='checkbox' checked>
<input name='rng' type='range' value='100'><br>
<input name='chx' type='checkbox' checked>
<input name='rng' type='range' value='100'><br>
<input name='chx' type='checkbox' checked>
<input name='rng' type='range' value='100'><br>
</fieldset>
</form>

Try this approach :
You need to iterate over all checkbox elements as well as range elements.
Then use a flag variable to verify if all checkboxes/ranges are checked/max.
Use onchange/oninput event handlers. -> while loop is not necessary

Related

Add/remove style after click label/input[radio] problem

I have a problem with a function that selects active items. There are some input/label fields with sectoins ( one section - one active/clicked element )
It only works when I double-click. If I click one time then no result. I can set setTimeout for that code and then works but not always.
Example:
var radios = document.querySelectorAll('#calculator input[type=radio]');
var label = document.querySelectorAll("#calculator label");
function active(e) {
radios.forEach((el,index) => {
if(el.checked === true) {
console.log('true');
label[index].classList.add('active');
} else {
console.log('false');
label[index].classList.remove('active');
}
})
}
Example html field:
<input id="p75" type="radio" name="geodesic_size" value="11250" >
<label for="p75">
<input id="p30" type="radio" name="geodesic_size" value="5626" checked>
<label for="p30">
Not sure if this is what you need, but here's an example of toggling the active class when the checked input changes:
const radios = document.querySelectorAll('input[type="radio"]');
const label = document.querySelectorAll("label");
function active(e) {
radios.forEach((el,index) => {
if(el.checked === true) {
console.log('true');
label[index].classList.add('active');
} else {
console.log('false');
label[index].classList.remove('active');
}
})
}
radios.forEach(el => {
el.addEventListener('change', active);
})
.active {
color: red;
}
<input id="p75" type="radio" name="geodesic_size" value="11250" >
<label for="p75">First</label>
<input id="p30" type="radio" name="geodesic_size" value="5626" checked>
<label for="p30" class="active">Second</label>
The other answers seem to work fine, I would just add a couple suggestions:
First, you can also access the label(s) associated to an element with HTMLInputElement.labels. Using el.labels[0] would IMO be a bit more robust than relying on the index of the radio button and the label to be the same.
If all you need to do is toggle an active class like this, you could accomplish the same thing with CSS only by using the adjacent sibling combinator (+) and get rid of all the JavaScript:
input:checked + label {
color: red;
}
<div>
<input id="p75" type="radio" name="geodesic_size" value="11250">
<label for="p75">p75</label>
</div>
<div>
<input id="p30" type="radio" name="geodesic_size" value="5626" checked>
<label for="p30">p30</label>
</div>
There was no major change I have just add <div id="calculator"></div>.
As #calculator input[type=radio] this means select all input with type equals to radio, which are children of id #calculator.
Then selected all inputs loop through them attach onclick event and put you logic for active() function there.
To see visual effect added .active{background-color:red;} css.
var radios = document.querySelectorAll('#calculator input[type=radio]');
var label = document.querySelectorAll("#calculator label");
radios.forEach(radioBtn => {
radioBtn.onclick = function() {
radios.forEach((el, index) => {
console.log(el.checked);
if (el.checked === true) {
console.log('true');
label[index].classList.add('active');
} else {
console.log('false');
label[index].classList.remove('active');
}
})
};
})
.active {
background-color: red;
}
<div id="calculator">
<input id="p75" type="radio" name="geodesic_size" value="11250">
<label for="p75">p75</label>
<input id="p30" type="radio" name="geodesic_size" value="5626" checked>
<label for="p30">p30</label>
</div>
Unfortunately I noticed one problem with event 'change' for input fields. When I click on default element ( input default checked ) then there is no change but it is normal because the state has not changed and the event did not call the function active(). Of course we can add window.onload with that function to change the styles of the clicked element. But I modified the script to add an async function toogle() for checked elements and works very well.
function active() {
radios.forEach(el => {
if(el.checked === true) {
toogle(el);
} else {
el.labels[0].classList.remove('active');
el.labels[0].setAttribute('data-before', '');
}
});
}
async function toogle(el) {
var f = await new Promise(resolve => {
el.labels[0].classList.add('active');
el.labels[0].setAttribute('data-before', '\uf058');
resolve('resolved');
})
console.log(f);
}

How to show div, if one of the checkboxes is checked (with a different name on each checkbox)?

I am trying to show div if one of the two checkboxes is checked. I found it in some article but with the same name, I am using a different name for each checkbox to store it into mysql. My current javascript code is
document.addEventListener('change', function(jj) {
function jj() {
if ((document.getElementById('jj1_ikk').checked) || (document.getElementById('jj2_ikk').checked)) {
document.getElementById('jsa').style.display="block";
} else {
document.getElementById('jsa').style.display="none";
}
}
})
the input fields are
<input type="checkbox" id="jj1_ikk" name="jj1_ikk" /><label for="jj1_ikk">A</label>
<input type="checkbox" id="jj2_ikk" name="jj2_ikk" /><label for="jj2_ikk">B</label>
where jj1_ikk and jj2_ikk are the checkboxes id, and jsa is the div that I want to do show/hide.
I hope my description is clear, thank you.
You can put two check box in span and check changes onclick span like this
HTML
<span onclick="CheckChanges()">
<input type="checkbox" id="jj1_ikk" name="jj1_ikk" /><label for="jj1_ikk">A</label>
<input type="checkbox" id="jj2_ikk" name="jj2_ikk" /><label for="jj2_ikk">B</label>
</span>
<div id="jsa">This is the element that will be shown if both checkboxes aren't checked</div>
JavaScript
var aCheckBox = document.getElementById("jj1_ikk")
var bCheckBox = document.getElementById("jj2_ikk")
function CheckChanges() {
if (aCheckBox.checked == true || bCheckBox.checked == true) {
document.getElementById("jsa").style.display = "block"
} else {
document.getElementById("jsa").style.display = "none"
}
}
You did a mistake when adding the handler for the change event defining two nested functions. Plus I added the event handler only once the document was loaded. You can test the code in this snippet:
//when the document has been loaded, adds the event handlers to the checkboxes
document.addEventListener("DOMContentLoaded", () => {
document.addEventListener('change', () => addHandlers());
});
/**
* Adds handler for the change event on both checkboxes
*/
function addHandlers(){
let jj1 = document.getElementById('jj1_ikk');
let jj2 = document.getElementById('jj2_ikk');
jj1.addEventListener('change', updateMsgVisibility);
jj2.addEventListener('change', updateMsgVisibility);
}
/**
* Show/Hide #jsa based on checkboxes status
*/
function updateMsgVisibility(){
let jj1 = document.getElementById('jj1_ikk');
let jj2 = document.getElementById('jj2_ikk');
if ( (jj1 && (jj1.checked)) || (jj2 && (jj2.checked)) ) {
document.getElementById('jsa').style.display="block";
} else {
document.getElementById('jsa').style.display="none";
}
}
<input type="checkbox" id="jj1_ikk" name="jj1_ikk" /><label for="jj1_ikk">A</label>
<input type="checkbox" id="jj2_ikk" name="jj2_ikk" /><label for="jj2_ikk">B</label>
<div id="jsa" style="display:none;">This is the element that will be shown if both checkboxes aren't checked</div>

Why is the checked checkbox null?

Below it's a very simple javascript function. When I click the button it's supposed to show me the value of the checked checkbox but it't prints out an error in the console saying the checkedValue is null?
I tried looping through the checkboxes and getting the checked one and i get the same error. I would really appreciate some help!
<body>
<p id='txt'>here: </p>
<button id="btn" type="button" onclick="ok" >Click </button>
<input type="checkbox" class="ckb" value="1">one
<input type="checkbox" class="ckb" value="2">two
<input type="checkbox" class="ckb" value="3">three
<script>
var checkedValue = document.querySelectorAll('.ckb').checked;
document.getElementById('btn').addEventListener('click', function(){
document.getElementById('txt').innerText = checkedValue.value ;
});
</script>
</body>
Looping through the checkboxes
var checkedValue;
var inputElements = document.querySelectorAll('.ckb');
for(var i=0; i < inputElements.length; i++){
if(inputElements[i].checked===true){
checkedValue = inputElements[i];
break;
}
}
With some minor adjustments, this should be what you are looking for.
<body>
<p id='txt'>here: </p>
<button id="btn" type="button">Click </button>
<input type="checkbox" class="ckb" value="1">one
<input type="checkbox" class="ckb" value="2">two
<input type="checkbox" class="ckb" value="3">three
<script>
document.getElementById('btn').addEventListener('click', function()
{
var chkbxElements = document.getElementsByClassName("ckb");
for (element of chkbxElements)
{
if (element.checked)
{
document.getElementById('txt').innerText = `here: ${element.value}`;
}
}
});
</script>
</body>
To directly address your question, the problem lies in the code:
// this line returns a NodeList of all elements matching the
// supplied CSS selector ('.ckb'), this NodeList has no
// 'checked' property, and so will ultimately return
// undefined.
var checkedValue = document.querySelectorAll('.ckb').checked;
document.getElementById('btn').addEventListener('click', function(){
// here you try to access the 'value' property of the undefined
// Object returned earlier, which returns null:
document.getElementById('txt').innerText = checkedValue.value ;
});
As an alternative, I would suggest something like the following:
// using a const to declare the element, since it's unlikely
// you'll want to change which element triggers the function:
const button = document.getElementById('btn');
//here we bind the anonymous function of EventTarget.addEventListener()
// to the 'click' event upon that identified <button> element, using
// Arrow function syntax (since we don't require access to the
// 'this'):
button.addEventListener('click', (e) => {
// here we retrieve all elements which are checked (using the
// CSS pseudo-class ':checked') and have the class of 'ckb':
let checked = document.querySelectorAll('.ckb:checked'),
// retrieving the element into which the output should be
// displayed:
output = document.querySelector('#txt');
// here we update the text-content (using the textContent property)
// and set it equal to the results returned from:
// first converting the NodeList of checked
// into an Array, using Array.from(), using the
// Array.prototype.map() method to iterate over that
// Array:
output.textContent = Array.from(checked).map(
// returning the value of the element ('el'):
(el) => el.value
// joining those array elements together into a String, using
// Array.prototype.join(), and appending a period for
// grammatical correctness:
).join(', ') + '. ';
});
const button = document.getElementById('btn');
button.addEventListener('click', (e) => {
let checked = document.querySelectorAll('.ckb:checked'),
output = document.querySelector('#txt');
output.textContent = Array.from(checked).map(
(el) => el.value
).join(', ') + '. ';
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
#txt::before {
content: 'Checked items: '
}
#txt:empty::before {
color: #999;
content: 'No items checked.';
}
input {
margin-right: 0.5em;
}
<p id='txt'></p>
<button id="btn" type="button">Click</button>
<label>
<input type="checkbox" class="ckb" value="1">one
</label>
<label>
<input type="checkbox" class="ckb" value="2">two
</label>
<label>
<input type="checkbox" class="ckb" value="3">three
</label>
JS Fiddle demo.
Note that I've also wrapped each <input> element within a <label> element, in order that clicking the text associated with each <input> also toggles the checked state of that element.
Using CSS generated content, I've taken the liberty of giving an indication of the current state; when the <p id="txt"> element is empty (matching the :empty pseudo-class, containing not even white-space) it shows the message "No items checked"), this may — or may not — represent a user-experience/interface improvement, but adjust to your own preference.
Further we move the event-binding out of the HTML mark-up, in order to reduce clutter in that mark-up, and reduce complications when it comes to future maintenance of the page.
You could, of course, bind the change event on the <input> elements themselves:
const inputs = document.querySelectorAll('.ckb'),
output = () => {
let results = document.querySelector('#txt'),
checked = Array.from(inputs).filter(
(el) => el.checked
);
results.textContent = checked.length === 0 ? '' : checked.map(
(el) => el.value
).join(', ') + '. ';
};
inputs.forEach(
(el) => el.addEventListener('change', output)
);
// getting a NodeList of all elements matching the supplied
// CSS selector:
const inputs = document.querySelectorAll('.ckb'),
// defining the function to bind as the event-
// handler, using Arrow function syntax:
output = () => {
// retrieving the element to which the results
// should be inserted:
let results = document.querySelector('#txt'),
// using Array.from() to convert the 'inputs'
// variable to an Array, and then calling
// Array.prototype.filter() to filter that
// Array returning a new one:
checked = Array.from(inputs).filter(
// 'el' refers to the current Array-element
// (node) of the Array we're iterating over,
// el.checked is a Boolean, and
// Array.protoype.filter() retains those Array-
// elements the assessment of which returns a
// true/truthy value (discarding those which do
// not):
(el) => el.checked
);
// here we use a ternary - conditional operator - to first
// check if the length of the checked Array is exactly zero;
// if so we return an empty string; otherwise we return
// the map of Array-element (node) values joined - as above -
// with a comma and space, with an appended period:
results.textContent = checked.length === 0 ? '' : checked.map(
(el) => el.value
).join(', ') + '. ';
};
// iterating over the NodeList of .ckb elements, with an
// Arrow function, and in each iteration we bind the
// output() function as the event-handler for the 'change'
// event:
inputs.forEach(
(el) => el.addEventListener('change', output)
);
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
#txt::before {
content: 'Checked items: ';
}
#txt:empty::before {
color: #999;
content: 'No items checked.';
}
<p id='txt'></p>
<label>
<input type="checkbox" class="ckb" value="1">one
</label>
<label>
<input type="checkbox" class="ckb" value="2">two
</label>
<label>
<input type="checkbox" class="ckb" value="3">three
</label>
JS Fiddle demo.
References:
Arrow functions.
Array.from().
Array.prototype.join().
Array.prototype.map().
document.getElementById().
document.querySelector().
document.querySelectorAll().

Removing value from array according to index using splice()

I have 4 checkboxes. I add values of them to an array on check. It looks like this.
Here are the four checkboxes I have.
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
Once I check all four of them, the array becomes,
["degree", "pgd", "hnd", "advdip"]
When I uncheck a checkbox, I need to remove the value of it from the array according to its correct index number. I used splice() but it always removes the first index which is degree. I need to remove the value from the array according to its index number no matter which checkbox I unselect. Hope someone helps. Below is the code. Thanks in advance!
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
<script>
function getLevels() {
// get reference to container div of checkboxes
var con = document.getElementById('course-levels');
// get reference to input elements in course-levels container
var inp = document.getElementsByTagName('input');
// create array to hold checkbox values
var selectedValues = [];
// collect each input value on click
for (var i = 0; i < inp.length; i++) {
// if input is checkbox
if (inp[i].type === 'checkbox') {
// on each checkbox click
inp[i].onclick = function() {
if ($(this).prop("checked") == true) {
selectedValues.push(this.value);
console.log(selectedValues);
}
else if ($(this).prop("checked") == false) {
// get index number
var index = $(this).index();
selectedValues.splice(index, 1);
console.log(selectedValues);
}
}
}
}
}
getLevels();
</script>
You used the wrong way to find index in your code. If you used element index, it will avoid real index in your array and gives the wrong output. Check below code, it may be work for you requirement.
<input type="checkbox" value="degree">
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
<script src="https://code.jquery.com/jquery-3.5.0.min.js" integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ=" crossorigin="anonymous"></script>
<script>
function getLevels() {
// get reference to container div of checkboxes
var con = document.getElementById('course-levels');
// get reference to input elements in course-levels container
var inp = document.getElementsByTagName('input');
// create array to hold checkbox values
var selectedValues = [];
// collect each input value on click
for (var i = 0; i < inp.length; i++) {
// if input is checkbox
if (inp[i].type === 'checkbox') {
// on each checkbox click
inp[i].onclick = function() {
if ($(this).prop("checked") == true) {
selectedValues.push(this.value);
console.log(selectedValues);
}
else if ($(this).prop("checked") == false) {
// get index number
var index = selectedValues.indexOf(this.value);
selectedValues.splice(index, 1);
console.log(selectedValues);
}
}
}
}
}
getLevels();
</script>
Add change handler to the inputs and use jQuery map to get the values of the checked inputs.
var levels
$('#checkArray input').on('change', function () {
levels = $('#checkArray input:checked').map(function () {
return this.value
}).get()
console.log(levels)
}).eq(0).change()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset id="checkArray">
<input type="checkbox" value="degree" checked>
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</fieldset>
my approach was to add an event handler that reads all checked values when any of those inputs is clicked and empty the array before loging the response. no need to add any dependencies with this one
Hope this is what you are looking for
function getLevels() {
let checkboxContainer = document.getElementById("checkboxContainer");
let inputs = checkboxContainer.querySelectorAll("input");
let checked = [];
inputs.forEach( (input) => {
checked = [];
input.addEventListener( 'click', () => {
checked = [];
inputs.forEach( (e) => {
e.checked ? checked.push(e.value) : null;
})
console.log(checked);
});
});
}
getLevels();
<div id="checkboxContainer">
<input type="checkbox" value="degree" >
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</div>
I don't know if this is what you need, to show an array of the selected values, if you want you can call the function that calculates on the check.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<fieldset id="checkArray">
<input type="checkbox" value="degree" checked>
<input type="checkbox" value="pgd">
<input type="checkbox" value="hnd">
<input type="checkbox" value="advdip">
</fieldset>
<button onclick="getLevels()">getLevels</button>
<script>
function getLevels() {
var levels = [];
$.each($("input:checked"), function() {
levels.push(($(this).val()));
});
console.log(levels);
}
getLevels();
</script>

Enable button if radio button selected

I've tried almost all the methods mentioned here and in other websites but still I'm stuck so that's why I'm asking it here.
I've created a form (with out <form></form> tags) in this form I'm creating 4 radios buttons using a while loop data is being pulled from a database.
To send data I'm using a JavaScript(Ajax) which is bound to a button click event.
Now I want to keep the submit button disabled until all the filed's are filled the last filed's are the radio buttons I'm tried to use many other ways to do this but nothing happened so any way below is code I'm using.
function checkUrole() {
var roles = document.getElementById("userRoles"),
btn = document.getElementById("submit"),
len = roles.length,
sel = null;
for(var i=0; i < len; i++){
if (roles.checked){
sel = roles[i].value;
}
}
if (sel === null){
document.getElementById("msgID").innerHTML = "9";
btn.disabled = true;
}else{
btn.disabled = false;
}
}
And this is my HTML
<label for="userRoles">User Role:</label><br>
<?php while ($row = $getUserRoleQuery -> fetch(PDO::FETCH_ASSOC)) { ?>
<input type="radio" id="userRoles" name="userRoles" value="<?php echo $row["urId"]; ?>" onmousedown="checkUrole()"><?php echo $row["userRole"]; }?>
<label id="msgID" hidden></label>
<div id="msg"></div>
Basically the HTML will create something like this,
<input type="radio" id="userRoles" name="userRoles" value="1" onmousedown="checkUrole()">Admin
<input type="radio" id="userRoles" name="userRoles" value="2" onmousedown="checkUrole()">Manager
<input type="radio" id="userRoles" name="userRoles" value="3" onmousedown="checkUrole()">Team Leader
<input type="radio" id="userRoles" name="userRoles" value="4" onmousedown="checkUrole()">User
I don't like write a code like this,
if(document.getElementById("userRoles1").checked{
something here;
}else if(document.getElementById("userRoles2").checked{
something here;
}else{
something here;
}
above I think makes the program a bit less dynamic 'cos if a new user role is added I've add a new IF to the loop.
So is there any way I solve this and I like to use JavaScript if can.
UPDATE: Thanks to #zer00ne I solved this problem and below is the finale working code hope this helps any one in the future as well.
My HTML:
<script language="JavaScript" type="text/javascript" src="../jScripts/userCreatFunctions.js">
<div id="userRoles">
<input type="radio" name="userRoles" value="1" checked>Admin
<input type="radio" name="userRoles" value="2">Manager
<input type="radio" name="userRoles" value="3">Team Leader
<input type="radio" name="userRoles" value="4">User
</div>
My JaveScript:
$(document).ready(function () {
/*Register the change element to #roles
|| When clicked...*/
//This code base was originally developed by zer00ne I'm using it under his permission
//Thanks man.
var form = document.getElementById('userRoles');
if (form){
form.addEventListener('change', function(e) {
/* Determine if the e.target (radio that's clicked)
|| is NOT e.currentTarget (#roles)
*/
if (e.target !== e.currentTarget) {
// Assign variable to e.target
var target = e.target;
// Reference the submit button
var btn = document.querySelector('[name=submit]');
// Enable submit button
btn.disabled = false;
// call rolrDist() passing the target,value
roleDist(target.value);
}
}, false);
}
function roleDist(rank) {
var display = document.getElementById("msg");
if (rank !== null) {
display.innerHTML = "All done! You can save";
} else {
display.innerHTML = "Please Select User Type";
}
}
});
Use the $(document).ready(function () {}) other wise the script get loaded before the DOM which leads to a NULL value making the script none functional.
Firstly, you don't need the id's on every input element. You can get an array of the button element by name using getElementsByName, here is an example of how you would do "something" based on one of those being checked:
JS (Using ES6)
const getRadioValue = (name) => {
const radios = document.getElementsByName(name);
let val;
Object.keys(radios).forEach((obj, i) => {
if (radios[i].checked) {
val = radios[i].value;
}
});
return val;
}
document.getElementById('form').addEventListener('change', (e) => {
getRadioValue('userRoles'); // value of checked radio button.
});
HTML
<div id="form">
<input type="radio" name="userRoles" value="1">Admin
<input type="radio" name="userRoles" value="2">Manager
<input type="radio" name="userRoles" value="3">Team Leader
<input type="radio" name="userRoles" value="4">User
</div>
JsFiddle Example
UPDATE - improved
A more efficient method would be using the Array.prototype.find() method, this is better because:
The find method executes the callback function once for each index of the array until it finds one where callback returns a true value. If such an element is found, find immediately returns the value of that element.
In other words, it doesn't need to iterate the entire Array, once we find what we want it returns.
Note: Use the below snippets within the change event mentioned above to retrieve the checked value.
JS (Using ES6)
const getCheckedRadioValue = (name) => {
const radios = document.getElementsByName(name);
try {
// calling .value without a "checked" property will throw an exception.
return Array.from(radios).find((r, i) => radios[i].checked).value
} catch(e) { }
}
getCheckedRadioValue('userRoles');
JsFiddle Example
JS (Without ES6)
function getCheckedRadioValue(name) {
var radios = document.getElementsByName(name);
var val;
for (var i = 0, len = radios.length; i < len; i++) {
if (radios[i].checked) {
val = radios[i].value;
break;
}
}
return val; // return value of checked radio or undefined if none checked
}
getCheckedRadioValue('userRoles');
JsFiddle Example
References
Array.prototype.forEach()
Array.from()
Array.prototype.find()
Not exactly sure what you are trying to do, so here is what I'm guessing:
Need to determine the value of a checked radio input
Need to enable a submit button that's determined by a checked radio
Need to effectively call upon other functions, run additional interactions, etc. depending on what was specifically checked.
Details are commented in Snippet
SNIPPET
// Reference #roles
var form = document.getElementById('roles');
/* Register the change element to #roles
|| When clicked...
*/
form.addEventListener('change', function(e) {
/* Determine if the e.target (radio that's clicked)
|| is NOT e.currentTarget (#roles)
*/
if (e.target !== e.currentTarget) {
// Assign variable to e.target
var target = e.target;
// Find the textNode next to target
var label = target.nextSibling;
// Reference the #display
var display = document.getElementById('display');
// Display the <label>s text and radio value
display.value = label.textContent + ' - Rank: ' + target.value;
// Reference the submit button
var btn = document.querySelector('[type=submit]');
// Enable submit button
btn.disabled = false;
// call rolrDist() passing the target,value
roleDist(target.value);
}
}, false);
function roleDist(rank) {
switch (rank) {
case '4':
alert('Rank 4 - Limited Access');
// Take user to landing page
break;
case '3':
alert('Rank 3 - Basic Access');
// Take user to dashboard
break;
case '2':
alert('Rank 2 - Advanced Access');
// Take user to database
break;
case '1':
alert('Rank 1 - Full Access');
// Take user to admin panel
break;
}
}
input,
output,
[type=submit] {
font: inherit;
cursor: pointer;
}
[type=submit] {
float: right;
}
<form id='roles'>
<input type="radio" name="role" value="1">Admin
<input type="radio" name="role" value="2">Manager
<input type="radio" name="role" value="3">Team Leader
<input type="radio" name="role" value="4">User
</form>
<br/>
<label for='display'>Role: </label>
<!--
Since #display and submit button are outside of
the <form>, using the form attribute and the
<form>'s #id as the value establishes an
association between them and <form>
-->
<output id='display' form='roles'></output>
<br/>
<input type='submit' form='roles' disabled>
There is very basic mistake in your markup you should not use elements with same id's in
You can use class instead of id (give class to radioboxes)
document.getElementsByClassName("userRoles")
<input type="radio" class="userRoles" name="userRoles" value="1" onmousedown="checkUrole()">Admin
Rest of your code seems ok

Categories