Take Input from a form and save it to an array - javascript

I am having trouble trying to convert this into an array. I don't fully understand how to take input from a form and save it in an array.
My project states: Do NOT save the input in a set of variables and then put those in an array.
Use the array as your collection of data saving variables. (That is what a data
structure is for.)
I have looked for the last 2 hours trying to find something to help me. I have to do this project in JavaScript, but keep finding jquery and I'm not quite sure on how to convert it to Javascript
Any suggestions on how I can take the form input and save it in an array?
This is only a little bit of my project. I just took the first function and the HTML that is attached to the function.
Code in the snippet.
function getID() {
var studentID = new Array();
studentID = document.forms["getFormInfo"]["txtStudentID"].value;
var numberOnly = /^[0-9]+$/;
//Checks for a null/blank within Student ID: field.
if (studentID.length == 0) {
document.getElementById('divAllField').style.display = '';
document.forms["getFormInfo"]["txtStudentID"].focus();
return false;
} //End of if statement
else {
if (studentID.length == 8 && studentID.match(numberOnly)) {
//Run the next function
getFirstName();
} //End of else/if statement
else {
//Show Error Message
document.getElementById('divStudentID').style.display = "";
//Focus on input field with the error.
document.forms["getFormInfo"]["txtStudentID"].focus();
} //end of else/if/else statement
} //End of else statement
} //End of function getID()
h1 {
text-align: center;
color: teal;
}
table {
border-spacing: 8px;
border: 2px solid black;
text-align: justify;
}
th {
text-align: center;
padding: 8px;
color: blue;
font-size: 125%;
}
td {
padding: 5px;
}
input,
select {
width: 200px;
border: 1px solid #000;
padding: 0;
margin: 0;
height: 22px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
input {
text-indent: 2px;
}
label {
float: left;
min-width: 115px;
}
div {
padding: 3px;
color: red;
font-size: 80%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Begining of the header -->
</head>
<!-- End of the header -->
<body>
<!-- Everything in the <body> </body> displays on the webpage -->
<form id="getFormInfo">
<!-- Creates a form with an ID -->
<table id="tableInfo">
<!-- Creates a table within the form -->
<!-- Creates a table header within the form and table -->
<th>User Information</th>
<!-- Error Message for all fields if they are null/blank -->
<tr>
<td><strong><div id="divAllField" style="display: none;">
Please make sure all input boxes are filled out.
</div></strong>
</td>
</tr>
<!-- Student ID Input -->
<tr>
<td><strong><label>Student ID:</label></strong>
<input type="text" name="txtStudentID" maxlength="8" placeholder="8 Digit ID" value="00149371" required>
<!-- Error Message for Student ID -->
<strong><div id="divStudentID" style="display: none;">
Please enter your 8 Digit Student ID. (Whole Numbers Only)</br>
Example: 00123456
</div></strong>
</td>
</tr>
<tfoot>
<td>
<input type="button" onclick="getID();" value="Submit">
</tfoot>
</td>
</table>
<!-- End of tableInfo -->
</form>
<!-- End of getInfo -->
</body>
</html>
Anyone know how I can save the input from the form and save it into an array?
Please help, I've been working on this project for over 10 hours.

Use the push function to add items to the array.
function getID() {
var studentID = [];
var tstStudentIdVal = document.forms["getFormInfo"]["txtStudentID"].value
studentID.push(tstStudentIdVal);
var numberOnly = /^[0-9]+$/;
//Checks for a null/blank within Student ID: field.
if (tstStudentIdVal.length == 0) {
document.getElementById('divAllField').style.display = '';
document.forms["getFormInfo"]["txtStudentID"].focus();
return false;
} //End of if statement
else {
if (tstStudentIdVal.length == 8 && tstStudentIdVal.match(numberOnly)) {
//Run the next function
getFirstName();
} //End of else/if statement
else {
//Show Error Message
document.getElementById('divStudentID').style.display = "";
//Focus on input field with the error.
document.forms["getFormInfo"]["txtStudentID"].focus();
} //end of else/if/else statement
} //End of else statement
} //End of function getID()

If you can't use jQuery, I think the most elegant solution is to use querySelectorAll() to get a nodeList of all your inputs, then use a combination of Function.prototype.call() and Array.prototype.map() to translate the array of inputs into an array of your own design.
In the snippet below, the resulting array has objects each which have a name and value, which come directly from the text inputs in your form (your question isn't quite clear on how the resulting array should look).
function getID() {
var nodes = document.forms["getFormInfo"].querySelectorAll("input[type='text']");
var array = [].map.call(nodes, function(item) {
return {name : item.name, value : item.value};
});
console.log(array);
}
<form id="getFormInfo">
<input type="text" name="txtStudentID"/>
<input type="text" name="firstName"/>
<input type="text" name="lastName"/>
<input type="button" onclick="getID();" value="Submit"/>
</form>

Related

Concate two input string instantly without a button(as soon as we move the cursor out of the second box)

A javascript program to concate the first name and last name, but the concated string gets displayed as the cursor moves out from the last name text box
`
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form name="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
<input type="Button" name="" value="Refresh" onclick="refresh()">
<input type="Button" name="" value="Full Name" onclick="concat()"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
`
I have to makes changes in this so that the full name button is gone and the two name are concatenated instantly
To achieve that result you may use a keyup event handler on your input elements so that a given logic will be executed every time the user type something.
Such logic just fetches the values of those input elements, concatenates the two string and sets the value of the return input element.
I used a general approach as far as possible so that the conditions to fetch those two input elements are defined as css selectors in the targetSelectors array.
//selectors relative to the root document for the input element to concat
const targetSelectors = ['#myform [name=fst]', '#myform [name=snd]'];
//adds a keyup event handler to all the elements in targetSelectors
targetSelectors.forEach( (targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//concats the fields value
const concatenated = concatFields(' ');
//refreshes the result input field value with the new one
refreshField('input[name=result]', concatenated);
});
});
//sets the value of the input element found with targetSelector
function refreshField(targetSelector, value){
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
function concatFields(spacer = ''){
return targetSelectors.map( targetSelector => document.querySelector(targetSelector).value ).join(spacer);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form id="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
And this an attempt went too far with the generalization able to keep an arbitrary number of inputs bound to each other in the aim of concatenating their values inside an output element when the change event occurs on any of those inputs.
*the answer was accepted already.. it was for the sake of making sense of the generalized approach and nothing else
const c = new Concatenator(
retrieveClassSelectors('#showingMaxPotential input.concat'),
'#showingMaxPotential input[name=result]');
//returns an array of selector (sorted) based on the class attribute belonging to all the elements grabbed by the matchingSelector
function retrieveClassSelectors(matchingSelector){
const specificSelectors =
[...document.querySelectorAll(matchingSelector)]
.map(target => {
const classesSelector =
target.getAttribute('class')
.replace(/[^\s]+/g, '.$&')
.replace(/\s/g, '');
return classesSelector;
}).sort();
return specificSelectors;
}
function Concatenator(targetSelectors, outputSelector) {
this.init = () => {
//adds a keyup event handler to all the elements in targetSelectors
this.targetSelectors.forEach((targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//refreshes the result input field value with the new one
this.refreshField(this.outputSelector, this.concatFields(' '));
});
});
}
//sets the value of the input element found with targetSelector
this.refreshField = (targetSelector, value) => {
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
this.concatFields = (spacer = '') => {
return this.targetSelectors.map(targetSelector => document.querySelector(targetSelector).value).join(spacer);
}
this.targetSelectors = targetSelectors;
this.outputSelector = outputSelector;
this.init();
}
form#showingMaxPotential{
border: solid 1px darkgray;
padding: 1em;
}
form#showingMaxPotential > label,
form#showingMaxPotential > input{
display: block;
}
form#showingMaxPotential > input{
margin-bottom: 1em;
}
<form id="showingMaxPotential">
<label>Enter <b>first</b> item name:</label>
<input type="text" name="i1" class="concat item-1">
<label>Enter <b>last</b> item name:</label>
<input type="text" name="i3" class="concat item-3">
<label>Enter <b>middle</b> item name:</label>
<input type="text" name="i2" class="concat item-2">
<label>Full Name:</label>
<input type="text" name="result" disabled>
</form>

