Replace input value by variable and - javascript

I'm trying to make a sort of questionnaire/quiz in javascript for my website. The questionnaire is spread on 5 pages, each page has a question. I want to use the GET method so the URL of each page looks something like that:
(I must keep the GET method because I want to use for something else).
First question: http://website.com/quiz/first?q=1
Second question: http://website.com/quiz/second?q=133
Third question: http://website.com/quiz/third?q=133
Fourth question: http://website.com/quiz/fourth?q=1332
Fifth question: http://website.com/quiz/fifth?q=13324
The user lands on the first page --> get a radio input form --> checks one --> gets redirected to the second page --> etc...
The ?q= is a variable containing the answers, for example ?q=133 means the user picked the following answers:
In the first question, he checked the radio input of the value 1
In the second question, he checked the radio input of the value 3
In the third question, he checked the radio input of the value 3
(so 133 means the user check the 1 for the first question, 3 for the second, 3 for the third.)
I managed to make the variables work:
answPre: gets the previous answer from the form GET (?q=1).
answCurrent: gets the radio input checked from the current page.
urlVal: an combination of the two (answPre+answCurrent)
so I'd like urlVal to be the value that gets transferred from a page to the other.
But I don't want to have both urlVal and the "q" value (name of checked radio) in the url.
What's the right thing to do?
can I hide the "q" value from the URL?
or can I "overwrite" the q value and put instead urlVal?
I'm lost and would appreciate any help, thanks for your help and your time!
function displayRadioValue() {
// var pageURL = window.location.href;
var fakeURL="website.com/quiz/first?q=1"
var answPre = fakeURL.substr(fakeURL.lastIndexOf('=') + 1); //get the previous page's answer.
//get the current page's answer
var ele = document.getElementsByName('q');
for(j = 0; j < ele.length; j++) {
if(ele[j].checked)
var answCurrent= document.getElementById("demo2").innerHTML = ele[j].value;
}
var array = [answPre,answCurrent]; //combine answPre + answNew
var urlVal = "";
var i;
for (i = 0; i < array.length; i++) {
urlVal += array[i];
}
document.getElementById("demo1").innerHTML = answPre;
document.getElementById("demo3").innerHTML = urlVal;
//document.getElementById("fquiz").submit();// Form submission
}
<html>
<body>
<h2>second.html</h2>
<b>answPre: </b><span id="demo1"></span><br>
<b>answCurrent: </b><span id="demo2"></span><br>
<b>urlVal: </b><span id="demo3"></span><br>
<!-- <b>final answNew: </b><span id="demo4"></span><br> -->
<hr>
<form id="fquiz" method="GET" action="third.html">
<p>Who are you going with?</p>
<input type="radio" name="q" value="1" id="yes"
onClick="javascript: displayRadioValue()">Solo<br>
<input type="radio" name="q" value="2" id="no"
onClick="javascript: displayRadioValue()">Couple<br>
<input type="radio" name="q" value="3" id="no"
onClick="javascript: displayRadioValue()">Family with kids<br>
<input type="radio" name="q" value="4" id="no"
onClick="javascript: displayRadioValue()">Group of friends<br>
<p>(then it takes you to third.html with hopefully this url: ../third.html?q=XX where XX is urlVal)
</form>
</body>
</html>

