Multi step form - how to show data from steps before? - javascript

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>

Related

checkbox value unidentified

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);
}

A want to use the for loop in my code, but I don't know how is it possible

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.

How to check if radiobutton is selected (javascript, html)

I am trying to check if a radio button is selected or not. If the "morn_before" radiobutton is selected, the data will be stored as "2", but if the "morn_after" radiobutton is selected instead, the data will be stored as "1".
Currently my code show below is not working. For example when i select the "morn_before" radiobutton, it doesnt print "morn_before checked true" in the console, despite me putting console.log("morn_before checked true") in that if statement.
HTML:
<div class="radiobutton">
<input type="radio" id="morn_before" name="morn_time" value="morn_before">
<label for="morn_before">Before Food</label><br>
<input type="radio" id="morn_after" name="morn_time" value="morn_after">
<label for="morn_after">After Food</label><br><br>
</div>
Javascript:
function check() {
let user=firebase.
auth().currentUser;
let uid;
if(user!=null){
uid=user.uid;
}
var firebaseRef = firebase.database().ref();
if(document.getElementById("morn_before").checked){
console.log("morn_before checked true");
firebase.database().ref(uid).child('/radiobutton/').child('/morn_time/').set("2");
}
else if(document.getElementById("morn_after").checked){
firebase.database().ref(uid).child('/radiobutton/').child('/morn_time/').set("1");
}
}
check();
You don't need any JavaScript for this. You can have a completely different display than the stored value.
<div class="radiobutton">
<input type="radio" id="morn_before" name="morn_time" value="2">
<label for="morn_before">Before Food</label><br>
<input type="radio" id="morn_after" name="morn_time" value="1">
<label for="morn_after">After Food</label><br><br>
</div>
Should produce the same result. The only improvement would be to set one of these to default true, in case the user chose neither. But that'd be up to you.
ADDITIONAL INFO: You are not supposed to read a radio button group that way.
You should go over some basics of HTML INPUT tag such as
https://www.geeksforgeeks.org/how-to-get-value-of-selected-radio-button-using-javascript/

How do I detect a change in value of a RadioNodeList?

With a form my_form with a set of radio buttons with name=my_radio I can get a RadioNodeList object with my_form.elements.my_radio. I can get the value of the currently selected button with that object's value property, and if I assign a string to the value property the selected option changes as appropriate.
I expected to be able to do my_form.elements.my_radio.addEventListener('change', ..., to listen for the value changing (via the user selecting a different option) but it has no such method.
How can I detect the value changing?
Is the only way to set up event listeners on each individual radio button object?
var my_form = document.querySelector('#my_form');
var my_radio = my_form.elements.my_radio;
// This fails since RadioNodeList has no addEventListener function
/*
my_radio.addEventListener('change', function () {
console.log("Value changed; new value is " + my_radio.value);
});
*/
// The following works, but is there a better way, such as with a single event listener?
for (var i = 0, l = my_radio.length; i < l; i++) {
my_radio[i].addEventListener('change', function () {
console.log("Value changed; new value is " + my_radio.value);
});
}
<form id=my_form>
<div>
<label>
<input type=radio name=my_radio value=value_1>
Value 1
</label>
</div>
<div>
<label>
<input type=radio name=my_radio value=value_2>
Value 2
</label>
</div>
<div>
<label>
<input type=radio name=my_radio value=value_3>
Value 3
</label>
</div>
<div>
<label>
Some other field where I don't need to detect changes
<input name=some_other_field>
</label>
</div>
</form>
In your markup, wrap just the radio buttons in a fieldset. Then attach the event-listener to that instead of the form, so it won't fire for changes to other <input> fields.
Here is the modified code:
var my_form = document.querySelector('#my_form');
var my_radio = my_form.elements.my_radio;
var my_radio_group = document.querySelector('#my_radio_group');
// Attach the eventListener to the fieldset instead of the form
my_radio_group.addEventListener('change', function() {
// You actually don't even need the other global variables; this also works:
// let my_radio = this.form.elements.my_radio);
console.log("Value changed; new value is " + my_radio.value);
});
/* If you don't want any border around the radio group */
#my_radio_group {
border: none;
}
<form id="my_form">
<fieldset id="my_radio_group">
<div>
<label>
<input type="radio" name="my_radio" value="value_1">
Value 1
</label>
</div>
<div>
<label>
<input type="radio" name="my_radio" value="value_2">
Value 2
</label>
</div>
<div>
<label>
<input type="radio" name="my_radio" value="value_3">
Value 3
</label>
</div>
</fieldset>
<div>
<label>
Some other field where I don't need to detect changes
<input name="some_other_field">
</label>
</div>
</form>
Why OP's first approach fails
A RadioNodeList, being a kind of NodeList, is a collection of Nodes (radio elements in this case). As such, it is much like a JS Array (you can do my_radio[i]). In JS, Events can be received only by objects that inherit the EventTarget interface, like Nodes and HTML Elements, and not by collections like arrays and NodeLists.
To attach a single event handler for multiple elements, you have to attach it to a close parent and use Event Delegation. Which is what I did in my solution, using the <fieldset> element. Any wrapper element e.g. <div> would have sufficed; only that the <fieldset> is semantically more accurate here.
you can try this:
my_form.addEventListener('change', function () {
console.log("Value changed; new value is " + my_radio.value);
});
document.formName.radioButtons[thisOne].click()

If radio button checked add new form element using dom?

How do I use DOM in Javascript to check if a radio button is checked and then if so add new form elements to datesettings?
//Radio buttons
<input type="radio" id="dateoption" name="dateoption" value="1">
<input type="radio" id="dateoption" name="dateoption" value="2">
//Add new form elements
<span id="datesettings"></span>
Im currently reading a Javascript book but its not helping me understand. If someone could help me with this example then maybe the penny will drop. Thanks for your time.
Check out this page:
It explains the process so you understand why you're doing it a certain way, AND it gives good example code.
http://www.webdevelopersnotes.com/tips/html/finding_the_value_of_a_radio_button.php3
You would write a function to do the check, like this:
function CheckDateOptions() {
var o1 = document.getElementById("dateoption1");
var o2 = document.getElementById("dateoption2");
var eSettings = document.getElementById("datesettings");
if(o1.checked) {
eSettings.appendChild(...);
}
else if(o2.checked) {
eSettings.appendChild(...);
}
}
But, you have to make sure to assign your radio buttons unique id values. You can duplicate names to group the radio buttons, but for any element, the id should be unique.
<form id="TestForm">
<!-- //Radio buttons -->
<input type="radio" id="dateoption1" name="dateoption" value="1">Text 1</input>
<input type="radio" id="dateoption2" name="dateoption" value="2">Text 2</text>
<!-- //Add new form elements -->
<span id="datesettings"></span>
</form>

Categories

Resources