Simple Javascript client-side form validation

Goodmorning everyone,
I have a problem with a script for validating a form.
Given that the module has server-side validation in PHP, what I want to achieve, too, is client-side validation.
This validation is very simple.
When you click on the SUBMIT button, you must check if all the mandatory fields have been filled in.
If they are not:
must add a class to the input to make it change color;
must change the content of the icon next to the input field.
I use this script which works with regards to check and class on input. However, it uses a check on the NAME of the fields.
HTML
<form id="signinform" method="post" action="" class="wp-user-form" autocomplete="off" onsubmit="event.preventDefault(); validateMyForm();" novalidate>
<div class="msc-login-form-input">
<input type="text" name="log" value="" size="20" id="user_login" placeholder="Username o Email" autocomplete="off" required onkeyup="validateElement(this)"/>
<span id="errorsign"></span> </div>
<div class="msc-login-form-input">
<input type="password" name="pwd" value="" size="20" id="user_pass" placeholder="Password" autocomplete="off" required onkeyup="validateElement(this)"/>
<span id="errorsign"></span> </div>
<div class="msc-login-form-input-sendh">
<input type="submit" id="submit-login" name="submit-login" value="" class="user-submit" />
</div>
</form>
JS
<script lang="javascript">
function validateMyForm(){
let isFormValid = true;
let elems = document.getElementsByName("namefield");
for(let i=0; i< elems.length; i++)
{
let elem = elems[i];
if(elem.value.length < 1)
{
if(isFormValid){
isFormValid = false;
}
}
validateElement(elem);
}
if(isFormValid)
{
document.getElementById("signinform").submit();
return true;
}
}
function validateElement(elem){
if(elem.value.length < 1)
{
elem.className = "errorClass";
}else{
elem.className = "okClass";
}
}
</script>
CSS
<style>
.msc-login-form-input input.okClass {
background-color: #ffffff;
color: #3F4254;
}
.msc-login-form-input input.errorClass {
background-color: #4d40ff;
color: #ffffff;
}
.msc-login-form-input #errorsign {
width: 35px;
background-color: rgba(0,0,0,0.05);
min-height: 100%;
align-items: center;
justify-content: center;
text-align: center;
display: flex;
}
.msc-login-form-input #errorsign::before {
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f100";
}
.msc-login-form-input #errorsign.fail::before {
content: "\f00d";
color:#4d40ff;
}
.msc-login-form-input #errorsign.okay::before {
content: "\f00c";
color:#FF1493;
}
</style>
The problem is that the NAMEs of my fields are not the same and therefore that loop cannot work.
How can I solve without duplicating the loop for each form field?
How can I also add the control on the class of the icon next to it?
Thank you.
If you don't want to use the builtin validation, I'd do it as follows
let formvalid = true;
//these are the divs surrounding your elements to be validated
let elements = document.getElementsByClassName("msc-login-form-input")
for (let i = 0; i < elements.length; i++) {
//this is the input to be validated
let input = elements[i].getElementsByTagName("input")[0];
//this is the span element holding the icon
let icon = elements[i].getElementsByTagName("span")[0];
let valid = validateElement(input);
//set the classes input and span according to the validation result
input.classList.Add(valid ? "okClass" :"errorClass");
span.classList.Add(valid ? "okay" :"fail");
input.classList.Remove(valid ? "errorClass": "okClass");
span.classList.Remove(valid ? "fail" : "okay" );
//the form is only valid if ALL elements are valid
formvalid &= valid;
}
function validateElement(element) {
if (input.value.length === 0) return false;
//any other validations you want to do
return true;
}
Furhtermore you have a problem in your DOM tree. You have mutliple <span> elements with the same id="errorsign". That's not gonna work, because an id has to be unique. So remove the ids and grab the <spans> from their parents as shown above.
You could also just add the "okay" and "fail" to the surrounding <div> and adapt your css accordingly. Ie something like the following CSS
.msc-login-form-input.okay input {
...
}
.msc-login-form-input.fail input {
...
}
.msc-login-form-input.okay span::before {
...
}
.msc-login-form-input.fail span::before {
...
}
And the following JS
let formvalid = true;
//these are the divs surrounding your elements to be validated
let elements = document.getElementsByClassName("msc-login-form-input")
for (let i = 0; i < elements.length; i++) {
//this is the input to be validated
let input = elements[i].getElementsByTagName("input")[0];
let valid = validateElement(input);
element.classList.Add(valid ? "okay" : "fail");
element.classList.Remove(valid ? "fail": "okay");
formvalid &= valid;
}

