Generating secure random numbers for HTML form - javascript

I am trying to create a JS function to generate 6 random, secure numbers that are inputted in a HTML form. I currently have:
function secureRandomNums(len) {
let array = new Uint8Array(len);
window.crypto.getRandomValues(array);
return array;
}
function getRandomNumbers() {
let elements = form.getElementsByName("number[]");
let nums = secureRandomNums(elements.length);
for (let i = 0; i < nums.length; i++) {
elements[i].value = nums[i]
}
}
In the HTML file I am calling the getRandomNumbers here:
<form action="AddUserNumbers" id="add_numbers_form" method="post" class="forms">
<label for="number1">Number 1:</label><br>
<input type="text" id="number1" name="number[]"><br>
<label for="number2">Number 2:</label><br>
<input type="text" id="number2" name="number[]"><br>
<label for="number3">Number 3:</label><br>
<input type="text" id="number3" name="number[]"><br>
<label for="number4">Number 4:</label><br>
<input type="text" id="number4" name="number[]"><br>
<label for="number5">Number 5:</label><br>
<input type="text" id="number5" name="number[]"><br>
<label for="number6">Number 6:</label><br>
<input type="text" id="number6" name="number[]"><br>
<input type="button" value="Generate numbers!" onclick="getRandomNumbers()"><br>
<input type="submit" id="submit_numbers" value="Submit your numbers" form="add_numbers_form"><br>
</form>
But it is not displaying the values. What am I doing wrong?
I had it working with an implementation of the Math.random() function but this is not as secure as window.crypto.

getElementsByName() is a document level method and not available at element level
Use querySelectorAll() instead to query elements that only exist in the specific form
const form = document.forms[0]
function secureRandomNums(len) {
let array = new Uint8Array(len);
window.crypto.getRandomValues(array);
return array;
}
function getRandomNumbers() {
let elements = form.querySelectorAll('input[name="number[]"]');
let nums = secureRandomNums(elements.length);
for (let i = 0; i < nums.length; i++) {
elements[i].value = nums[i]
}
}
<form>
<input name="number[]" />
<input name="number[]" />
<input name="number[]" />
<input type="button" value="Generate numbers!" onclick="getRandomNumbers()"><br>
</form>

Related

Computing using functions and arrays / Output error: Not a Number

Background: I'm practicing arrays and functions and am having trouble computing the sum of array items. I'm pretty sure there is something wrong with the function I'm writing but I'm not sure what. Using 8 input fields I'm pulling data into a array one item at a time and converted to floating numbers(for now...I'll try to fix that later). I've created a function that will compute the total of this list but it only outputs NaN.
Any suggestions are highly appreciated!
function myfunction() {
list = [];
list[0] = parseFloat(document.getElementById('number1').value);
list[1] = parseFloat(document.getElementById('number2').value);
list[2] = parseFloat(document.getElementById('number3').value);
list[3] = parseFloat(document.getElementById('number4').value);
list[4] = parseFloat(document.getElementById('number5').value);
list[5] = parseFloat(document.getElementById('number6').value);
list[6] = parseFloat(document.getElementById('number7').value);
list[7] = parseFloat(document.getElementById('number8').value);
function total(myvals) {
let total = 0;
for (let i = 0; i <= myvals.length; i++) {
total += myvals[i];
}
return total;
}
document.getElementById('results').innerHTML = total(list);
}
<form>
<input type="text" name="number1" id="number1"><br>
<input type="text" name="number2" id="number2"><br>
<input type="text" name="number3" id="number3"><br>
<input type="text" name="number4" id="number4"><br>
<input type="text" name="number5" id="number5"><br>
<input type="text" name="number6" id="number6"><br>
<input type="text" name="number7" id="number7"><br>
<input type="text" name="number8" id="number8"><br>
<input type="submit" value="Compute Score" onclick="javascript:myfunction()">
</form>
<div id="results"></div>
Here is a simple example using a for loop with querySelectorAll.
Additionally, I cleaned up your code a bit. Run the snippet below:
EDIT: Included some comments to show what's happening.
function myfunction() {
let total = 0;
//get the value for each element being called by querySelectorAll
//add values to total to get a sum
document.querySelectorAll('input').forEach(el => total += +el.value);
//append the new value to the results div
document.querySelector('#results').innerHTML = total;
}
<form>
<input type="text" name="number1" id="number1"><br>
<input type="text" name="number2" id="number2"><br>
<input type="text" name="number3" id="number3"><br>
<input type="text" name="number4" id="number4"><br>
<input type="text" name="number5" id="number5"><br>
<input type="text" name="number6" id="number6"><br>
<input type="text" name="number7" id="number7"><br>
<input type="text" name="number8" id="number8"><br>
</form>
<br/><br/>
<button type="submit" onclick="myfunction()">Compute Score</button>
<br/><br/>
<div id="results"></div>
This is resolved. I was able to fix my source code by removing
"<=" in the for loop and adding "<" in its place. Thanks everyone, I will look over everything else for extra practice!
1 - in HTML forms and their elements use names.
2 - each element of a form can be accessed by name with the form as parent
3 - if several elements have the same name (with the same type of preference) then they form an object collection
PS: I have used here [... myForm.numX] to transform the myForm.numX collection to array, so that it can accept the arry.map () method
this way:
const myForm = document.forms['my-form']
, res = document.getElementById('results')
;
myForm.onsubmit = evt =>
{
evt.preventDefault() // disable submit
let list = [...myForm.numX].map(inp => parseFloat(inp.value))
res.textContent = list.reduce((t,v)=>t+v,0)
// control...
console.clear()
console.log( myForm.numX.length, JSON.stringify(list) )
}
<form name="my-form">
<input type="text" name="numX" placeholder="num 1"><br>
<input type="text" name="numX" placeholder="num 2"><br>
<input type="text" name="numX" placeholder="num 3"><br>
<input type="text" name="numX" placeholder="num 4"><br>
<input type="text" name="numX" placeholder="num 5"><br>
<input type="text" name="numX" placeholder="num 6"><br>
<input type="text" name="numX" placeholder="num 7"><br>
<input type="text" name="numX" placeholder="num 8"><br>
<button type="submit">Compute Score</button>
</form>
<div id="results">..</div>

