undefined field javascript loop - javascript

I'm trying to use ajax with a form I'm working on, and to do so I am building a post string,
Which looks like this: field_name=field_value&field_name=field_value and so on..
I am having trouble with figuring out where "undefined" is coming from. Take a look at this screenshot
If you look carefully, you'll see the loop I am using, outputs "undefinedemail=Emailpassword=Password" instead of "email=Email&password=Password"
Here is the stripped version of the form & javascript I am using:
<form id="signup_form" enctype="multipart/form-data" action="register.php" method="post">
<input name="email" type="text" value="Email"/>
<input name="password" type="text" value="Password"/>
<input name="email_confirm" type="text" value="Confirm Email"/>
<input name="password_confirm" type="text" value="Confirm Password"/>
<input name="first_name" type="text" value="First Name"/>
<input name="country" type="text" value="Country"/>
<input name="birthday" type="text" value="Birthday DD/MM/YYYY"/>
<input name="last_name" type="text" value="Last Name"/>
<input name="city" type="text" value="City"/>
<input name="profession" type="text" value="Profession"/>
<input type="radio" name="gender" value="Male"><span>Male</span>
<input type="radio" name="gender" value="Female"><span>Female</span>
<input type="checkbox" name="user_type" value="User type" /><span>Checkbox</span>
<button type="submit" name="submit" class="" id="submit">Sign up</button>
</form>
javascript:
var post_string;
var input = document.forms["signup_form"].getElementsByTagName("input");
for(var i = 0; i < input.length; i++) {
post_string += input[i].name + "=" + input[i].value;
if(i > 0 && i < input.length) { post_string += "&"; }
}
Thanks for helping !

You did forget to initialize your accumulator variable with the empty string, so the first time you appended something it evaluated to undefined. Use
var post_string = "";

It looks as if you're declaring post_string as an undefined variable, instead of declaring it as an empty string e.g. var post_string = "".
That means, for the first look-up of post_string, it's returning the undefined variable instead.

Related

How can generate numbers from given number and then populate in while loop

i'm trying to generate numbers from from_number value and then populate in a loop
Let's say that from_number value is 10
`
<label>
<input type="text" class="form-control"
id="from_number" placeholder="from_number"
autocomplete="off">
</label>
start php while.. I have 50 inputs with the same name ['list']
<label>
<input type="text" class="form-control" name="list"
placeholder="list" autocomplete="off">
</label>
`
end php
`
$('#from_number').blur(function () {
let begin = document.getElementById('from_number').value;
let arr = [];
let inputs = document.querySelectorAll('[name^="list"]');
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = arr.push(begin++) + begin -1;
}
});
`
Thanks
DESIRED OUTPUT
`
<input type="text" class="form-control" name="list" value="10" autocomplete="off">
<input type="text" class="form-control" name="list" value="11" autocomplete="off">
<input type="text" class="form-control" name="list" value="12" autocomplete="off">
<input type="text" class="form-control" name="list" value="13" autocomplete="off">
<input type="text" class="form-control" name="list" value="14" autocomplete="off">
<input type="text" class="form-control" name="list" value="50" autocomplete="off">
`
The document.querySelectorAll() method returns a NodeList object container which can be iterated over as an array. The event listener in the following code fragment checks that the input value is numeric before converting it to an integer and iterating over the array of inputs.
const startValueElem = document.getElementById("from_number");
startValueElem.addEventListener("blur", (event) => {
if (!isNaN(event.target.value)) {
let value = parseInt(event.target.value);
Array.from(document.querySelectorAll('[name^="list"]')).forEach(el => {
el.value = value++;
});
}
});

Using onkeyup to display output whilst typing