Copy/Paste String in HTML Fields

I am trying to copy a string from notepad to HTML form on base of new line but it is not working for me, below is the code snippet for your help. First Line Should Populate in Field 1, 2nd in Field 2 and 3rd in Field 3
$("input[name=query]").on("paste", function() {
var $this = $(this);
setTimeout(function() {
var id = $this.attr("id"), no = parseInt(id.substr(5)),
//groups = $this.val().split(/\s+/);
//groups = $this.val().split('.');
groups = $this.val().split(/[\n\r]/g);
if (groups) {
var i = 0;
while (no <= 3 && i < groups.length) {
$("#input" + no).val(groups[i]);
++no;
++i;
}
}
}, 0);
});
form {
width: 500px;
margin: 50px auto 0;
}
form h2 {
text-align: center;
text-decoration: underline;
}
form table {
width: 100%;
}
form input {
width: 100%;
height: 40px;
border-radius: 5px;
outline: none;
padding: 0 15px;
border: 1px solid #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form name="form1" action="#" method="get" target="">
<h2>Copy/Paste String</h2>
<table cellpadding="0" cellspacing="20">
<tr>
<td width="100px"><h3>Line 1:</h3></td>
<td><input id="input1" name="query" placeholder="Line 1" type="text"></td>
</tr>
<tr>
<td width="100px"><h3>Line 2:</h3></td>
<td><input id="input2" name="query" placeholder="Line 2" type="text" ></td>
</tr>
<tr>
<td width="100px"><h3>Line 3:</h3></td>
<td><input id="input3" name="query" placeholder="Line 3" type="text"></td>
</tr>
</table>
</form>
Below is the 3 lines I am trying to copy from notepad behavior is new line
This is Line 1
This is Line 2
This is Line 3
Kindly have a look into snippet and guide, where I am doing mistake
The problem with that is your line breaks are being lost when you paste into the (single-line) inputs; only textareas will preserve line breaks; normal inputs will collapse multi-line text into a single line.
The solution is to read the pasted input not from the input but via the clipboardData() area of the event - not the contrived jQuery event, but the original (native) event. jQuery exposes this via the originalEvent property.
This also means you can avoid the timeout hack. All in all:
let fields = $('input[name=query]');
$(document).on('paste', 'input[name=query]', evt => {
evt.preventDefault();
let pasted = evt.originalEvent.clipboardData.getData('text/plain');
pasted.split(/\n/).forEach((line, i) => fields[i].value = line);
});
Fiddle
(Further reading: my blog post about hacking incoming clipboard data.)
You can try this :
$("input[name=query]").on("paste", function(e) {
// Stop data actually being pasted into div
e.stopPropagation();
e.preventDefault();
// Get pasted data via clipboard API
pastedData = window.event.clipboardData.getData('Text');
// Do whatever with pasteddata
var $this = $(this);
setTimeout(function() {
var id = $this.attr("id"), no = parseInt(id.substr(5)),groups = pastedData.split("\n");
if (groups) {
var i = 0;
while (no <= 3 && i < groups.length) {
$("#input" + no).val(groups[i]);
++no;
++i;
}
}
}, 0);
});
Good luck!

Adding labels to QR codes

I have created a QR code generator. The user can create multiple QR codes.
I would like the user to be able to name each QR code (referred to as a checkpoint) by writing the desired checkpoint name in the text input field, clicking the Assign Name button and having the text input field disappear, being replaced by the name the user typed into the field.
The user can input checkpoint names, however, it only works for the first QR code printed, and the label only appears below the QR code. Below is the code that I have so far. Any help or suggestions to help me get the ball rolling on this would be very much appreciated. Thank you!
Note: If you try to run this to see the QR codes, you will have to enter something in the text field and press generate. They won't appear automatically.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: arial, sans-serif;
}
section {
margin: 50px auto;
max-width: 350px;
text-align: center;
}
textarea {
width: 50%;
height: 50px;
margin-bottom: 10px;
}
#size {
max-width: 64px;
}
label {
display: inline-block;
width: 140px;
text-align: left;
}
</style>
<script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
</head>
<body>
<section>
<h1>QR Code Generator</h1>
<p>Enter a URL or some text bellow and hit the Generate button (<kbd>Ctrl</kbd>+<kbd>Enter</kbd>)!</p>
<textarea id="textarea" autofocus></textarea>
<div class="block">
<label for="size">Size (px):</label>
<input align="left" id="size" type="number" value="150" min="50" max="500" step="50">
<label for="amount">Amount of Labels:</label>
<input align="left" id="amount" type="number" value="1" min="1" max="500" step="1">
<button id="genQRcode">Generate</button>
</div>
<div id="content" style="display: none;"></div>
</section>
<p id="demo" align="center"></p>
<script>
function myFunction() {
var x = document.getElementById("cpname").value;
document.getElementById("demo").innerHTML = x;
}
</script>
<script id="template-qr-code" type="text/html">
<p> <img id="qrcode" src="{{src}}" /></p>
<label for="checkpoint"> Checkpoint Name:</label>
<input id="cpname" type="text" value="">
<button onclick="myFunction()">Assign Name</button>
</script>
<script type="text/javascript">
window.addEventListener('load', function() {
var textarea = document.getElementById("textarea"),
content = document.getElementById("content"),
amount = document.getElementById("amount"),
qrTemplate = document.getElementById('template-qr-code');
function genQRcode() {
var data = encodeURIComponent(textarea.value),
size = document.getElementById("size").value,
chart = "http://chart.googleapis.com/chart?cht=qr&chs=" + size + "x" + size + "&choe=UTF-8&chld=L|0&chl=" + data;
if (data === "") {
alert("Please enter valid data!");
textarea.focus();
content.style.display = "none";
} else {
for (var i = 0; i < amount.value; i++) {
var qrSrc = qrTemplate.innerHTML;
qrSrc = qrSrc.replace(new RegExp('{{src}}', 'g'), chart);
qrSrc = qrSrc.replace(new RegExp('{{i}}', 'g'), i);
content.insertAdjacentHTML('beforeEnd', qrSrc);
}
content.style.display = "";
}
}
document.getElementById("genQRcode").addEventListener("click", genQRcode);
document.addEventListener("keydown", function(e) {
if (e.ctrlKey && e.keyCode == 13) {
genQRcode();
}
});
});
</script>
</body>
</html>
Your click function
function myFunction() {
var x = document.getElementById("cpname").value;
document.getElementById("demo").innerHTML = x;
}
is getting and setting an element by ID. That will only ever affect a single element on the page (usually the first one that the browser runs into with that specific id). You need to use a different selector / way of getting the label you want to change because you can't reuse ids.
Basically you need to make your label fields distinct so you can actually select them