merge textbox values with javascript

I have 5 textbox in html. I want to merge their values. All of them have one name. How can I do it?
<input type="text" name="textbox1">
<input type="text" name="textbox1">
<input type="text" name="textbox1">
<input type="text" name="textbox1">
<input type="text" name="textbox1">
Get the values as an array, and join it
var val = [].map.call( document.getElementsByName('textbox1'), (el) => el.value ).join('');
var values = [].map.call( document.getElementsByName('textbox1'), (el) => el.value ).join('');
console.log(values)
<input type="text" name="textbox1" value="a1-">
<input type="text" name="textbox1" value="a2-">
<input type="text" name="textbox1" value="a3-">
<input type="text" name="textbox1" value="a4-">
<input type="text" name="textbox1" value="a5-">
If you want to select by the name attribute of your inputs, use getElementsByName like this:
var inputs = document.getElementsByName("textbox1");
var inputValues = "";
for(var index=0; index < inputs.length; index++) {
inputValues += inputs[index].value;
}

Output form within html page

I want to print the submitted input elements within the same page below the html form. The checked checkbox elements should all be printed. The image element can be avoided.
The function does not seem to be working.
function validateForm(myForm) {
var a = document.getElementById("fname").value;
document.getElementById("display").innerHTML = y;
var b = document.getElementByName("passwords").value;
document.getElementById("display1").innerHTML = y;
var c = document.getElementByName("gender");
var i;
for (i = 0; i < c.length; ++i) {
if (c[i].checked)
document.getElementById("display1").innerHTML = c[i].value; //looping through radio buttons
}
var d = document.getElementByName("hobbies");
for (i = 0; i < d.length; ++i) {
if (d[i] checked)
ans = ans + d[i].value; //looping through checkboxes and adding to display in display 2 id.
}
document.getElementById("display2").innerHTML = ans;
var e = document.getElementByName("cities").value;
document.getElementById("display3").innerHTML = e;
}
<form name="myForm">
<fieldset>
<legend>Personal Details</legend>
Name:
<input type="text" id="fname" <br>Password:
<input type="password" name="password" id="passwords" />
<br>Gender:
<input type="radio" name="gender" />Male
<input type="radio" name="gender" />Female</input>
<br>Hobbies:
<input type="radio" name="hobbies" value="Reading" />Reading
<input type="radio" name="hobbies" value="Writing" />Writing</input>
<br>City:
<select name="cities" />
<option>Surat</option>
<option>Ahmedabad</option>
<option>Rajkot</option>
<option>Vadodra</option>
</select>
<br>Image:
<input type="file" accept="image/*" value="image" style="margin:0px 10px 10px 100px; margin:absolute;" />
</form>
<br>
<input type="Submit" value="Submit" onSubmit="validateform(myForm);">
</fieldset>
<p id="display"></p>//display the values submitted within the html page
<p id="display1"></p>
<p id="display2"></p>
<p id="display3"></p>
getElementsByName - plural and when accessing the first, use [0] like
document.getElementsByName("cities")[0].value
missing a dot in d[i].checked
move the onSubmit="validateform(myForm);" to the form tag and do onSubmit="return validateForm(this);" and add return false;
validateForm misspelled in event handler (lower case f)
y missing
ans not defined
function validateForm(myForm) {
var a = document.getElementById("fname").value;
document.getElementById("display").innerHTML = a;
var b = document.getElementsByName("passwords").value;
document.getElementById("display1").innerHTML = a;
var c = document.getElementsByName("gender");
var i, ans;
for (i = 0; i < c.length; ++i) {
if (c[i].checked)
document.getElementById("display1").innerHTML = c[i].value; //looping through radio buttons
}
var d = document.getElementsByName("hobbies");
for (i = 0; i < d.length; ++i) {
if (d[i].checked)
ans = ans + d[i].value; //looping through checkboxes and adding to display in display 2 id.
}
document.getElementById("display2").innerHTML = ans;
var e = document.getElementsByName("cities")[0].value;
document.getElementById("display3").innerHTML = e;
return false; // normally when error but here to stay on page
}
<form name="myForm" onSubmit="return validateForm(this);">
<fieldset>
<legend>Personal Details</legend>
Name:
<input type="text" id="fname" <br>Password:
<input type="password" name="password" id="passwords" />
<br>Gender:
<input type="radio" name="gender" />Male
<input type="radio" name="gender" />Female</input>
<br>Hobbies:
<input type="radio" name="hobbies" value="Reading" />Reading
<input type="radio" name="hobbies" value="Writing" />Writing</input>
<br>City:
<select name="cities" />
<option>Surat</option>
<option>Ahmedabad</option>
<option>Rajkot</option>
<option>Vadodra</option>
</select>
<br>Image:
<input type="file" accept="image/*" value="image" style="margin:0px 10px 10px 100px; margin:absolute;" />
</form>
<br>
<input type="Submit" value="Submit">
</fieldset>
<p id="display"></p><!-- display the values submitted within the html page -->
<p id="display1"></p>
<p id="display2"></p>
<p id="display3"></p>

