Hi I'm new to web development and working on simple projects and I am stuck on a problem if anyone can help. I have a 3 checkboxes that a user can check on what their favourite things are to do. After completing the question I am trying to log the value of the chosen boxes however I am getting unidentified results if anyone can help id be grateful. This is the code:
html:
What is your favorite thing to do:
<p id = "favoriteThings">
<input type="checkbox" name="TV" value=1>Watch TV
<input type="checkbox" name="Books" value=2>Read Books
<input type="checkbox" name="work" value=3>Work
</p>
JS:
var favoriteThings = document.getElementById("favoriteThings");
console.log("favorite things: " + favoriteThings.value);
I am assuming that the problem is the paragraph tag is the ID but can someone give me a fix to this? As I don't want to give each checkbox the same ID as I heard its bad practice.
thanks in advance.
When you want to group your checkbox (or radio) inputs, use the same name for your group of inputs
Use a different value
Use querySelectorAll() to get your desired elements using the Attribute selector "[]"
Use nodeList.forEach() to iterate your elements
Use addEventListener() to attach an Event, "input" in your case:
const ELs_favorite = document.querySelectorAll("[name=favorite]");
const get_favorite = () => {
const checked_values = [...ELs_favorite].reduce((arr, EL) => {
if (EL.checked) arr.push(EL.value);
return arr;
}, []);
console.log(checked_values);
};
ELs_favorite.forEach(EL => {
EL.addEventListener("input", get_favorite);
});
What is your favorite thing to do:
<p>
<label><input type="checkbox" name="favorite" value="tv">Watch TV</label>
<label><input type="checkbox" name="favorite" value="books">Read Books</label>
<label><input type="checkbox" name="favorite" value="work">Work</label>
</p>
In the example above, Array.reduce() is used to collect only the values of the checked input elements into an Array.
you can give each checkbox the same id (there is no problem).
Solution:
<p id = "favoriteThings">
<input type="checkbox" name="favoriteThings" value="TV" or "1" onclick="MyNameFunction()">Watch TV
<input type="checkbox" name="favoriteThings" value="Read Books" or "2" onclick="MyNameFunction()">Read Books
<input type="checkbox" name="favoriteThings" value="Work" or "3" onclick="MyNameFunction()">Work
</p>
js
var choices = [];
var els = document.getElementsByName('favoriteThings');
console.log("Favourite things: ");
for (var i=0;i<els.length;i++){
if ( els[i].checked ) {
console.log(els[i].value);
}
Related
I am about to learn programming and I have created a practice form to test my knowledge. The checkbox allows the user to choose what extra topping they want for their hamburger. in javascript I can get extra topping value by using the getElementById command. The code works perfectly but I need the for loop to go through all the elements .I need the checkbox's index which were written in HTML code to be able to use in javascript.
This what I written in HTML:
<div class="extra">
<div>
<input value="250" type="checkbox" name="cheese" id="cheese">
<label for="cheese">Sajt (+250 Ft)</label>
</div>
<div>
<input value="600"type="checkbox" name="meat" id="doublemeat">
<label for="doublemeat">+Hús (+600 Ft)</label>
</div>
<div>
<input value="250"type="checkbox" name="onion" id="onion">
<label for="onion">Hagyma (+250 Ft)</label>
</div>
<div>
<input value="450"type="checkbox" name="bacon" id="bacon">
<label for="bacon">Bacon (+450 Ft)</label>
</div>
<div>
<input value="600"type="checkbox" name="coleslaw" id="coleslaw">
<label for="coleslaw">Coleslaw saláta (+600)</label>
</div>
</div>
And this in javascript:
var extra=0;
if (document.getElementById("cheese").checked){
extra=extra+parseInt(cheese.value)}
if (document.getElementById("doublemeat").checked){
extra=extra+parseInt(doublemeat.value)}
if (document.getElementById("onion").checked){
extra=extra+parseInt(onion.value)}
if (document.getElementById("bacon").checked){
extra=extra+parseInt(bacon.value)}
if (document.getElementById("coleslaw").checked){
extra=extra+parseInt(coleslaw.value)
}
You'll need to make an array of all your elements and then you can use JavaScript's reduce method.
Here's an example:
const elements = [
document.getElementById("cheese"),
document.getElementById("doublemeat"),
document.getElementById("onion"),
document.getElementById("bacon"),
document.getElementById("coleslaw")
];
const extra = elements.reduce((total, element) => {
if (element.checked) {
return total + parseInt(element.value);
}
return total;
}, 0);
The .reduce method reduces an array into a new value. In this case we start with 0 and return the sum + value if the element is checked.
You can read more about reduce on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
In your JavaScript, you might be better off doing:
const elements = Array.from(document.querySelectorAll('.extra > div > input'))
This will save you from having to manually fetch all the elements.
This is the checkboxes in my HTML:
<input type="checkbox" name="sides" id="1" value="French Fries" >French Fries<br />
<input type="checkbox" name="sides" id="2" value="Baked Potato">Baked Potato<br />
<input type="checkbox" name="sides" id="3" value="Cole Slaw">Cole Slaw<br />
<input type ="button" value = "Enter my side dish selections" onclick="checkbox(sides.value1,sides.value2)"/>
What i want is when the user clicks the button, it should take first two checked boxes and then display it as:
function checkbox(dish1,dish2) {
document.getElementById("side_one").innerHTML = dish1;
document.getElementById("side_two").innerHTML = dish1;
}
I am confused on how to do this, can you please help me here.
You can select the first two checked inputs with [...document.querySelectorAll( ":checked" )].slice( 0, 2 );.
What it does is to create an Array from a NodeList made of all the elements that matches the :checked pseudo-class and slice it in an new Array of two items.
Then you just need to grab the .value of the found <input> elements:
document.querySelector('[type="button"]').onclick = (evt) => {
const checked = [...document.querySelectorAll( ":checked" )].slice( 0, 2 );
checkbox( ...checked.map( (input) => input.value ) )
};
function checkbox(dish1 = "", dish2 = "") {
document.getElementById("side_one").innerHTML = dish1;
document.getElementById("side_two").innerHTML = dish2;
}
<input type="checkbox" name="sides" id="1" value="French Fries" >French Fries<br />
<input type="checkbox" name="sides" id="2" value="Baked Potato">Baked Potato<br />
<input type="checkbox" name="sides" id="3" value="Cole Slaw">Cole Slaw<br />
<input type ="button" value = "Enter my side dish selections"/>
<p id="side_one"></p>
<p id="side_two"></p>
If you want it to search only in the content of a specific element, you just need to make the CSS selector in querySelectorAll more specific.
You can use something like the following:
Array.from(document.getElementsByName('entree')).filter(input => input.checked).map(input => input.value)
This makes an array out of node list of interest, filters out all unchecked elements and returns an array that will have zero or more values depending on what is checked. You can then .join() it or otherwise do as you see fit.
basically, radio is a NodeList, so you can do this
const radioValue = (radio.length > 0) ? radio[0].value : "";
Is this a good solution to check multiple radio buttons with 1 label? I have a form with multiple steps. The last step shows a summary about the previous steps and I need to get all data from there. Is there a better option? How can I get the text from the input fields and insert it to the summary? JavaScript?
$('label').click(function() {
id = this.id.split('-');
if (id[0] === '1') {
id[0] = '2';
} else {
id[0] = '1';
}
$('#' + id[0] + '-' + id[1]).prop('checked', true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="one">
<input type="radio" id="1-1" name="1-level">
<label for="1-1" id="1-1">1</label>
<input type="radio" id="1-2" name="1-level">
<label for="1-2" id="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level">
<label for="2-1" id="2-1">1</label>
<input type="radio" id="2-2" name="2-level">
<label for="2-2" id="2-2">2</label>
</div>
Add a form element to wrap your input elements in. Forms can access all the inputs that are inside of it and see their names and their values. So in this case it is important that you use the value attribute on your input elements. Start by doing the above and make your code look like the example below.
Also, be careful with id's. They need to be unique, so they can only appear once in every document. Right now the label and their input elements have the same id.
<form id="step-form">
<div class="one">
...
</div>
</form>
Like #Shilly suggested, use the FormData API. This API is designed to get all the values from a form, think input, textarea and select elements and puts all of that data into a single object. This way you can create as many form-elements as you want, add them to the form and store their values in a single object.
The data in that object will be read as key-value pairs, which in this case are the name and value attribute values. For example: ['1-level', '2'], here we see the input with the name '1-level' and the value '2'.
I would not recommend using other input elements to show your results or summary. This could be confusing for the user as it suggests input. Instead print your results in plain text or create a list.
I do not know the jQuery equivalent of many of these API's or methods, so I've used Vanilla JavaScript to create a demo which, hopefully, demonstrates what you try to accomplish.
If you have any question, I've been unclear, or have not helped you in any way. Please let me know.
const form = document.getElementById('step-form');
const summary = document.getElementById('step-summary');
const clear = document.getElementById('step-clear');
// Remove all children of the summary list.
function clearSummary() {
while(summary.firstElementChild) {
summary.firstElementChild.remove();
}
}
// Clear list on click.
clear.addEventListener('click', event => {
clearSummary();
});
form.addEventListener('submit', event => {
// Clear list first.
clearSummary();
// Create a fragment to store the list items in.
// Get the data from the form.
const fragment = new DocumentFragment();
const formData = new FormData(event.target);
// Turn each entry into a list item which display
// the name of the input and its value.
// Add each list item to the fragment.
for (const [ name, value ] of formData) {
const listItem = document.createElement('li');
listItem.textContent = `${name}: ${value}`;
fragment.appendChild(listItem);
}
// Add all list items to the summary.
summary.appendChild(fragment);
event.preventDefault();
});
<form id="step-form">
<div class="one">
<input type="radio" id="1-1" name="1-level" value="1">
<label for="1-1">1</label>
<input type="radio" id="1-2" name="1-level" value="2">
<label for="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level" value="1">
<label for="2-1">1</label>
<input type="radio" id="2-2" name="2-level" value="2">
<label for="2-2">2</label>
</div>
<div class="three">
<input type="radio" id="3-1" name="3-level" value="1">
<label for="3-1">1</label>
<input type="radio" id="3-2" name="3-level" value="2">
<label for="3-2">2</label>
</div>
<ul id="step-summary"></ul>
<button type="submit">Review form</button>
<button type="button" id="step-clear">Clear summary</button>
</form>
I have the following code:
<fieldset id="dificuldade">
<legend>Dificuldade:</legend>
<input type="radio" name="dificuldade" value="facil"> Fácil </input>
<input type="radio" name="dificuldade" value="medio"> Médio </input>
<input type="radio" name="dificuldade" value="dificil"> Difícil </input>
</fieldset>
<fieldset id="tipo">
<legend>Tipo de jogo:</legend>
<input type="radio" name="Tipodejogo" value="somar"> Somar </input>
<input type="radio" name="Tipodejogo" value="subtrair"> Subtrair </input>
<input type="radio" name="Tipodejogo" value="dividir"> Dividir </input>
<input type="radio" name="Tipodejogo" value="multiplicar"> Multiplicar </input>
</fieldset>
<input type="button" value="Começa" id="button" ></input>
</form>
and here is the jsfiddle with both the html and the js http://jsfiddle.net/3bc9m/15/ . I need to store the values of the 2 fieldset so I, depending on the values picked can generate a game, but my javascript isn't returning any of them. What is wrong? I've been told that JQuery is much easier but i can't use it.
Your code on jsFiddle seems to be working fine for the most part. The only thing was that the elements output and output2 don't exist on the page.
So this code that was supposed to display the selected values wasn't working:
document.getElementById('output').innerHTML = curr.value;
document.getElementById('output2').innerHTML = tdj.value;
The part that actually retrieves the selected values is working fine.
Just add those two elements to the page, like this:
<p>Selected Values:</p>
<div id="output"></div>
<div id="output2"></div>
An updated jsFiddle can be found here.
EDIT
If a radio button from only one of the sets is selected, the code fails. You could use this code to find the selected values instead:
document.getElementById('button').onclick = function() {
var dif = document.getElementsByName('dificuldade');
var tip = document.getElementsByName('Tipodejogo');
var difValue;
for (var i = 0; i < dif.length; i++) {
if (dif[i].type === "radio" && dif[i].checked) {
difValue = dif[i].value;
}
}
var tipValue;
for (var i = 0; i < tip.length; i++) {
if (tip[i].type === "radio" && tip[i].checked) {
tipValue = tip[i].value;
}
}
document.getElementById('output').innerHTML = difValue;
document.getElementById('output2').innerHTML = tipValue;
};
An updated jsFiddle is here.
Consider this post that adresses the issue. It shows a few javascript methods as well as how you would use it in jQuery.
How can I check whether a radio button is selected with JavaScript?
Is there a specific reason you want to break it down by fieldset instead of directly accessing the radio buttons by name?
Ok before i make spaghetti of this code i thought id ask around here. ive made a quiz for an online site.
The answers are stored in an array, and ive a function that checks the answers array to what youve clicked. then it counts them and gives you your score.
but i want to change the clor of the right answer wen the user clicks the score button. so the correct answers are highlighted. something like this https://www.shutterpoint.com/Home-Quiz.cfm (just hit submit at the bottom, no need to do the quiz).
the little answer icon at the side looks flashy but id rather just have the text change color. heres how my questions are formatted
<p>Film speed refers to:</p>
<p id = "question1">
<input type="radio" name="question1" id="Wrong" value = "a" onClick = "recordAnswer(1,this.value)"/>How long it takes to develop film. <br/>
<input type="radio" name="question1" id="Wrong" value = "b" onClick = "recordAnswer(1,this.value)"/>How fast film moves through film-transport system. <br/>
<input type="radio" name="question1" id="Answer" value = "c" onClick = "recordAnswer(1,this.value)"/> How sensitive the film is to light. <br/>
<input type="radio" name="question1" id="Wrong" value = "d" onClick = "recordAnswer(1,this.value)"/> None of these makes sense. <br/></p>
and these are the two functions that are called throughout. record answer is called every time the user clicks a button
function recordAnswer(question,answer)
{
answers[question-1] = answer;
}
this is the final button which calculates the score
function scoreQuiz()
{
var totalCorrect = 0;
for(var count = 0; count<correctAnswers.length;count++)
{
if(answers[count]== correctAnswers[count])
totalCorrect++;
}
<!--
alert("You scored " + totalCorrect + " out of 12 correct!");
-->
}
another function is best i think. ive already made attempts at it and know i have to set the color using
document.getElementById('Answer').style.color = '#0000ff';
onyl problem is 'Answer' doesnt seem to be registering. anyone shed some light?
ok so i cant have two or more of the same ids.
what about
if(value == correctAnswers[])
{
// change the color.
}
QUICK RESPONCE:
USE <P>
<p>
<input type="radio" name="question_1" class="wrong" value="a" />
How long it takes to develop film.
</p>
THEN
if(value == correctAnswers[])
{
YOUR_ELEMENT.parentNode.style.color = 'green';
}
IMPROVEMENT
DEMO: http://jsbin.com/aceze/26
hi Overtone!
first of all you need to restyle a litte your HTML schema!
you have multiple id="Wrong" instead of class="Wrong"
then here how your code should look:
var answers = { 1:'a' , 2:'f' , 3:'h' };
function checkQuestions() {
var form_elements = document.question_form.elements.length;
for ( var i = 0; i < form_elements; i++ )
{
var type = question_form.elements[i].type;
if ( type == "radio" ){
var quest = question_form.elements[i];
//if ( quest.checked ) {
var question_index = parseInt(quest.name.split('_')[1]);
//}
if ( quest.value == answers[question_index] ) {
quest.parentNode.style.border = '1px solid green';
quest.parentNode.style.color = 'green';
} else {
//quest.parentNode.style.border = '1px solid red';
quest.parentNode.style.color = 'red';
}
}
}
}
USE a FORM and one time SUBMIT BUTTON instead of adding onclick to each RADIO like this
<form name="question_form" id="question_form" method="POST" action='#'>
<div id="question_1"> <H4>QUESTIONS TIME 1</H4>
</div>
<p>
<input type="radio" name="question_1" class="wrong" value="a" />
How long it takes to develop film.
</p>
<p>
<input type="radio" name="question_1" class="wrong" value="b" />
How fast film moves through film-transport system.
</p>
<p>
<input type="radio" name="question_1" class="answer" value="c" />
How sensitive the film is to light.
</p>
<p>
<input type="radio" name="question_1" class="wrong" value="d" />
None of these makes sense.
</p>
...
...
<input type="radio" name="question_2" class="wrong" value="h" />
<span>None of these makes sense.
</span>
</p>
<input type="submit" name="submit" onclick="checkQuestions();return false;" value="submit"/>
</form>
PS: demo example updated with style... for sake!
You should format your ids in a more usable way.. I'd suggest something similar to questionNUMBER_answerVALUE.
Then it'd be a simple matter of...
for (var i=0; i<correctAnswers;i++) {
document.getElementById("question" + (i+1) + "_answer" + correctAnswers[i].toUpperCase()).style.color = "#0000FF";
};
Just check I've got your zero/non-zero indexing correct with regard to question/ answer numbers.
Instead of using a <p> I would consider using a <label for='question1_answerA'>How long it takes to develop film.</label>. You can still use a jQuery selector to find it and it feels more semantically correct. You will then also be able to select the option by clicking the text.
Although your other HTML isn't semantically correct. You need to give each radio a unique ID.
Obligatory jquery solution:
var highlightCorrect = function(){
$(".Answer").css("color", "#00FF00");
}
This is all assuming that you fix your HTML to use classes rather than IDs for "Wrong" and "Answer".