Button to clear text and reset search input not working

Ok, so I have a filterable search form that returns certain images in a grid, which works great, it resets when I delete the text in the search input, but when I click the "Clear" button, which should do the same thing as deleting the text, it doesn't work. Here is the HTML and JQuery used:
<form id="live-search" action="" class="styled" method="post" style="margin: 2em 0;">
<div class="form-group">
<input type="text" class="form-control" id="filter" value="" style="width: 80%; float: left;" placeholder="Type to search"/>
<span id="filter-count"></span>
<input type="button" class="clear-btn" value="Clear" style="background: transparent; border: 2px solid #af2332; color: #af2332; padding: 5px 15px; border-radius: 3px; font-size: 18px; height: 34px;">
</div>
</form>
This is the JQuery for the clearing text:
jQuery(document).ready(function(){
jQuery("#filter").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = jQuery(this).val(), count = 0;
// Loop through the comment list
jQuery(".watcheroo").each(function(){
jQuery(this).removeClass('active');
// If the list item does not contain the text phrase fade it out
if (jQuery(this).text().search(new RegExp(filter, "i")) < 0) {
jQuery(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
jQuery(this).show();
count++;
}
});
// Update the count
var numberItems = count;
});
//clear button remove text
jQuery(".clear-btn").click( function() {
jQuery("#filter").value = "";
});
});
Any help would greatly be appreciated.
value is a property on a DOMElement, not a jQuery object. Use val('') instead:
jQuery(document).ready(function($) {
$("#filter").keyup(function() {
var filter = $(this).val(),
count = 0;
$(".watcheroo").each(function(){
var $watcheroo = $(this);
$watcheroo.removeClass('active');
if ($watcheroo.text().search(new RegExp(filter, "i")) < 0) {
$watcheroo.fadeOut();
} else {
$watcheroo.show();
count++;
}
});
var numberItems = count;
});
$(".clear-btn").click(function() {
$("#filter").val(''); // <-- note val() here
});
});
Note that I amended your code to alias the instance of jQuery passed in to the document.ready handler. This way you can still use the $ variable safely within the scope of that function.
As the accepted answer doesn't solve the problem.
Try input event instead of keyup
$("#filter").on("input", function() {.....
& then clear the filter input field on which event you want.
$(".clear-btn").on("click", function() {
$("#filter").val("").trigger("input");
});
Add this to your CSS:
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
<form>
<input type="search" name="search" placeholder="Search...">
</form>

Categories