I am a noob to programming, so I'd appreciate any advice from you more knowledgeable folks out there. I am working on a bit of javascript for a web page and I need the javascript to print to that current HTML page, preferably in the div tag I have set up for that purpose. Here's what I have so far:
<html>
<head>
<title>Tardy Reporting</title>
<script src="students.js" type="text/javascript">
</script>
</head>
<body>
<h1>Scan in Student ID</h1>
<form method="POST" name="idForm" onSubmit="getId(parseInt(document.idForm.studentId.value));">
<input type="text" name="studentId" id="studentId"/>
<input type="Submit" name="Submit" />
</form>
<div id="div1"></div>
<p>
</body>
</html>
and my JS file:
var studentNumberArray = [50011234, 50012345, 50013456];
var studentNameArray = ["Mike Simpson", "Greg Pollard", "Jason Vigil"];
var studentLastPeriodArray = ["George Washington", "Darth Vadar", "Obi Wan Kenobi"];
var tardyArray = [0, 0, 0];
function getId(studentId) {
for (i = 0; i < studentNumberArray.length; i++){
if(studentId === studentNumberArray[i]){
tardyArray[i] += tardyArray[i] + 1;
document.getElementById('div1').innerHTML='test';
}
}
}
Mind you, this is just the basic framework, so it's not nearly done yet, but the thing that is bugging me is that it'll go through the code correctly and print it out, but the result only lasts a fraction of a second on my browsers (chromium and firefox). Any help would be appreciated.
Here is an easier/better way to accomplish what you are trying to do
var students = {};
// Add students to object
students[50011234] = { 'id': '50011234', 'name':"Mike Simpson", 'lastPeriod':"George Washington", 'tardy':0 };
students[50012345] = { 'id': '50012345', 'name':"Greg Pollard", 'lastPeriod':"Darth Vadar", 'tardy':0 };
students[50013456] = { 'id': '50013456', 'name':"Jason Vigil", 'lastPeriod':"Obi Wan Kenobi", 'tardy':0 };
function getId(studentId) {
students[ studentId ].tardy += 1;
document.getElementById('div1').innerHTML='test';
}
Also, as pointed out below, you should change your button to not submit if that is not what you are intending to happen:
<form method="POST" name="idForm">
<input type="text" name="studentId" id="studentId"/>
<input type="button" onclick="getId(parseInt(document.idForm.studentId.value));" name="Mark Tardy" />
</form>
The reason why you see it only for a fraction of a second is that you are actually causing a submit. A submit is a full call back to the server which returns the page to its initial status.
To fix this simply make the function call on the onclick event of the button:
<html>
<head><title>Tardy Reporting</title>
<script src="students.js" type="text/javascript"> </script>
</head>
<body>
<h1>Scan in Student ID</h1>
<form method="POST" name="idForm" >
<input type="text" name="studentId" id="studentId" />
<input type="button" onclick="getId(parseInt(document.idForm.studentId.value));" value="submit" />
</form>
<div id="div1"></div>
<p>
</body>
</html>
What do you mean by "result"? It appears that you are setting the innerHTML of div1 to "test" over and over again.
Perhaps you mean to write
document.getElementById('div1').innerHTML += 'test';
Doing this is not efficient and it is preferable you concatenate on a string, or even better, join an array, before assigning the innerHTML.
but the result only lasts a fraction of a second on my browsers (chromium and firefox).
That is because you are submitting the page, so the page gets refreshed. You need to change the button type to button from submit. Also add a onclick to the button and call the js function getId
Forms are a special construct that allows communication with a server:
When a form is submitted, the form data is "POSTED" to a server via an HTTP request.
Typically, the browser displays the server's response as a new web page.
Forms use the action attribute to specify which server page should process the request
In your case, no action is specified, so the form POSTS to the current page, which is equivalent to refreshing the page. This means that all client-side (JavaScript) changes are wiped out, which is why you only see them for a split-second.
To achieve your desired result, change the input type from submit to button:
<input type="button" onclick=".." value="submit" />
Ideally, the student data exists in a database that is manipulated by code on a server. Your form would POST a request that returns an HTML page containing the desired data.
References
HTTP
Forms
Related
Simplified the code as much as possible. How are the button clicks counted?
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Example File 3</h1>
<form action="<?= url ?>" method="GET">
<input type="text" name="update" />
<input type="submit" name="Submit" /><br> <!-- count clicks -->
<span><?= update ?></span>
<span><?= count ?></span>
</form>
</body>
</html>
The Code.js file:
var clicks = 0;
function doGet(e) {
Logger.log(JSON.stringify(e));
var htmlOutput = HtmlService.createTemplateFromFile('ExampleFile3');
if (!e.parameter['update']) {
htmlOutput.update = '';
}
else {
htmlOutput.update = 'updated value is: ' + e.parameter['update'];
htmlOutput.count = 'count is: ' + clicks;
clicks++
}
htmlOutput.clicks = clicks;
htmlOutput.count = clicks;
htmlOutput.url = getUrl();
return htmlOutput.evaluate();
}
function getUrl() {
var url = ScriptApp.getService().getUrl();
return url;
}
the increment isn't increasing, that I see, and the output is squished together. Looking to count the number of form submissions.
Here is a sample code for creating an oversimplified web app. It shows one way to count button clicks using JavaScript.
The client-side code is added to the HtmlOutput object by using the HtmlService.HtmlOutput.append method.
The global variable is set in the client-side instead of the server-side. Please bear in mind that reloading the web app will reset the global variable.
In <form> uses the attribute onsubmit instead of the attributes action and method. This attribute calls a client-side JavaScript function that updates the client-side global variable and display it in <div>.
Please note the use of event.preventDefault(). This is required when submitting html forms in Google Apps Script web apps because the form is hosted in a special Google service that cannot be modified by the Google Apps Script web app developers.
function doGet(e) {
return HtmlService.createHtmlOutput()
.append(`
<form onsubmit="handleFormSubmit()">
<input type="text" name="something"><br>
<button type="submit">Submit</button>
</form>
<div>0</div>
<script>
var clicks = 0;
function handleFormSubmit(){
event.preventDefault();
document.querySelector('div').innerHTML = ++clicks;
}
</script>
`);
}
Notes:
The web browser console will show several warnings. You can ignore them
The web browser console will show the following error:
Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
at gas-hub.js:25:10
For the purpose of this oversimplified example, you can ignore it. To avoid this error, the HtmlOutput object should include a "full" HTML5 structure:
function doGet(e) {
return HtmlService.createHtmlOutput()
.append(`
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form onsubmit="handleFormSubmit()">
<input type="text" name="something"><br>
<button type="submit">Submit</button>
</form>
<div>0</div>
<script>
var clicks = 0;
function handleFormSubmit(){
event.preventDefault();
document.querySelector('div').innerHTML = ++clicks;
}
</script>
</body>
</html>
`)
.setTitle('Demo')
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
To send <form> values to the server side, as well for other type of values, without reloading the web app, use google.script.run to call a server side function as is explained in https://developers.google.com/apps-script/guides/html/communication.
You also can use google.script.run to call server side functions on client-side event like clicking button. A very simple way is by using a button (<button> or <input type="button"> with an onclick attribute).
<button onclick="google.script.run.myFunction();">Run</button>
Also it's possible to use it with <form>'s onsubmit attribute and buttons of type submit but you have to include event.preventDefault() to avoid the page redirection cause the form submit action.
Please bear in mind that the use of event attributes is discouraged. Instead set the function to be called on the event by using HtmlElement.addEventListener whenever be possible.
To store a value persistently, do not use server-side global variables, instead consider to use the Properties Service among other options (see the related questions).
Here is another example, now using the "full" HTML5 structure, the Properties Service to persistently keep the number of button clicks. Instead of using the attribute onsubmit it uses the <form>attributes action and method but also use <base> to set the elements target to `"_top". This is required to properly reload the web app when the form is submitted.
A hidden <input> is used to pass a value to control when the click counter should be increased, this way we prevent that following the link (without the clicked=yes url parameter) increase the counter. Please note that no JavaScript is included on the client-side (HtmlOutput).
function doGet(e) {
const props = PropertiesService.getScriptProperties();
const name = "clicks";
let clicks = Number(props.getProperty(name));
if (e && e.parameter && e.parameter.clicked === 'yes') {
props.setProperty(name, ++clicks);
}
return HtmlService.createHtmlOutput()
.append(`
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form action="${ScriptApp.getService().getUrl()}" method="GET">
<input type="hidden" name="clicked" value="yes">
<input type="text" name="something" value="default value"><br>
<button type="submit">Submit</button>
</form>
<div>${clicks}</div>
</body>
</html>
`)
.setTitle('Demo')
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
If you are on your way to create a production class web application, please be aware that the client-side code is "satinized" and there are some limitations about what can done compared to other platforms. Please study the references to learn the basics about this.
Related
How to define global variable in Google Apps Script
How do I know which button was clicked in the Google Apps script?
References
https://developers.google.com/apps-script/guides/web
https://developers.google.com/apps-script/guides/html
I am attempting to create a couple of web pages that will allow me to fill out a form on input.html and have the entered data appended to a different HTML file, index.html.
I have been searching for an answer for a couple of hours now and it might just drive me insane!
Here is some example code of what I'm trying to do:
HTML form input.hmtl:
<form>
<label>
Enter something:
<input type="text" id="userinput" required>
</label>
<input type="submit" id="submit" value="submitted">
</form>
Javascript to get entered data and pass to index.html:
var userInput = document.querySelector("#userinput");
var submit = document.querySelector("#submit");
function addToIndex()
{
// create new element on index.html
}
submit.addEventListener("click", addToIndex, false);
HTML output file index.html:
<div id="contentstart">
<!-- newly created element here -->
</div>
I have attempted using this solution, but Chrome's console gives me an error and tells me that newWindow is not a function. I just stumbled upon using the <iframe> element in a couple of answers but don't quite understand it yet (I'm a noob).
Thanks in advance!
The best option is to use a web server or a serverless implementation. Server code can be written in multiple languages. Some of the languages include PHP, NodeJS, and ASP.NET.
However, you can pass data using browser storage.
But, browser storage is not secure and can be wiped at any time by the user. If you are storing information such as passwords or data that should be visible to multiple users, you should use a web server and/or database.
You need to have a script on both pages. The page with the form will store/set the data. The index page will retrieve the data and use javascript to render more content.
function addToIndex()
{
localStorage.setItem('input', userInput .value)
}
The script for the index page would look something like this.
var data = localStorage.getItem('input');
if (input) {
document.querySelector('#contentstart').innerHTML = data;
}
I put together a simple demo here.
http://plnkr.co/edit/iAitGxtdsHwXowNg
For you to receive data from a form in a different file, you will need a server-side language like php.
So the form will have this structure
<form action="external_file.php" method="get">
<label>
Enter something:
<input type="text" id="userinput" name="user_input" required>
</label>
<input type="submit" id="submit" value="submitted">
</form>
Note the action="external_file.php and the name="user_input" attribute added to the input element.
Then the file: external_file.php might have the following structure to receive the content from the form
<?php
$input = $_GET["user_input"];
//do something with $input
echo 'The data you entered is: ' . $input;
?>
I showed you the way to start. The rest is up to you, you can do whatever you want to do. I hope you could help.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form id ="form">
<label>
Enter something:
<input type="text" id="userinput" required>
</label>
<input type="submit" id="submit" value="submitted">
</form>
<script>
let form = document.getElementById("form");
let userInput = document.getElementById("userinput");
form.addEventListener("submit", submitForm) //this function will work when the form is submit
function submitForm (e) {
e.preventDefault() // this event will prevent page refresh when form submit
let userInputValue = userInput.value; // userinput value
console.log(userInputValue);
moveToAnotherPage(userInputValue); //we send the value we get from userinput to use in another function.
}
function moveToAnotherPage (value) {
// Select the index2 html elements and add with innerhtml or something.
//to do this, you may need to save the userinput value you received to localStorage and pull it from it. I suggest you look into localStorage .And if you know php, you can use it.
}
</script>
</body>
</html>
I have a .js file with setCookie() and getCookie() functions which are working fine. I'm running into a problem when trying to use this same .js file with 2 different web pages. For example, one page's cookie sets name, room number, and beverage selection, while the other page's cookie sets name, address line 1, address line 2, etc...
Thus, I will need to account for differences in the 2 page's forms in the .js file. I thought that I could reference the particular form I'm addressing by its form name (they have different form names) but that isn't working:
if (document.getElementsByTagName("form") == document.getElementsByName("form1"))
{
document.cookie = 'Name = ' + userName; 'expires = ' + userExpires;
document.cookie = 'Room = ' + userPrt1; 'expires = ' + userExpires;
document.cookie = 'Drink = ' + userPrt2; 'expires = ' + userExpires;
}
Thus, my question is, when I have to add an if statement to handle code specific to one particular form (or one particular web page), how do I do this?
Thank you
EDIT: I'm not really sure this will be helpful, but since it was requested, here is the HTML:
<!doctype html>
<html lang="en">
<head>
<title>Javascript</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="mycss.css"/>
<script type="text/javascript" src="myjs.js"></script>
</head>
<body onLoad="javascript:getCookie();">
<header>
<img src="js.png" width="800" height="135"/>
</header>
<main>
<h2>JavaScript Cookie Test</h2>
<br><br>
<form name="form1" id="form1id" action="javascript:setCookie();">
Name: <input type="text" name="customer" id="customer" required /><br><br>
Room: <input type="text" name="roomNumber" id="roomNumber" required /><br><br><br>
What type of coffee would you like to order?<br><br> <!-- It seems radio input would be better here -->
<input type="checkbox" name="cbox" value="regular" />Regular<br>
<input type="checkbox" name="cbox" value="espresso" />Espresso<br>
<input type="checkbox" name="cbox" value="cappuccino" />Cappuccino<br>
<input type="checkbox" name="cbox" value="mocha" />Mocha<br>
<input type="checkbox" name="cbox" value="raspberry" />Raspberry<br><br>
<input type="submit" name="submit" id="submit" value="Submit" />
</form>
</main>
As I mentioned, everything works fine in terms of setting and getting the cookie, whether my JavaScript is in the HTML file or in a separate .js file. It's only when I try to add code in the .js file that references a specific form (or web page) that I do not succeed.
Should I be referencing the web page instead of the form? If so, how would I do this in an if statement? Thank you!
EDIT: I want to add a brief clarification in case it will be helpful. What I want to know is how to reference the form or web page calling a function in the .js file. If form1 or index1.html called the setCookie() function, I want to add an if code block. If form2 or index2.html called the setCookie() function, I want to add a different if code block. Thank you.
Have you tried giving each form an id and using getElementById() instead ? I think your error is coming from the fact that getElementsByTagName returns an array so you're trying to compare an array of elements to a single element
I'm not sure to understand your question, but in case I have you could just check if the form exists, by its id.
if (document.getElementById('form1') !== null)
{
// there is a form1
}
else if (document.getElementById('form2') !== null)
{
// there is a form2
}
for the first, getElementsByName() doesn't return single node, but a node collection, so if you want to access the first matching node, you have to use
document.getElementsByName("form1")[0]
For the second, you can simply use document.forms property where you have access to all forms on your page.
EDIT:
In document.forms you can access to form by index of its occurrence (document.forms[1] returns the second form on page) or you can use name attribute value (document.forms["form1"] returns form with name "form1").
Okay, I finally figured out an answer to this.
HTML:
<script type="text/javascript">var formName = "form1"</script>
<form name="form1" action="javascript:setCookie(formName);">
insert form code...
</form>
Then, in the .js file:
function setCookie(formName)
{
insert cookie code...
}
And the form name is passed to the JavaScript page, so I can use it to add cookie code that is specific to form1.
I was hoping to find a way to know which form called the JavaScript page, but I'm starting to think that's not possible, since the question has been posted for 5 days without a resolution. Fortunately, this resolves the issue just as easily as knowing which form called the JavaScript page.
I appreciate everyone's input.
Let me Clear what title means:
In my code for a validation purpose of one field dependent on field "t1" I need to auto submit my form once (Just Once). But my below code is submitting it infinite times and I know the reason why its happening.
I guess Reason is everytime the form submits again JS in header runs. Please help me avoid this. Following is my code:
<html>
<head>
<script>
window.onload = function()
{
var f = document.getElementById("CheckForm");
var temp = document.getElementById("CheckForm.t1");
if(f.name == "CheckForm")
{
var temp1 = document.getElementById("t1");
temp1.value = "Task";
}
document.CheckForm.submit();
}
</script>
</head>
<body>
<form name="CheckForm" id="CheckForm" method="Post">
<input type="text" id="t1" name="t1"/>
</form>
</body>
</html>
I tried stopping it using variable like flag and static variables like arguments.callee.count = ++arguments.callee.count || 1 and placing my CheckForm.submit() line in if clause. But nothing worked. Any advice or help is appreciable.
<html>
<head>
<script>
window.onload = function()
{
var f = document.getElementById("t1");
var temp = document.getElementById("CheckForm.t1");
if(f.name == "CheckForm")
{
var temp1 = document.getElementById("CheckForm.t1");
temp1.value = "Task";
}
if(window.location.search=="")document.CheckForm.submit();
}
</script>
</head>
<body>
<form name="CheckForm">
<input type="text" id="t1"/>
</form>
</body>
</html>
Surely your form is more complex than:
<form name="CheckForm">
<input type="text" id="t1">
</form>
That will not submit anything to the server since there are no successful controls (the only control doesn't have a name).
Since the form is just submitting to the same page, you can submit a hidden value like:
<form name="CheckForm">
<input type="text" id="t1">
<input type="hidden" name="hasBeenSubmitted" value="yes">
</form>
Now when the form submits the URL of the new page will include ...?hasBeenSubmitted=yes so you can look for that value in the URL, e.g.
if (/hasBeenSubmitted=yes/.test(window.location.search)) {
// this page loaded because the form was submitted
}
If it exists, don't submit the form again.
So since you are using a post method the easiest way's to handle this is to ubmitted to a new url , however you seem set on keeping the form submitted to the same url in which case is you are using php (or really any other language) you can check if the http request has a post attribute with a value t1
<?php
if(isset($_POST['t1']){
$your_text=$_POST['t1'];
/*do some string checking to make safe and the throw into your database or mdo whatever you please with data
if you wanted to include the ip address of the user you can get a basic and most likely client ip address like so
$ip_address= $_SERVER['REMOTE_ADDR'];
if you are handing a mulitpage form look into php session or similar tech ... cookies is kind of over kill for this scenario
then include a succes page as the form has been submitted
or you could end php with this tag ?> and then have your html and start again with <?
*/
include 'form_submitted.php';
}else{
//this would be the html page that you included in your question and can be handle in same ways as form submitted
include 'my_form.php'
}
?>
Ip address may not be best included as it would stop 2 user from filling out the form if they are in the same LAN for eg. 2 people in same office or same house (if your page is acttual on the worldwide web).
I would take a look at #RobG answer as it he is basically suggesting the same type of thing with a get instead of post
ANyways hope this helps
I had to take my working example here. For some reason, it does not work as easily as the initial example.
New Example
Suppose I want to see M5s every time the page loads. So how can I fire the same query for M5 every time the page load?
I copied the critical part here:
<body>
<div id="search">
<form onSubmit="makeRequest(1); return false;" style="margin: 2px; padding: 2px; font-size: 1.2em;">
<input id="searchinput" type="text" name="tags" size="20" value="">
<input id="searchbutton" type="button" onClick="makeRequest(1);" value="Create VideoWall"><br />
...
</form>
</div>
Response to the idea in MiffTheFox's and Tom's reply
So I added the command before the form above:
<body onload="document.getElementById('myform').submit();">
However, the wall stays black. It should be full of M5s.
Emerged problem to the initial Question: Why does it not work? Why does the wall stay black?
makeRequest asked by Tom
function makeRequest(page){
startrequest = 0;
for(i =1; i < 4; i++){
clearList('ul'+i);
var tags = encodeURI(document.getElementById('searchinput').value);
if(i == 1 || i == 2){
quantity = 45;
}
if(i == 3){
quantity = 36;
}
insertVideos('ul'+i,'search',tags,quantity,startrequest);
startrequest = startrequest + quantity;
}
}
Please, see the url at the top and press CTRL+U to see the code.
Well, thereĀ“s on load attribute inside the body element
<body onload = "javascript:doSubmit()">
...
</body>
<script>
function doSubmit(){
var form = document.getElementById("myform");
if (form !=null)
form.submit();
}
</script>
Also, you could add javascript at the end of your html page. This is not as portable as the first option
<html>
<body>
<form id="myForm" ...>
...
</form>
<script>
//this executes when the page finishes loading
var form = document.getElementById("myForm");
if (form!=null) form.submit();
</script>
</body>
</html>
First add an ID to the form, then add an onLoad handler that submits it.
<body onload="myForm.submit();">
<form id="myForm" name="input" action="form_action.asp" method="get">
...
Not sure what you're trying to accomplish, but you can certainly use jQuery to do
$(document).ready( function() {
$("#submitButton").click();
});
The problem is ensuring that this only happens the first time the document is submitted; you will need to keep track of that on the server-side and remove the submission code after the first time.
A better approach is probably to compose your HTML on the server side so that whatever initial state you want to display is displayed. Many web applications have a form to submit a query of some kind (say, a search) but start with some initial sample result below the form. This is just created on the server side before loading, not by "pre-submitting".