I've made a few changes to your code to modernize it a bit.
I moved the binding of the event handlers to the JavaScript from the HTML. Generally speaking I like to keep my HTML about the structure and the JavaScript about the behavior.
I added code to grab the step from the URL in addition to the previous answers.
I used querySelector to retrieve the selected radio button, using the :checked pseudo-selector.
I used join('') on the array of answers to make it easier to read.
In the HTML, I used <p> elements for everything that needed to be in one line, rather than tacking a <br> at the end of each line. That's just a personal preference.
I wrapped the radio buttons and their text in <label> elements. This helps in accessibility and to give a larger target for people to click on (clicking on the entire label checks the radio, rather than just the radio itself).
I also changed the name of the URL parameter to urlVal rather than q, but I'm not sure I understood that part of your question. I'm not using the form submission process at all with this code, relying instead on changing the location directly...
Do note that running the code here on Stack Overflow won't redirect correctly, since of course there's nothing at example.com/quiz/second listening, and Stack Snippets are sandboxed anyway. You'll need to adjust the code for your specific use in any case.
// Use JavaScript to attach event handlers to HTML elements.
document.querySelectorAll('input[name="q"]').forEach(el => el.addEventListener('click', displayRadioValue));
function displayRadioValue() {
// var pageURL = window.location.href;
var fakeURL = "example.com/quiz/first?q=1"
var step = fakeURL.substring(fakeURL.lastIndexOf('/') + 1, fakeURL.indexOf('?'));
var answPre = fakeURL.substr(fakeURL.lastIndexOf('=') + 1); //get the previous page's answer.
//get the current page's answer
// The :checked pseudo-class makes it easier to find the checked radio button
var el = document.querySelector('input[name="q"]:checked');
var answCurrent = document.getElementById("demo2").innerHTML = el.value;
var array = [answPre, answCurrent]; //combine answPre + answNew
// The join method is easier to use than looping.
var urlVal = array.join('');
document.getElementById("demo1").innerHTML = answPre;
document.getElementById("demo3").innerHTML = urlVal;
switch (step) {
case 'first': step = 'second'; break;
case 'second': step = 'third'; break;
case 'third': step = 'final'; break;
default: return;
}
location.href = `example.com/quix/${step}?urlVal=${urlVal}`;
}
.form-group { margin: 0; }
<h2>second.html</h2>
<!-- <br> is a presentational element; better just to split up lines with paragraphs -->
<p class="form-group"><b>answPre: </b><span id="demo1"></span></p>
<p class="form-group"><b>answCurrent: </b><span id="demo2"></span></p>
<p class="form-group"><b>urlVal: </b><span id="demo3"></span></p>
<!-- <p class="form-group"><b>final answNew: </b><span id="demo4"></span></p> -->
<hr>
<form id="fquiz" method="GET" action="third.html">
<p>Who are you going with?</p>
<!-- <br> is a presentational element; better just to split up lines with paragraphs -->
<!-- Always use <label> elements to label form fields -->
<!-- IDs must be unique to a document. They did not appear relevant here. -->
<p class="form-group"><label><input type="radio" name="q" value="1">Solo</label></p>
<p class="form-group"><label><input type="radio" name="q" value="2">Couple</label></p>
<p class="form-group"><label><input type="radio" name="q" value="3">Family with kids</label></p>
<p class="form-group"><label><input type="radio" name="q" value="4">Group of friends</label></p>
<p>(then it takes you to third.html with hopefully this url: ../third.html?q=XX where XX is urlVal)</p>
</form>

Related

Calculations with Radio Buttons