Finding the total or average from four input fields and displaying the value in another input field

I'm trying to use JS to get the sum or the average of four numbers from an input field and then displaying that in another text field. There's a radio button to choose if it's the total or average that is to be displayed.
Here is my html for the form:
<form name="calculate">
Mark: <input type="number" name="number" id="num1"><br>
Mark: <input type="number" name="number" id="num2"><br>
Mark: <input type="number" name="number" id="num3"><br>
Mark: <input type="number" name="number" id="num4"><br>
<input type="radio" id="numTotal" name="choice" value="total">Find total</input>
<input type="radio" id="numAvg" name="choice" value="average">Find average</input>
<br>
<input type="submit" form="calculate" value="Submit" onclick="calculate();">
<input type="reset" form="calculate" value="Reset">
<br>
Result: <input type="text" name="result" id="result" value="" disabled>
</form>
And down here is my JS code:
function calculate(){
var arr = document.getElementsByName("number");
var tot = 0;
var av = 0;
for(var i = 0; i < arr.length; i++) {
if(parseInt(arr[i].value)){
tot += parseInt(arr[i].value);
}
}
av = tot/arr.length;
if(document.getElementById("numTotal").checked) {
document.calculate.getElementbyId("result").value = tot;
}
if(document.getElementById("numAvg").checked) {
document.getElementbyId("result").value = av;
}
}
After running this, the result input field doesn't show the input. Is the error in my script or in the html or both?
<script type="text/javascript">
function calculateFunc() {
var arr = document.getElementsByName("number");
var tot = 0;
var av = 0;
for (var i = 0; i < arr.length; i++) {
if (parseInt(arr[i].value)) {
tot += parseInt(arr[i].value);
}
}
av = tot / arr.length;
if (document.getElementById("numTotal").checked) {
document.getElementById("result").value = tot;
}
if (document.getElementById("numAvg").checked) {
document.getElementById("result").value = av;
}
return false;
}
</script>
<div class="form">
<form name="calculate">
Mark: <input type="number" name="number" id="num1"><br>
Mark: <input type="number" name="number" id="num2"><br>
Mark: <input type="number" name="number" id="num3"><br>
Mark: <input type="number" name="number" id="num4"><br>
<input type="radio" id="numTotal" name="choice" value="total">Find total</input>
<input type="radio" id="numAvg" name="choice" value="average">Find average</input>
<br>
<br>
Result: <input type="text" name="result" id="result" value="" disabled>
</form>
<input type="submit" value="Submit" onclick="calculateFunc();">
<input type="reset" value="Reset">
</div>
This is work for me in Chrome :)
document.calculate.getElementbyId("result").value = tot;
if(document.getElementById("numTotal").checked) {
document.calculate.getElementbyId("result").value = tot;
}
if(document.getElementById("numAvg").checked) {
document.getElementbyId("result").value = av;
}
need to replace
document.getElementbyId("result").value = tot;
if(document.getElementById("numTotal").checked) {
document.calculate.getElementById("result").value = tot;
}
if(document.getElementById("numAvg").checked) {
document.getElementById("result").value = av;
}

