I am making a program to get user input from HTML forms and compile them into an object for each user. So, I have an HTML form, I make a constructor, then I set up a click event to make the object, then I put it in the variable, and then I am trying to put that variable in an array of objects, before finally using a for loop to get all of the information from each object in this array. However, I am having trouble with that last part (or at least I think). Every time I run the code, the console log does display the message, but it is coming up with undefined rather than the user input. Can someone help please?
function user(firstName, lastName, address) {
user.firstName = firstName;
user.lastName = lastName;
user.address = address;
}
var users = [];
document.addEventListener("submit", function(addUser) {
event.preventDefault();
var newUser = new user(
document.getElementById("userFName").value,
document.getElementById("userLName").value,
document.getElementById("userAdd").value
);
users.push(newUser);
for (let i = 0; i < users.length; i++) {
console.log("User" + (i + 1) + "'s first name is " + users[i].firstName + ", their last name is " + users[i].lastName + ", and their address is " + users[i].address);
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WWW</title>
<style>
</style>
</head>
<body>
<form>
<input id="userFName" placeholder="First Name">
<input id="userLName" placeholder="Last Name">
<input id="userAdd" placeholder="Address">
<button type="submit">Submit</button>
</form>
</body>
</html>
By assigning to user, you're assigning to a property of the constructor, not a property of the instance. new User will mutate the constructor and return an empty object whose internal prototype is user.prototype.
Assign to this instead inside the constructor, to change the instance that gets returned.
function user(firstName, lastName, address) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
var users = [];
document.addEventListener("submit", function(addUser) {
event.preventDefault();
var newUser = new user(
document.getElementById("userFName").value,
document.getElementById("userLName").value,
document.getElementById("userAdd").value
);
users.push(newUser);
for (let i = 0; i < users.length; i++) {
console.log("User" + (i + 1) + "'s first name is " + users[i].firstName + ", their last name is " + users[i].lastName + ", and their address is " + users[i].address);
}
});
<form>
<input id="userFName" placeholder="First Name">
<input id="userLName" placeholder="Last Name">
<input id="userAdd" placeholder="Address">
<button type="submit">Submit</button>
</form>
Or use a plain object instead of a constructor.
const user = (firstName, lastName, address) => ({
firstName, lastName, address
});
const users = [];
document.addEventListener("submit", function(addUser) {
event.preventDefault();
var newUser = user(
document.getElementById("userFName").value,
document.getElementById("userLName").value,
document.getElementById("userAdd").value
);
users.push(newUser);
for (let i = 0; i < users.length; i++) {
console.log("User" + (i + 1) + "'s first name is " + users[i].firstName + ", their last name is " + users[i].lastName + ", and their address is " + users[i].address);
}
});
<form>
<input id="userFName" placeholder="First Name">
<input id="userLName" placeholder="Last Name">
<input id="userAdd" placeholder="Address">
<button type="submit">Submit</button>
</form>
make your life easier, use names in your forms!
const
myForm = document.querySelector('#my-form')
, users = []
;
myForm.onsubmit = e =>
{
e.preventDefault()
users.push({ firstName: myForm.userFName.value
, lastName : myForm.userLName.value
, address : myForm.userAdd.value
})
console.clear()
users.forEach( (user,i) => console.log(i,JSON.stringify(user)) )
myForm.reset() // clear inputs
myForm.userFName.focus()
}
<form id="my-form">
<input name="userFName" placeholder="First Name" required >
<input name="userLName" placeholder="Last Name" required >
<input name="userAdd" placeholder="Address" required >
<button type="submit">Submit</button>
</form>
Related
I have managed to get data registering to my localStorage as arrays, however I have three queries:
Why are there double square brackets around my array?
How do I change the name field to the respective html ID?
Data returning as undefined when I try to retrieve it from the localStorage?
The output I am looking for in my localStorage is:
bookings: [
[0]{fname: "John", lname: "Smith" }
[1]{fname: "Jane", lname: "Doe" }
]
But I am currently getting:
bookings: [
[0][{name: "fname" value: "John"},{name: "lname": value: "Smith" }]
[1][{name: "fname" value: "Jane"},{name: "lname": value: "Doe" }]
]
I understand how to change the name value when items are hardcoded but I am initialising an empty array in my JS and not sure where the error is, I have tried assigning a value to the array [0] but then it doesn't register anything. I have also tried the data.flat() method which does nothing.
The issue is my next step is to amend and delete items so I need to try and understand the structure. Currently I am getting undefined when I try to get data from storage, I have provided my remove function (currently to show) below, I know it is wrong but I think the issue is to do with how I am storing the data. Sorry I have asked so many questions on this but I am new to JS and still learning. I am struggling with searches as there are so many variations of Javascript and getting a lot of answers relating to C# or Python which isn't helping.
Here is my code:
//var bookings = [];
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
//bookings = JSON.parse(localStorage.getItem("bookings")) || [];
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBooking = $("#regForm").serializeArray();
bookings.push(newBooking)
var json = JSON.stringify(bookings);
const newData = bookings.flat();
window.localStorage.setItem("bookings", json);
});
$("#remove").click(function () {
var strBookings;
var i;
strBookings = localStorage.getItem("bookings");
//document.write("<p>" + strBookings + "</p>");
bookings = JSON.parse(strBookings);
for (i = 0; i < strBookings.length; i++) {
document.write("<p>" + strBookings[i].value + "</p>");
}
//localStorage.removeItem('bookings');
});
Form
<form id="regForm" name="regForm" class="col-sm-6">
<div class="row">
<input type="text" id="fname" placeholder="First Name" name="fname" required>
<input type="text" id="lname" placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
Show
//var bookings = [];
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
//bookings = JSON.parse(localStorage.getItem("bookings")) || [];
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBooking = $("#regForm").serializeArray();
bookings.push(newBooking)
var json = JSON.stringify(bookings);
const newData = bookings.flat();
window.localStorage.setItem("bookings", json);
});
$("#remove").click(function () {
var strBookings;
var i;
strBookings = localStorage.getItem("bookings");
//document.write("<p>" + strBookings + "</p>");
bookings = JSON.parse(strBookings);
for (i = 0; i < strBookings.length; i++) {
document.write("<p>" + strBookings[i].value + "</p>");
}
//localStorage.removeItem('bookings');
});
<form id="regForm" name="regForm" class="col-sm-6">
<div class="row">
<input type="text" id="fname" placeholder="First Name" name="fname" required>
<input type="text" id="lname" placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
<button id="remove" value="Remove">Show</button>
I tried to make a function that receive data from user and combine such data either by concatenation in case of string or by getting the sum as a result if the entered data was integer.
My main problem is that I don't know what what condition in if statement I use to JavaScript act according to data entered by user.
That's my last invented code to solve such problem
function GetFullName() {
var first = document.getElementById('FirstName').value;
var last = document.getElementById('LastName').value;
if (first == "string" || last == "string") {
document.getElementById('FullName').value = first + " " + last;
} else {
var first = parseInt(document.getElementById('FirstName').value);
var last = parseInt(document.getElementById('LastName').value);
document.getElementById('FullName').value = first + last;
}
document.getElementById('FirstName').focus();
}
<form>
First Name <input type="text" id="FirstName" />
Last Name <input type="text" id="LastName" />
<input type="button" value="submit" onclick="GetFullName()" />
<input type="reset" value="reset" />
<br />
Full Name <input type="text" id="FullName" />
</form>
when you get an element's value it will always be a string,
you can check of a variables type by typeof first
for your specific problem if you want to check if the user inputted integers then you will have to use isNaN
if(isNaN("123")) {
} else {
//this executes
}
All in all the new code would be:
if (isNaN(first) || isNaN(last)) {
document.getElementById('FullName').value = first + " " + last;
} else {
document.getElementById('FullName').value = parseInt(first) + parseInt(last);
}
I am trying to pass data from a form into a Google Apps Script but when I press submit I am greeted by I blank screen.
Form:
<div id="nameDiv">
<form action="https://script.google.com/a/umbc.edu/macros/s/AKfycbztum1ImJZeXXYt0fFhwOAMUsB5zCsJQohrum4W7qiH/dev">
<label for="fname">First Name</label>
<input type="text" id="fname" name="firstname">
<label for="lname">Last Name</label>
<input type="text" id="lname" name="lastname" >
<input type="submit" value="Submit" onclick="google.script.run.nameSearch()">
</form>
</div>
Script:
function nameSearch(){
try {
var firstName = document.getElementById("fname").value
var lastName = document.getElementById("lname").value
var inputSheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1z3j7wxMLsXilyKDIH7XnE7VNQqF66fIH4B-mmuWwCJ8/edit#gid=1235654559");
var inputData = inputSheet.getDataRange().getValues();
for (var i = 1; i < inputData.length; i++) {
if (inputData[i][10] == firstName && inputData[i][11] == lastName) {
var result = inputData[i][14] + ": " + inputData[i][15]
}
}
document.getElementById('nameDiv').innerHTML =
"<center>Last Name:" + lastName + "</center>" +
"</br><center>First Name:" + firstName + "</center>"
} catch(e) {
alert(e)
}
}
I am trying to pass this data to the script so that it can use it to search a google sheet so I cannot just place the script in the html as a client side script. Any thought?
All the HTML-related methods (getElementById, innerHTML, etc.) should be in client-side script, and Apps Script methods should be in the server-side.
If I understand you correctly, you want to do the following:
When this form gets submitted, look for the row whose columns K and L match the inputted fields (indexes 10 and 11 from inputData array).
For this row, return data from columns O and P (indexes 14 and 15 from inputData array).
Write this returned data to the HTML.
If all this is correct, then you could do this:
Add an onclick event in the submit input that will fire a client-side function (a function that is declared inside the tags in the HTML). There is no need to use a for this. The HTML body could be something like this:
<div id="nameDiv">
<label for="fname">First Name</label>
<input type="text" id="fname" name="firstname">
<label for="lname">Last Name</label>
<input type="text" id="lname" name="lastname" >
<input type="submit" value="Submit" onclick="clientNameSearch()">
</div>
From this client-side function called clientNameSearch(), retrieve the values from fname and lname, and use these as parameters when you call a server-side function called nameSearch):
function clientNameSearch() {
var firstName = document.getElementById("fname").value;
var lastName = document.getElementById("lname").value;
google.script.run.withSuccessHandler(onSuccess).nameSearch(firstName, lastName);
}
This server-side function iterates through all rows with content in the spreadsheet, and returns the result for the first row whose columns K and L match the inputted data:
function nameSearch(firstName, lastName){
try {
var inputSheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1z3j7wxMLsXilyKDIH7XnE7VNQqF66fIH4B-mmuWwCJ8/edit#gid=1235654559");
var inputData = inputSheet.getDataRange().getValues();
for (var i = 1; i < inputData.length; i++) {
if (inputData[i][10] == firstName && inputData[i][11] == lastName) {
var result = inputData[i][14] + ": " + inputData[i][15];
return result;
}
}
} catch(e) {
alert(e)
}
}
This result is then passed as a parameter to a client-side function called onSuccess via a success handler. This is necessary since server-side functions called by google.script.run don't return anything directly, as specified here. Then onSuccess writes the result to the HTML:
function onSuccess(result) {
document.getElementById('nameDiv').innerHTML = "<div>" + result + "</div>";
}
Full code:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="nameDiv">
<label for="fname">First Name</label>
<input type="text" id="fname" name="firstname">
<label for="lname">Last Name</label>
<input type="text" id="lname" name="lastname" >
<input type="submit" value="Submit" onclick="clientNameSearch()">
</div>
</body>
<script>
function clientNameSearch() {
var firstName = document.getElementById("fname").value;
var lastName = document.getElementById("lname").value;
google.script.run.withSuccessHandler(onSuccess).nameSearch(firstName, lastName);
}
function onSuccess(result) {
document.getElementById('nameDiv').innerHTML = "<div>" + result + "</div>";
}
</script>
</html>
And the Code.gs would be like:
function nameSearch(firstName, lastName){
try {
var inputSheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1z3j7wxMLsXilyKDIH7XnE7VNQqF66fIH4B-mmuWwCJ8/edit#gid=1235654559");
var inputData = inputSheet.getDataRange().getValues();
for (var i = 1; i < inputData.length; i++) {
if (inputData[i][10] == firstName && inputData[i][11] == lastName) {
var result = inputData[i][14] + ": " + inputData[i][15];
return result;
}
}
} catch(e) {
alert(e)
}
}
function doGet(e) {
return HtmlService.createHtmlOutputFromFile("your-html-name");
}
I'm not sure you want to write the result to the HTML, but in any case, at this point it shouldn't be difficult to modify this so that it writes exactly what you want and where you want.
Reference:
google.script.run.myFunction(...) (any server-side function)
withSuccessHandler(function)
I hope this is of any help.
Try this:
Launch the dialog fill the text boxes and click submit. The view logs and see the next dialog.
function launchADialog() {
var html='<form><br /><input type="text" name="Name" /> Name: <br /><input type="text" name="Age" /> Age: <br />';
html+='<select name="Children" ><option value="0">None</option><option value="1">One</option><option value="2">Two</option></select> Children:<br />';
html+='<input type="button" value="Submit" onClick="google.script.run.processForm(this.parentNode);" /></form>';
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showModelessDialog(userInterface, "The Form");
}
function processForm(form) {
Logger.log(JSON.stringify(form));
var s=Utilities.formatString('<br />Name: %s <br />Age:%s <br />Number Of Children: %s', form.Name, form.Age, form.Children);
s+='<br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(s);
SpreadsheetApp.getUi().showModelessDialog(userInterface, "Form Data")
}
I've just started learning JS and I'm trying to do some basic projects to cement what I've learned from reading and courses and tutorials and whatnot. I'm trying to make a contact list which takes 4 inputs: first name, last name, email and phone number. I wrote this part already and passed the arguments into an object within an array. What I can't figure out is how to display the contact object. I want to try and print each property into a list item within an unordered list but I'm stuck here, either because I don't know enough about DOM manipulation or just because I'm not looking in the right direction
//this passes the text input as an object to the list array
var contactList = {
list: [],
addNew: function() {
this.list.push({
firstName: document.getElementById('firstname').value,
lastName: document.getElementById('lastname').value,
email: document.getElementById('emailAdd').value,
phoneNumber: document.getElementById('phoneNumber').value
});
},
};
// this runs the addNew() function and clears the input fields afterwards
var handlers = {
addContact: function() {
contactList.addNew();
document.getElementById('firstname').value = '';
document.getElementById('lastname').value = '';
document.getElementById('emailAdd').value = '';
document.getElementById('phoneNumber').value = '';
// view.displayContact();
},
};
//this is where i'm trying to display the contacts array
var view = {
displayContact: function() {
var contacts = document.getElementById('contactul');
for (var i = 0; i < contactList.list.length; i++) {
var li = document.createElement('li');
contacts.appendChild(li);
li.innerHTML += contactList.list[i];
};
},
};
<form>
First name:<br>
<input id="firstname" type="text" name="firstname">
<br> Last name:<br>
<input id="lastname" type="text" name="lastname">
<br> Email Address:<br>
<input id="emailAdd" type="text">
<br> Phone number:<br>
<input id="phoneNumber" type="text">
<br>
</form>
<button onclick='handlers.addContact()'>Submit</button>
<div id='displayContacts'>
<ul id='contactul'>
</ul>
</div>
This is the desired result. I just can't figure out how to write it.
Well, you're close. The problem you have here is that when you go to display your items, you have to get the values for each individual element (first name, last name, etc). You can do that through another loop, or just hard-code each one since there are only 4. Here is an example:
//this passes the text input as an object to the list array
var contactList = {
list: [],
addNew: function() {
this.list.push({
firstName: document.getElementById('firstname').value,
lastName: document.getElementById('lastname').value,
email: document.getElementById('emailAdd').value,
phoneNumber: document.getElementById('phoneNumber').value
});
},
};
// this runs the addNew() function and clears the input fields afterwards
var handlers = {
addContact: function() {
contactList.addNew();
document.getElementById('firstname').value = '';
document.getElementById('lastname').value = '';
document.getElementById('emailAdd').value = '';
document.getElementById('phoneNumber').value = '';
view.displayContact();
},
};
//this is where i'm trying to display the contacts array
var view = {
displayContact: function() {
var contacts = document.getElementById('contactul');
while(contacts.firstChild ){
contacts.removeChild(contacts.firstChild );
}
for (var i = 0; i < contactList.list.length; i++) {
var liForFirstName = document.createElement('li');
contacts.appendChild(liForFirstName);
liForFirstName.innerHTML += "First Name: " + contactList.list[i].firstName;
var liForLastName = document.createElement('li');
contacts.appendChild(liForLastName);
liForLastName.innerHTML += "Last Name: " + contactList.list[i].lastName;
var liForEmail = document.createElement('li');
contacts.appendChild(liForEmail);
liForEmail.innerHTML += "Email: " + contactList.list[i].email;
var liForPhoneNumber = document.createElement('li');
contacts.appendChild(liForPhoneNumber);
liForPhoneNumber.innerHTML += "Phone Number: " + contactList.list[i].phoneNumber;
};
},
};
<form>
First name:<br>
<input id="firstname" type="text" name="firstname">
<br> Last name:<br>
<input id="lastname" type="text" name="lastname">
<br> Email Address:<br>
<input id="emailAdd" type="text">
<br> Phone number:<br>
<input id="phoneNumber" type="text">
<br>
</form>
<button onclick='handlers.addContact()'>Submit</button>
<div id='displayContacts'>
<ul id='contactul'>
</ul>
</div>
I need to display the answer from the form in a story. The story must be displayed below the form only after the form is successfully submitted (not an alert), and with the form remaining on the page (not a new page). I am able to insert the form values into the story, but need help with displaying the story after form is submitted. I cannot use anything but html and javascript. I think this can be done with innerHTML.
<head><title>Questions</title>
<script type = "text/javascript" src="quiz1.js">
</script>
</head><body>
<h1>Tell Me About Yourself</h1>
<form name = "the_form" action = "" method = "post"
onSubmit = "var the_result = checkMandatory(); return the_result;">
Full Name:<input type = "text" name = "name" id = "name" /><br/>
Favourite Animal:<input type = "text" name = "animal" id = "animal"><br/>
Favourite Food:<input type = "text" name = "favFood" id = "favFood"><br/>
Favourite Destination:<input type = "text" name = "destination" id = "desitnation"><br/>
Least Favourite Food:<input type = "text" name = "leastFav" id = "leastFav"><br/>
Happiest Moment:<input type = "text" name = "moment" id = "moment"><br/>
Adjective that describes you:<input type = "text" name = "adjective" id = "adjective"><br/>
<br>
<input type="button" value="Submit" onClick = "checkMandatory(); return false;"/><br />
<br />
</form>
<div id="storyDiv"></div>
</body>
</html>
function checkMandatory()
{
// check the text field
// make a var for each question to access easier eg "favMeal"
var name = window.document.the_form.name.value;
//! means 'not'... flips around the if
if (!(name.indexOf(" ") > 0))
{
alert("You must give your full name.");
//return false stops the program
return false;
} else {
//firstName checks all character from 0 to whenever (space) occurs and strips it
var firstName = name.substring(0,name.indexOf(" "));
var name = window.document.the_form.name.value;
var animal = window.document.the_form.animal.value;
var favFood = window.document.the_form.favFood.value;
var destination = window.document.the_form.destination.value;
var leastFav = window.document.the_form.leastFav.value;
var moment = window.document.the_form.moment.value;
var adjective = window.document.the_form.adjective.value;
//alert("first name is " + firstName);
//use alert firstName to test the firstName function
document.write("The young person's name was "+firstName+". "+firstName+" loved to ride
"+animal+
" almost every day. "+firstName+"'s second happiest moment, only next to "+moment+", was in
"+destination+", where "+favFood+
" was served for breakfast, lunch and dinner. It was only when "+firstName+" was told that
"+favFood+
" is actually made from "+animal+", that it instantly became "+firstName+"'s least
favourite food, even worse than "+leastFav+
", and that made "+firstName+" feel very "+adjective+" indeed.")
//document.getElementById('storyDiv').innerHTML = document.getElementById('name').value;
//document.getElementById(‘storyDiv’).innerHTML="The boy's name was "+firstName;
//document.write(‘storyDiv’).innerHTML="The boy's name was " + firstName;
}
}
You can achieve this by posting your form using ajax.
Don't call writethetext(); in your submit button
I'll use jQuery in my solution:
$(function() {
$("form").on("submit", function(e) {
var data = JSON.stringify($("form").serializeArray());
e.preventDefault();
$.post("yourserver/path/", data, function(result) {
writethetext(result);
});
});
});
function checkMandatory() {
// check the text field
// make a var for each question to access easier eg "favMeal"
var name = window.document.the_form.name.value;
//! means 'not'... flips around the if
if (!(name.indexOf(" ") > 0)) {
alert("You must give your full name.");
//return false stops the program
return false;
} else {
//firstName checks all character from 0 to whenever (space) occurs and strips it
var firstName = name.substring(0, name.indexOf(" "));
//alert("first name is " + firstName);
//use alert firstName to test the firstName function
}
}
function writethetext() {
document.getElementById(‘storyDiv’).innerHTML =
("There once was a boy named" + name;)
var firstName = name.substring(0, name.indexOf(" "));
var name = window.document.the_form.name.value;
var animal = window.document.the_form.animal.value;
var favFood = window.document.the_form.favFood.value;
var destination = window.document.the_form.destination.value;
var leastFav = window.document.the_form.leastFav.value;
var moment = window.document.the_form.moment.value;
var adjective = window.document.the_form.adjective.value;
}
function writethetext(text) {
document.getElementById(‘storyDiv’).innerHTML = text;
}
}
<html>
<head>
<title>Questions</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="quiz1.js">
</script>
</head>
<body>
<h1>Tell Me About Yourself</h1>
<form name="the_form" action="" method="post" onSubmit="var the_result = checkMandatory(); return the_result;">
Full Name:
<input type="text" name="name" id="name" />
<br/>Favourite Animal:
<input type="text" name="animal" id="animal">
<br/>Favourite Food:
<input type="text" name="favFood" id="favFood">
<br/>Favourite Destination:
<input type="text" name="destination" id="desitnation">
<br/>Least Favourite Food:
<input type="text" name="leastFav" id="leastFav">
<br/>Happiest Moment:
<input type="text" name="moment" id="moment">
<br/>Adjective that describes you:
<input type="text" name="adjective" id="adjective">
<br/>
<br>
<input type="button" value="Submit" onClick="checkMandatory();
return false;" />
<br />
<br />
</form>
<div id="storyDiv"></div>
</body>
</html>