I am trying to create this JavaScript calculation with radio buttons. So If the user Checks the "delivered to home address" then the value of £5.99 will be added into the total box, but if the user selects the other radio button, then no price will get shown. I am pretty new to JavaScript so I may have a few errors, but i'd be grateful if you could help me out
<section id="collection">
<h2>Collection method</h2>
<p>Please select whether you want your chosen event ticket(s) to be delivered to your home address (a charge applies for this) or whether you want to collect them yourself.</p>
<p>
Home address - £5.99 <input type="radio" name="deliveryType" value="home" data-price="5.99" checked> |
Collect from ticket office - no charge <input type="radio" name="deliveryType" value="ticketOffice" data-price="0">
</p>
</section>
Total <input type="text" name="total" size="10" readonly>
JavaScript
let totalPrice = 0;
var RadioBtn = document.getElementById ('input[name=deliveryType]');
radioBtn.addEventListener("click", function() {
if(radioBtn.clicked) {
totalPrice += parseFloat(radioBtn.dataset.price)
total.value = " + totalPrice;
}
}
Here are my observations from the code provided:
The radioBtn variable was declared with Pascal Case (first letter
upper case) so it won't be referenced in the code since the other
lines use camelCase(starts with Lower case). change to camelCase and
stick with it through out the code.
Your selector - getElementById is used for Ids and it would return one
element, since you are passing a query selector
'input[name=deliveryType]' instead the code will not find the
element you are looking for
Since you are looking to add click events to the radio buttons, you can
use getElementsByName and provide the name of the radio
buttons. Then iterate through the resulting elements to apply the
click event... that way the click will be called for both radio
buttons.
No need to check if clicked inside the click event, you already know it
will be called when clicked only, instead you can add the
event parameter to get the click target and its information to apply
it as needed.
Example:
let totalPrice = 0;
let radioBtns = document.getElementsByName('deliveryType');
let totalEl = document.getElementsByName ('total')[0];
radioBtns.forEach(function(element, index){
element.addEventListener("click", function(event){
totalPrice += parseFloat(event.target.dataset.price); //remove += if the price should be the same everytime, replace with = or it will add the number to the total when clicked
totalEl.value = totalPrice + " totalPrice";
});
});
https://jsfiddle.net/dn4x7oy9/8/

Need help using increments and displaying in a textbox

We need to have a textbox where you enter a number, hit a button, and it increments by 1, while staying in the same text box. Here is the code I have so far:
<form action=#>
<p>
Current Count...<input type="text" id="txtCounter" value="0">
</p>
<p>
<input type="button" value="Increment Count" id="btnIncrement" onclick="btnIncrement_onclick()">
<input type="reset">
</p>
</form>
<noscript>This website requires JavaScript to be enabled.</noscript>
JavaScript:
function btnIncrement_onclick() {
// get textbox and assign to a variable
var countTextbox = document.getElementById("txtCounter");
var txtCounterData = txtCounter.value;
var countTextbox.value = 0++;
}
If someone could explain to me how to do it not just give me the answer. I don't know why I'm having such a hard time with this.
Try the following simple code :
function btnIncrement_onclick()
{
//asign the textbox to variable
var textbox = document.getElementById("txtCounter");
//Get the value of textbox and add 1 then update the textbox
textbox.value = parseInt(textbox.value)+1;
}
<form action=#>
<p>
Current Count...<input type="text" id="txtCounter" value="0">
</p>
<p>
<input type="button" value="Increment Count" id="btnIncrement" onclick="btnIncrement_onclick()">
<input type="reset">
</p>
</form>
<noscript>This website requires JavaScript to be enabled.</noscript>
Hope this helps.
In your HTML:
In your html you had a onclick="btnIncrement_onclick()" and that means every click will triggers your function.
In your JS:
function btnIncrement_onclick() {
// Named as countTextbox you input. sou we can use it later.
var countTextbox = document.getElementById("txtCounter");
// Get the current value attribute of it, initialy 0.
var txtCounterData = txtCounter.value;
// The line above is not being used. but you can check it with a console.log like this:
console.log(txtCounterData);
// Now you are calling again your input and changing his value attribute. this ++ means a increment. so we are increasing +1;
countTextbox.value++;
}
You should read more about increment and operators and DOM (the way whe select the tag by id, and again selected his attribute).
Sorry didn't found a good source in english.

multiple div with same template

I have a 'users page'. I would like to give a textbox for entering the no. of users. On click of submit 'n' no of user forms need to be presented to user.
User1
first name -
last name -
User2
first name -
last name -
.
.
.
UserN
first name -
last name -
I don't know the value of 'N' upfront. So it won't be a good idea to write multiple 'divs' in my html.
Requirement:Rather I want to have a user template div. And copy the template 'n' times depending on the value of 'n' in the textbox. But I would also want all the 'divs' to have different ids like 'user1', 'user2' etc.
I cannot figure out a way to do this apart from populating my html with too many 'divs'. Would need help achiving the Requirement specified.
Looking for a template like:-
<div id="user-template" class="hidden">
<label class="lbl"><b>Handle:</b></label><input type="text" id="first_name" value=""/>
</div>
And wanted to have id="user-template" change for all new divs.
You can try something like this:
You can make a template and append it to the DOM for the number entered in the input field.
$(document).ready(function() {
$("#createForms").click(function() {
var numOfForms = $("#numOfForms").val();
var template = $('#hidden-template').html();
for (var i = 0; i < numOfForms; i++) {
$('#targetDiv').append("<p>User" + (i + 1) + ":</p>");
$('#targetDiv').append(template);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="numOfForms"></input>
<input type="button" id="createForms" value="Get Fields"></input>
<div id="targetDiv"></div>
<script id="hidden-template" type="text/x-custom-template">
<div id="user-template" class="hidden">
<p>First Name:
<input type="text" name="firstName"></input>
</p>
<p>Last Name:
<input type="text" name="lastName"></input>
</p>
<br>
</div>
</script>
A simple way is to write a function that takes the n value and returns the actual dom that you can append to some parent element on your page. A simple example below:
function createNDivs(n) {
if(!n) return;
var fragment =document.createDocumentFragment();
for(var i=0;i<n;i++) {
var div = document.createElement('div');
fragment.appendChild(div);
}
return fragment;
}

Can't get if/else function to work with radio buttons

I have looked all over this site (and Google) for an answer to my problem but I can only seem to find bits and pieces, nothing specific.
I am primarily playing around with JavaScript and HTML but am not trying to use jquery right now.
So, with that said, this is what I'm trying to do: I would like the user to enter two numbers, select an operation (add, subtract, multiply, divide) out of a list of four radio buttons, and then click a button which is linked to a function that does the math and then presents it in a text box on the page. How would I do this using only HTML and JavaScript? I have gotten everything to work up until the point I add the radio buttons.
The code is as follows:
<script>
function operationForm (form) {
var x = document.operationForm.getElementById("numberOne");
var y = document.operationForm.getElementById("numberTwo");
var operation;
var answer;
if (document.operationForm.addSelect.checked === true) {
answer = x + y;
document.operationForm.answerBox.value = answer;
} else if (document.operationForm.subtractSelect.checked === true) {
answer = x - y;
document.operationForm.answerBox.value = answer;
} else if (document.operationForm.multiplySelect.checked === true) {
answer = x * y;
document.operationForm.answerBox.value = answer;
} else(document.operationForm.divideSelect.checked === true) {
answer = x / y;
document.operationForm.answerBox.value = answer;
}
}
</script>
<h1>Let's calculate!</h1>
<form name="operationForm">
<p>
<label>Enter two numbers, select an operation, and then click the button below.
<p>
<label>Number One:
<input type="text" name='numbers' id="numberOne">
<br>
<br>Number Two:
<input type="text" name='numbers' id="numberTwo">
<p>
<input type="radio" name="operations" id="addSelect" value=''>Add
<input type="radio" name="operations" id="subtractSelect" value=''>Subtract
<input type="radio" name="operations" id="multiplySelect" value=''>Multiply
<input type="radio" name="operations" id="divideSelect" value=''>Divide
<label>
<p>
<input type="button" value=" Calculate " onClick='operationForm(form);'>
<p>
<label>Your answer is:
<input type="text" name="answerBox">
If anyone has any fixes or can point me in the right direction of the correct syntax for handling radio buttons, functions linking to them, and onClick events linking to those functions, it would be extremely appreciated.
Consider replacing the <input type="button" value=" Calculate " onClick='operationForm(form);'> with <input type="button" value=" Calculate " onClick='operationForm();'>. Next change the function operationForm to accept no parameters. Then add id to your input answer box. Next for each if statement in the function use the elementById function to get the radios and the answerBox. For example, the first if should be
if (document.getElementById("addSelect").checked) {
answer = x + y;
document.getElementById("answerBox").value = answer;
}
This works:
JavaScript:
<script type="text/javascript">
function operationForm(){
var form = document.forms['operation_form'];
var x = form['numberOne'].value*1;
var y = form['numberTwo'].value*1;
var operation = null;
var answer = null;
if (form['addSelect'].checked == true) {
answer = x + y;
} else if (form['subtractSelect'].checked == true) {
answer = x - y;
} else if (form['multiplySelect'].checked == true) {
answer = x * y;
} else if (form['divideSelect'].checked == true) {
answer = x / y;
}
form['answerBox'].value = answer;
}
</script>
HTML:
<form name="operation_form">
<label>Enter two numbers, select an operation, and then click the button below.</label>
<br/>
<label>Number One:</label><input type="number" name='numberOne' />
<br/>
<br/>Number Two:</label><input type="number" name='numberTwo' />
<br/>
<input type="radio" name="operations" id="addSelect" value='' />Add
<input type="radio" name="operations" id="subtractSelect" value='' />Subtract
<input type="radio" name="operations" id="multiplySelect" value='' />Multiply
<input type="radio" name="operations" id="divideSelect" value='' />Divide
<br/>
<input type="button" value=" Calculate " onclick="operationForm();" />
<br/>
<label>Your answer is:</label><input type="text" name="answerBox">
</form>
Fixes between this and your example:
There are a ton of things wrong with the code you provided. I will update this answer shortly with as many as I can remember.
Update:
Please remember this is meant to be helpful and not punishing. So keep in mind that while listening to the attached feedback, I want you to learn this stuff.
Notes on your HTML:
1.) The biggest problem is none of the <label> elements have closing</label> tags.
Although, none of your html elements have any closing tags.
This will group all of the elements inside one big parent <label>.
So when the browser auto-closes the unclosed tags at the end of the document, this causes a hodgepodge of mixed up child elements. Close your elements.
2.) The first two text boxes have the same name="numbers" attribute. You can only do that with radio type inputs.
3.) Your <form> name="" attribute can NOT have the same name as the JavaScript function you are trying to call. They are stored in the same browser namespace so it causes an error.
Notes on your JavaScript:
1.) Your checked === true is an exact comparison. This will almost never evaluate to be truthful. Use checked == true, or better yet, just use if( my_element.checked ){}. Sometimes .checked will equal a string like this: .checked = 'checked'. So even though 'checked'==true it will never be truthful for 'checked'===true. The === means Exactly Equal. So only true===true.
2.) Your var x = document.opera.. ... .mberOne"); will store the whole <input> element into the x variable. You need to have ...mberOne").value; so just the value of the <input> is stored, not the whole html element.
3.) The only object that has a getElementById() method is the document. You can't use that from a document form object.
4.) You have to convert your x any y input values to numbers. If not, 5 + 5 will give you 55 instead of 10 because they are treated as strings. I multiplied them by * 1 to do that. I also changed the <input type='text' attribute to type='number' just to be safe.
5.) You can assign your answerBox.value just one time at the end of the function instead of doing it once per if(){} bracket. It will work the same but it's just much more readable.
6.) I used the syntax of form['numberOne'] instead of form.numberOne but they both work the same. It is referencing the element name (not necessarily the id) as it exists inside the form. <form> is the only object that lets you do this, whereas a <div> or <p> does not.