JavaScript sorting a string of integers

So I have this form which takes in a string of numbers that needs to be split at each semi colon and space. Afterwards, it sorts the numbers and returns the sorted list.
For some reason, when I click on the button, it does not post the value in the text box.
Can anyone help me solve my problem please! Thank you.
Edit 1: Added the name to the form and added the fieldset
function sort() {
var allNumbers = document.mainForm.mainSet.numbers.value.split("; ");
allNumbers.parseFloat;
for (var i = 0; i < allNumbers.length; i++) {
allNumbers[i] = parseInt(allNumbers[i], 10);
}
allNumbers.sort();
document.mainForm.mainSet.sorted.value = allNumbers.toString();
}
<form name="mainForm">
<fieldset name="mainSet">
Enter Numbers:
<input type="text" class="text" name="numbers" />
<br/>
<br/>Select Option:
<select name="sortOption" id="dropDown">
<option value="Ascending" class="select">Ascending</option>
<option value="Descending" class="select">Descending</option>
</select>
<br/>
<br/>Sorted Numbers:
<input type="text" class="text" name="sorted">
<br/>
<br/>
<input type="button" value="Sort Numbers" id="submit" onclick="sort()" />
</fieldset>
</form>
I think this is what you are looking for. This will order the number by what you have selected in your sortOption field.
var order;
function sort() {
order = document.getElementById("dropDown").value;
var allNumbers = document.getElementById("numbers").value.split("; ");
var nums = [];
for (var i = 0; i < allNumbers.length; i++) {
nums.push(parseInt(allNumbers[i], 10));
}
nums.sort(function(a, b) {
if (a > b)
return order == 'asc' ? 1 : -1;
else
return order == 'asc' ? -1 : 1;
});
document.getElementById("sorted").value = nums.toString();
}
<form name="mainForm">
<fieldset name="mainSet">
Enter Numbers:
<input id="numbers" type="text" class="text" name="numbers" />
<br/>
<br/>Select Option:
<select name="sortOption" id="dropDown">
<option value="asc" class="select">Ascending</option>
<option value="desc" class="select">Descending</option>
</select>
<br/>
<br/>Sorted Numbers:
<input id="sorted" type="text" class="text" name="sorted">
<br/>
<br/>
<input type="button" value="Sort Numbers" id="submit" onclick="sort()" />
</fieldset>
</form>
I don't see any elements named "mainForm" or "mainSet" in the HTML. Likewise, I'm not entirely sure what the purpose of "allNumbers.parseFloat;" is, either, since that's not how to invoke a function, and parseFloat isn't a member of Array.
function sort() {
function asc(a,b)
{
return a - b;
}
function desc(a,b)
{
return b - a;
}
var allNumbers = document.getElementById("numbers").value.split("; ");
var nums = [];
var order = document.getElementById("dropDown").value;
for (var i = 0; i < allNumbers.length; i++) {
nums.push(parseInt(allNumbers[i], 10));
}
nums.sort((order == 'asc') ? asc : desc);
document.getElementById("sorted").value = nums.toString(',');
}
<form name="mainForm">
<fieldset name="mainSet">
Enter Numbers:
<input id="numbers" type="text" class="text" name="numbers" />
<br/>
<br/>Select Option:
<select name="sortOption" id="dropDown">
<option value="asc" class="select">Ascending</option>
<option value="desc" class="select">Descending</option>
</select>
<br/>
<br/>Sorted Numbers:
<input id="sorted" type="text" class="text" name="sorted">
<br/>
<br/>
<input type="button" value="Sort Numbers" id="submit" onclick="sort()" />
</fieldset>
</form>

Categories