Expanding HTML forms using Javascript - 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.

Related

Replace input value by variable and

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>

How do a maintain an accurate character count between input from separate fields using JS?

I am using a form to build a block of text, the final output of which needs to be kept under a certain character count.
For the user, I need to be able to provide real-time character counting so they can adjust their entries as appropriate.
Basic HTML would be as follows:
<form>
<input type="text" id="#input1">
<input type="text" id="#input2">
</form>
<div class="character-counter">0</div>
However my JS/jQuery is not working very well: while it is outputting a counter in real time, it seems to be concatenating the final results in the output despite me parsing the variables as integers.
$('#input1').keyup(function() {
// Variables
var currentCharCount = parseInt($('.character-counter').text());
var fieldLength = parseInt($(this).val().length, 10);
var newCharCount = fieldLength + currentCharCount;
// Counter output
$('.character-counter').text(Number(newCharCount));
});
$('#input2').keyup(function() {
// Variables
var currentCharCount = parseInt($('.character-counter').text());
var fieldLength = parseInt($(this).val().length, 10);
var newCharCount = fieldLength + currentCharCount;
// Counter output
$('.character-counter').text(Number(newCharCount));
});
The correct solution will update the '.character-counter' div with the correct total character count between the fields every time a character is typed or deleted or pasted in.
Thanks!
You don't want the old value of the character-counter element at all, you purely want to use the lengths of the text in the two inputs. Separately: Don't use keyup, use input. (What if the user right-clicks and pastes? No keyup occurs...)
Separately, the id attributes of your input fields are incorrect: They shouldn't have the # on them.
So (see comments):
// You can hook the event on both fields with the same call
// Note using `input`, not `keyup`
$("#input1, #input2").on("input", function() {
// Get the length of each input's current value, then put it
// in the .character-counter div
$('.character-counter').text($("#input1").val().length + $("#input2").val().length);
});
<form>
<input type="text" id="input1">
<!-- No # here --------^ -->
<input type="text" id="input2">
<!-- Nor here ---------^ -->
</form>
<div class="character-counter">0</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

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.

How can I count the total number of inputs with values on a page?

I'm hoping for a super simple validation script that matches total inputs on a form to total inputs with values on a form. Can you help explain why the following doesn't work, and suggest a working solution?
Fiddle: http://jsfiddle.net/d7DDu/
Fill out one or more of the inputs and click "submit". I want to see the number of filled out inputs as the result. So far it only shows 0.
HTML:
<input type="text" name="one">
<input type="text" name="two">
<input type="text" name="three">
<textarea name="four"></textarea>
<button id="btn-submit">Submit</button>
<div id="count"></div>
JS:
$('#btn-submit').bind('click', function() {
var filledInputs = $(':input[value]').length;
$('#count').html(filledInputs);
});
[value] refers to the value attribute, which is very different to the value property.
The property is updated as you type, the attribute stays the same. This means you can do elem.value = elem.getAttribute("value") to "reset" a form element, by the way.
Personally, I'd do something like this:
var filledInputs = $(':input').filter(function() {return !!this.value;}).length;
Try this: http://jsfiddle.net/justincook/d7DDu/1/
$('#btn-submit').bind('click', function() {
var x = 0;
$(':input').each(function(){
if(this.value.length > 0){ x++; };
});
$('#count').html(x);
});

Pass variable value from form javascript

Say I got a HTML form like below and want to pass the values in the textfields to JS variables.
<form name="testform" action="" method="?"
<input type="text" name="testfield1"/>
<input type="text" name="testfield2"/>
</form>
I've only passed values to variables in PHP before. When doing it in javascript, do I need a method? And the main question, how is it done?
Here are a couple of examples:
Javascript:
document.getElementById('name_of_input_control_id').value;
jQuery:
$("#name_of_input_control_id").val();
Basically you are extracting the value of the input control out of the DOM using Javascript/jQuery.
the answers are all correct but you may face problems if you dont put your code into a document.ready function ... if your codeblock is above the html part you will not find any input field with the id, because in this moment it doesnt exist...
document.addEventListener('DOMContentLoaded', function() {
var input = document.getElementById('name_of_input_control_id').value;
}, false);
jQuery
jQuery(document).ready(function($){
var input = $("#name_of_input_control_id").val();
});
You don't really need a method or an action attribute if you're simply using the text fields in Javascript
Add a submit button and an onsubmit handler to the form like this,
<form name="testform" onsubmit="return processForm(this)">
<input type="text" name="testfield1"/>
<input type="text" name="testfield2"/>
<input type="submit"/>
</form>
Then in your Javascript you could have this processForm function
function processForm(form) {
var inputs = form.getElementsByTagName("input");
// parse text field values into an object
var textValues = {};
for(var x = 0; x < inputs.length; x++) {
if(inputs[x].type != "text") {
// ignore anything which is NOT a text field
continue;
}
textValues[inputs[x].name] = inputs[x].value;
}
// textValues['testfield1'] contains value of first input
// textValues['testfield2'] contains value of second input
return false; // this causes form to NOT 'refresh' the page
}
Try the following in your "submit":
var input = $("#testfield1").val();

Categories

Resources