Expanding HTML forms using Javascript

I have a simple HTML form that asks a user to input their name, SKU, quantity, and comments. This is for a simple inventory request system.
<html>
<body>
<form id="myForm" method="post">
<input type="submit">
<br>Name: <input type="text" name="form[name]">
<br>SKU: <input type="text" name="form[SKU1]">
<br>Quantity: <input type="text" name="form[quantity1]">
<br>Comment: <input type="text" name="form[comment1]">
</form>
Add item
<script>
var num = 2; //The first option to be added is number 2
function addOption() {
var theForm = document.getElementById("myForm");
var newOption = document.createElement("input");
newOption.name = "form[SKU"+num+"]"; // form[varX]
newOption.type = "text";
theForm.appendChild(newOption); //How can I add a newline here?
optionNumber++;
}
</script>
</body>
</html>
Currently I can only get it working where it will add a single form value. I would like to recreate the entire myForm except for the name field with a single click.
Your post is very old, so presumably you've found an answer by now. However, there are some things amiss with your code.
In the JavaScript code you have
var num = 2;
This is the number that is incremented to keep track of how many "line-items" you will have on the form. In the function addOption(), though, instead of incrementing num you have
optionNumber++;
You never use optionNumber anywhere else. Your code works once, when you add the first item, but since you increment the wrong variable, you are effectively always adding option 2.
Oh, and adding the newline: you need to append a <br> element.

Categories

Resources