I am trying to use "onkeyup" to display the realtime output of a form. It appears to be working just fine in my Codepen project, but not in VS Code. I can't pinpoint where I'm going wrong.
Here's my Codepen: https://codepen.io/jonah-cockshaw/pen/OJOrapb
Here's the code from VS Code:
<h3>Chiller capacity</h3>
<p>Please input each chiller’s rated capacity in kW. The rated capacity is on the chiller nameplate.</p>
<label for="chiller-1">Chiller 1</label><br>
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-1" name="chiller-1" placeholder="Input number in KW" value="" required><br>
<label for="chiller-2">Chiller 2</label><br>
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-2" name="chiller-2"placeholder="Input number in KW" value=""><br>
<label for="chiller-3">Chiller 3</label><br>
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-3" name="chiller-3" placeholder="Input number in KW" value=""><br>
<label for="chiller-4">Chiller 4</label><br>
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-4" name="chiller-4" placeholder="Input number in KW" value=""><br>
<label for="chiller-5">Chiller 5</label><br>
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-5" name="chiller-5" placeholder="Input number in KW" value=""><br>
<p id="output">Output goes here</p>
function addAll() {
const chiller1 = Math.floor(document.getElementById("chiller-1").value);
const chiller2 = Math.floor(document.getElementById("chiller-2").value);
const chiller3 = Math.floor(document.getElementById("chiller-3").value);
const chiller4 = Math.floor(document.getElementById("chiller-4").value);
const chiller5 = Math.floor(document.getElementById("chiller-5").value);
const allChillersValue = chiller1 + chiller2 + chiller3 + chiller4 + chiller5;
// console.log(allChillersValue);
document.getElementById('output').innerHTML = allChillersValue;
};
the issue come from the way you add the keyup event listener
onkeyup=`addAll()`
the valid html syntax is
onkeyup="addAll()"
but a better way i can advice is use addEventlistener method on all input-field class
[...document.getElementsByClassName('input-field')].forEach(input => {
input.addEventListener('keyup', addAll);
});
[...document.getElementsByClassName('input-field')].forEach(input => {
input.addEventListener('keyup', addAll);
});
function addAll() {
const chiller1 = Math.floor(document.getElementById("chiller-1").value);
const chiller2 = Math.floor(document.getElementById("chiller-2").value);
const chiller3 = Math.floor(document.getElementById("chiller-3").value);
const chiller4 = Math.floor(document.getElementById("chiller-4").value);
const chiller5 = Math.floor(document.getElementById("chiller-5").value);
const allChillersValue = chiller1 + chiller2 + chiller3 + chiller4 + chiller5;
console.log(allChillersValue);
document.getElementById('output').innerHTML = allChillersValue;
}
<h3>Chiller capacity</h3>
<p>Please input each chiller’s rated capacity in kW. The rated capacity is on the chiller nameplate.</p>
<label for="chiller-1">Chiller 1</label><br>
<input type="number" class="input-field" id="chiller-1" name="chiller-1" placeholder="Input number in KW" value="" required><br>
<label for="chiller-2">Chiller 2</label><br>
<input type="number" class="input-field" id="chiller-2" name="chiller-2"placeholder="Input number in KW" value=""><br>
<label for="chiller-3">Chiller 3</label><br>
<input type="number" class="input-field" id="chiller-3" name="chiller-3" placeholder="Input number in KW" value=""><br>
<label for="chiller-4">Chiller 4</label><br>
<input type="number" class="input-field" id="chiller-4" name="chiller-4" placeholder="Input number in KW" value=""><br>
<label for="chiller-5">Chiller 5</label><br>
<input type="number" class="input-field" id="chiller-5" name="chiller-5" placeholder="Input number in KW" value=""><br>
<p id="output">Output goes here</p>
It's a copy-paste issue. VS Code has turned single quotes ' into ticks `.
Change the ticks surrounding the onkeyup property value for each element to a single or double quote instead.
INCORRECT
<input type="number" onkeyup=`addAll()` class="input-field" id="chiller-1" name="chiller-1" placeholder="Input number in KW" value="" required><br>
FIXED
<input type="number" onkeyup="addAll()" class="input-field" id="chiller-1" name="chiller-1" placeholder="Input number in KW" value="" required><br>
By fixing those characters, the code will run.

Avoid user touching HTML or JS in payment page

I'm testing stripe API and I'm wondering how to avoid that user changes prices by HTML and/or javascript code?
As you can see in my code, anybody with a bit of coding knowledge could change price value in the input #price, input checkboxes, or even directly change it in console with $("#price").val(some_value);
HTML SAMPLE CODE
<form id="articles_form">
<div>
<div>
<label for="one_article">One Article</label>
<input class="articles" type="checkbox" name="one_article" id="one_article" value="90">
</div>
<div>
<label for="another_article">Another Article</label>
<input class="articles" type="checkbox" name="another_article" id="another_article" value="75">
</div>
</form>
<form action="payment_form.php" method="post" id="payment-form">
<div class="form-row">
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>" />
<input type="hidden" name="price" id="price" value="">
<input type="hidden" name="products" id="products">
<input type="text" name="first_name" class="form-control StripeElement StripeElemet--empty" placeholder="Name">
<input type="text" name="last_name" class="form-control StripeElement StripeElemet--empty" placeholder="Surname">
<input type="email" name="email" class="form-control StripeElement StripeElemet--empty" placeholder="Email">
</div>
</form>
JS SAMPLE CODE
<script>
$(".articles").each(function(){
$(this).on("change", function(){
let value = 0;
let products = '';
$(".articulos").each(function(){
if(this.checked == true){
value = parseInt($(this).val()) + value;
products = $(this).attr("id") + '|' + products;
}
})
$("#price").val(value);
$("#btn-pagar").text('payment ' + value + '€');
$("#products").val(products);
})
})
</script>
How could avoid that?

Push elements in array from html form

I'm trying to get user input from an html form into an array, by using getElementsByClassName.
It works using getElementsById("...").value and then push it into the empty array. But when I try to do it with getElementsByClassName, I get a htmlcollection returned and something seems to go wrong. It doesn't register the user input.
Any help is strongly appreciated, I've been trying to find a solution all day...
<title>Word Input</title>
<form>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<button id="submit"> Submit </button>
</form>
<script>
document.getElementById("submit").addEventListener("click", handler9);
function handler9() {
let vocabEnglish = [];
let englishWords = document.getElementsByClassName("englishWord");
for (let i = 0; i < englishWords.length; i++) {
let englishWord = englishWords[i].innerText;
vocabEnglish.push(englishWord);
}
}
console.log(vocabEnglish);
</script>
I expect the words to be pushed into an array, but I get returned an empty one.
A few issues:
Your indentation is off, and putting it right reveals that the console.log happens outside of the function that has the local variable vocabEnglish. So obviously it is undefined outside the function.
The value of an input element is not retrieved via the innerText property, but value.
When you click the button the form is submitted, and a reload of the page happens, whereby you lose the output. Cancel the submission with e.preventDefault
Corrected code:
document.getElementById("submit").addEventListener("click", handler9);
function handler9(e) {
let vocabEnglish = [];
let englishWords = document.getElementsByClassName("englishWord");
for (let i = 0; i < englishWords.length; i++) {
let englishWord = englishWords[i].value;
vocabEnglish.push(englishWord);
}
console.log(vocabEnglish);
e.preventDefault()
}
use value instead of innerText
I've made an example here, it still prints to the console for you to view.
document.getElementById("submit").addEventListener("click", handler9);
function handler9() {
let vocabEnglish = [];
let englishWords = document.getElementsByClassName("englishWord");
for (let i = 0; i < englishWords.length; i++) {
let englishWord = englishWords[i].value;
vocabEnglish.push(englishWord);
}
console.log(vocabEnglish);
}
<form>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<button id="submit"> Submit </button>
</form>
<form>
<input type="text" class="englishWord"> <input type="text" class="spanishWord">
<br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord">
<br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord">
<br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord">
<br> <br>
<input type="text" class="englishWord"> <input type="text" class="spanishWord"> <br> <br>
<button id="submit"> Submit </button>
</form>
<script>
document.getElementById("submit").addEventListener("click", handler9);
function handler9() {
let vocabEnglish = [];
let englishWords = document.getElementsByClassName("englishWord");
for (let i = 0; i < englishWords.length; i++) {
let englishWord = englishWords[i].value;
vocabEnglish.push(englishWord);
}
}
console.log(vocabEnglish);
</script>

Calculate values of multiple fields and display for every row in Javascript

I have an invoice which is not a table but inside a div in html are some input fields. These fields are being created dynamically by clicking on a button.
<li><input type="text" id="cost[]" name="unit[]" value="<?php echo $val->unit ; ?>"> </li>
<li><input type="text" id="qty[]" name="rate[]" value="<?php echo $val->rate ; ?>"> </li>
<li><input type="text" id="price[]" name="total[]" value="<?php echo $val->total ; ?>"> </li>
Now I want to multiply unit with rate and display it in the total field.
My Javascript is
window.onkeyup=function() {
var str = document.getElementById("cost[]").value;
var str1 = document.getElementById("qty[]").value;
var price = parseFloat(str*str1);
document.getElementById("price[]").value = price;
}
The javascript above works fine but it works only for the first row. For the rest of the rows below the first row, it does not work. I want the calculation for all the rows. I have seen some of the answers but none of them works in my case.
Any help is welcome.
What I observe from your code is that you might be using same ids for multiple items.
The "id" attribute assigns a name to an element. This name must be unique in a document.
Though we have a workaround like:
document.querySelectorAll("[id='someID']");
to select all elements with same "id"s, your HTML will be invalid.
And this is why we have "class" instead. A class is a group of elements.
Though I have used "name" attribute.
May be what you are looking for:
window.onkeyup=function() {
var items = document.querySelectorAll(".item");
var itemsArray = Array.prototype.slice.call(items,0);
var unit, rate, total, net = 0;
itemsArray.forEach(function(el){
unit = el.querySelector('input[name="unit[]"]').value;
rate = el.querySelector('input[name="rate[]"]').value;
total = unit * rate;
el.querySelector('input[name="total[]"]').value = total;
net+=total;
});
document.getElementById('net').value=net;
}
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
<br><br>
<div class='item'>
<li><input type="text" name="unit[]" value=""> </li>
<li><input type="text" name="rate[]" value=""> </li>
<li><input type="text" name="total[]" value=""> </li>
</div>
</br></br>
<li><input id='net' type="text" name="net[]" value=""> </li>
As I've stated before, It's not recommended to keep multiple elements with the same id on your HTML. But if you want to keep things that way, then you can make use of document.querySelectorAll and iterate over the elements to sum their value and store it in the total:
window.onkeyup=function() {
var costs = document.querySelectorAll("input[id='cost[]'");
var qtys = document.querySelectorAll("input[id='qty[]'");
var price = 0;
for (var i = 0; i < costs.length; i++){
price += +costs[i].value + +qtys[i].value;
}
document.getElementById("price[]").value = price;
}
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<br>
<input type="text" id="cost[]" name="unit[]" value="2">
<input type="text" id="qty[]" name="rate[]" value="4">
<input type="text" id="price[]" name="total[]" value="">
var invoices = document.querySelectorAll('.invoice')
var handleChange = function (foo, bar, total) {
let str = +foo.value || 0
let str2 = +bar.value || 0
total.value = parseFloat(str*str2)
}
invoices.forEach(function(invoice) {
var foo = invoice.querySelector('input[name=foo]')
var bar = invoice.querySelector('input[name=bar]')
var total = invoice.querySelector('input[name=total]')
foo.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
bar.addEventListener('keyup', function() {
handleChange(foo, bar, total)
})
})
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo" value="">
<input type="text" name="bar" value="">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
<div class="invoice">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="total">
</div>
Notice how i prepended a + to the parse of str & str2 this operator turns any String number into a Number
I recommend you do this because when querying the value of a input[type=text] - it will give you the value represented as a String...
This is fine when multiplying e.g '1'*'2'// = 2...
But, if you want to ADD two numbers together, your sum will be interpreted as concatenation e.g '2'+'2' // = '22'
It may also be smart to default your values to 0 if a value is not provided or a Alphabetic or special character is put into the input e.g 'hello'*'2' // = NaN
try
var str = +foo.value || 0;
var str1 = +bar.value || 0;
var price = parseFloat(str*str1);
Alternatively, make your input type="number" this will limit the user to only be able to input numbers.

Categories