I'm building a custom "Google Forms"-form with a file upload function.
The form uses a custom "Thankyou"-page (see 1st line: iframe).
I've found a file upload script that needs to run in the Google Script environment and it will upload files to my Google Drive.
Now I need to combine this upload script with my custom Google Form.
But I don't know exactly how to achieve this because there actions that need to be combined and the file upload has to be completed first before going to the "Thank you" page.
I've tried to combine it which looks like the code below.
The form:
<iframe name="hidden_iframe" id="hidden_iframe" style="display:none;" onload="if(submitted) { picUploadJs(myForm); }"></iframe>
<form id="myForm" action="https://docs.google.com/forms/d/e/xxx/formResponse" target="hidden_iframe" onsubmit="submitted=true;">
<input placeholder="1234" name="entry.1234" id="user" type="text">
<label for="user">User:</label>
<input name="picToLoad" type="file" />
<div id="status" style="display: none">
Uploading. Please wait...
</div
<button type="submit" name="action">Send</button>
</form>
The upload script:
<script>
function picUploadJs(frmData) {
document.getElementById('status').style.display = 'inline';
google.script.run
.withSuccessHandler(updateOutput)
.processForm(frmData)
};
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
This now results in:
Form input data is submitted, upload status text appears but nothing happens: "Uploading. Please wait...".
The result should be:
Form input data submit, upload file to drive and redirect to the thankyou page.
EDIT:
Google Script code
function doGet(e) {
return HtmlService.createTemplateFromFile('test')
.evaluate() // evaluate MUST come before setting the Sandbox mode
.setTitle('Name To Appear in Browser Tab')
//.setSandboxMode();//Defaults to IFRAME which is now the only mode available
}
function processForm(theForm) {
var fileBlob = theForm.picToLoad;
Logger.log("fileBlob Name: " + fileBlob.getName())
Logger.log("fileBlob type: " + fileBlob.getContentType())
Logger.log('fileBlob: ' + fileBlob);
var fldrSssn = DriveApp.getFolderById('xxxx');
fldrSssn.createFile(fileBlob);
return true;
}
When you click "Send" button,
Google Form works fine.
document.getElementById('status').style.display = 'inline' works.
Function of processForm(frmData) at Google Apps Script doesn't work.
Function of updateOutput() at Javascript doesn't work.
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
Modification points:
In this modification, the file was retrieved using onclick event, while the script for submitting to Google Form is not modified.
The retrieved file is converted to base64 and sent to Google Apps Script.
Modified script:
HTML:
<form id="myForm" action="https://docs.google.com/forms/d/e/xxx/formResponse" target="hidden_iframe" onsubmit="submitted=true;">
<input placeholder="1234" name="entry.1234" id="user" type="text">
<label for="user">User:</label>
<input name="picToLoad" type="file" id="sampleFile" /> <!-- Modified -->
<div id="status" style="display: none">
Uploading. Please wait...
</div>
<button type="submit" name="action" id="sampleId" >Send</button> <!-- Modified -->
</form>
Javascript:
<script>
// Below script was added.
document.getElementById("sampleId").onclick = function(e) {
e.stopPropagation();
e.preventDefault();
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
picUploadJs(obj);
}
f.readAsDataURL(file);
};
function picUploadJs(frmData) {
document.getElementById('status').style.display = 'inline';
google.script.run.withSuccessHandler(updateOutput).processForm(frmData)
};
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
Google Apps Script:
function processForm(theForm) {
var fileBlob = Utilities.newBlob(Utilities.base64Decode(theForm.data), theForm.mimeType, theForm.fileName);
var fldrSssn = DriveApp.getFolderById('xxxx');
fldrSssn.createFile(fileBlob);
return true;
}
Note:
When the file is selected and click a "Send" button, the file is send to Google Apps Script and is created as a file on Google Drive, while Google Form is submitted. Then updateOutput() at Javascript side is run.
In this modified script, The blob is used. So the maximum size of a file for uploading is 50 MB. Please be careful this.
Edit 1:
At your comment, it was found that When I remove the id=sampleId from the submit button, the Google Form data is submitted correctly. Using this, please test the following modification.
In this modification, id="sampleId" was removed and the event is triggered using the name of element.
HTML:
<form id="myForm" target="hidden_iframe" onsubmit="submitted=true;">
<input placeholder="1234" name="entry.1234" id="user" type="text">
<label for="user">User:</label>
<input name="picToLoad" type="file" id="sampleFile" />
<div id="status" style="display: none">
Uploading. Please wait...
</div>
<button type="submit" name="action">Send</button> <!-- Modified -->
</form>
Javascript:
var button = document.getElementsByName('action')[0]; // Modified
button.onclick = function(e) { // Modified
e.stopPropagation();
e.preventDefault();
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
picUploadJs(obj);
}
f.readAsDataURL(file);
};
Edit 2:
I updated HTML and Javascript. Please confirm it. Google Apps Script is not modified.
HTML:
<iframe name="hidden_iframe" id="hidden_iframe" style="display:none;" onload="if(submitted) { picUploadJs(myForm); }"></iframe>
<form id="myForm" action="https://docs.google.com/forms/d/e/xxx/formResponse" target="hidden_iframe" onsubmit="submitted=true;">
<input placeholder="1234" name="entry.1234" id="user" type="text">
<label for="user">User:</label>
<input name="picToLoad" type="file" id="sampleFile" /> <!-- Modified -->
<div id="status" style="display: none">
Uploading. Please wait...
</div>
<button type="submit" name="action">Send</button>
</form>
Javascript:
<script>
// This function was modified.
function picUploadJs(myForm) {
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
document.getElementById('status').style.display = 'inline';
google.script.run.withSuccessHandler(updateOutput).processForm(obj);
}
f.readAsDataURL(file);
}
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
Related
I made PHP script to preview an image before upload it, which is simple and easy to read. the first part is to displays the image then to upload it after pressing Submit button.
I have an issue with uploading the image, it doesn't upload.
<?php
if (!empty($_POST["uploadForm"])) {
if (is_uploaded_file($_FILES['userImage']['tmp_name'])) {
$targetPath = "uploads/".$_FILES['userImage']['name'];
if (move_uploaded_file($_FILES['userImage']['tmp_name'], $targetPath)) {
$uploadedImagePath = $targetPath;
}
}
}
?>
<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="userImage" />
<script>
var loadFile = function(event) {
var output = document.getElementById('userImage');
output.src = URL.createObjectURL(event.target.files[0]);
output.onload = function() {URL.revokeObjectURL(output.src) } // free memory
};
</script>
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
<input type="submit" name="upload" value="Submit" class="btnSubmit">
</form>
You have several logical errors in your PHP Code as well as HTML.
When checking for form submission you have to check if "upload" (name of submit button) is in the $_POST.
The File Upload Input should be inside <form> tag.
Set a name for File Upload field, I have set it to "userImageUpload", so you can access it from $_FILES in PHP.
Here is the final Code:
<?php
if (!empty($_POST["upload"])) {
if (is_uploaded_file($_FILES['userImageUpload']['tmp_name'])) {
$targetPath = "uploads/" . $_FILES['userImageUpload']['name'];
if (move_uploaded_file($_FILES['userImageUpload']['tmp_name'], $targetPath)) {
$uploadedImagePath = $targetPath;
}
}
}
?>
<img id="userImage" />
<script>
var loadFile = function(event) {
var output = document.getElementById('userImage');
output.src = URL.createObjectURL(event.target.files[0]);
output.onload = function() {
URL.revokeObjectURL(output.src)
} // free memory
};
</script>
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
<input type="file" accept="image/*" onchange="loadFile(event)" name="userImageUpload">
<input type="submit" name="upload" value="Submit" class="btnSubmit">
</form>
Note: Please make sure that "upload" folder is already there and permissions are correct too.
Youve placed the input out of the form, but it should be in it:
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
<input type="file" accept="image/*" onchange="loadFile(event)">
<input type="submit" name="upload" value="Submit" class="btnSubmit">
</form>
I am new to google scripting. I have followed some tutorials online and created a user form which has 4 input:
company name, qty, agent and comment. The only goal here is to copy data from user form to spread sheet. I have written the following html and functions but data does not get populated after button add is clicked.
I know the addRowData function is working when correct input gets to it. So either I am not population rowData correctly or EventListener does not work correctly. Can anybody please help me find where the issue is?
function addNewRow(rowData) {
const currentDate=new Date();
const ss=SpreadsheetApp.getActiveSpreadsheet();
const ws=ss.getSheetByName("Results");
ws.appendRow([currentDate, rowData.companyName,rowData.qty,rowData.agentName,rowData.commentText]);
return true;
}
<div class="container">
<div>
<div class="form-group">
<label for="company-name">Company</label>
<input type="text" class="form-control" id="company-name">
</div>
<div class="form-group">
<label for="number-boxes">Number of Boxes</label>
<input type="Text" class="form-control" id="number-boxes">
</div>
<div class="form-group">
<label for="agent-name">Agent</label>
<input type="text" class="form-control" id="agent-name">
</div>
<div class="form-group">
<label for="comment-text">Comment</label>
<input type="Text" class="form-control" id="comment-text">
</div>
<button class="btn btn-primary" id="mainButton">Add</button>
</div>
</div>
<script>
function afterButtonClicked(){
var companyName = getElementById("company-name");
var qty = getElementById("number-boxes");
var agentName = getElementById("agent-name");
var commentText = getElementById("comment-text");
var rowData={companyName: companyName.value,qty: qty.value,agentName: agentName.value,commentText: commentText.value};
google.script.run.withSuccessHandler(afterSubmit).addNewRow(rowData);
}
function afterSubmit(e){
var qty = getElementById("number-boxes");
qty.value="";
}
document.getElementById("mainButton").addEventListener("click",afterButtonClicked());
</script>
</body>
I would like to propose the following modification.
Modification points:
At document.getElementById("mainButton").addEventListener("click",afterButtonClicked());, the function is run by () of afterButtonClicked() at the load of HTML. In this case, please remove ().
About getElementById("###"), in this case, please add document like document.getElementById("###").
When above points are reflected to your script, it becomes as follows. I think that your Google Apps Script works.
Modified script:
In this case, please modify your Javascript as follows.
<script>
function afterButtonClicked(){
var companyName = document.getElementById("company-name");
var qty = document.getElementById("number-boxes");
var agentName = document.getElementById("agent-name");
var commentText = document.getElementById("comment-text");
var rowData={companyName: companyName.value,qty: qty.value,agentName: agentName.value,commentText: commentText.value};
google.script.run.withSuccessHandler(afterSubmit).addNewRow(rowData);
}
function afterSubmit(e){
var qty = document.getElementById("number-boxes");
qty.value="";
}
document.getElementById("mainButton").addEventListener("click",afterButtonClicked);
</script>
References:
EventTarget.addEventListener()
Document.getElementById()
Actually I load the picture on the server. But once we do this, the page refreshes. My goal is to do this without refreshing the page. How can I do that? Is there anyone who can help?
In the code below I write onsubmit = "return false" in the form. But the picture is not uploaded to the server because the page is not refresh in this way.
VIEW
#using (Html.BeginForm("create_conference", "Home", FormMethod.Post, new { enctype = "multipart/form-data", id = "registerFormValidation", onsubmit = "return false" }))
{
<div class="form-group">
<div class="input-group">
<span class="btn btn-default btn-wd btn-info btn-fill btn-file input-group-addon">
<i class="fa fa-image"></i> <input type="file" name="file" id="imgInp" accept="image/*">
</span>
<input type="text" class="form-control" readonly id="image-path" value="">
</div>
</div>
<div id="enter-room-name">
<div class="form-group">
<input type="text" placeholder="Enter Name of Room" class="form-control" required="true" id="room-name" autocomplete="false" style="text-transform:uppercase">
</div>
<button type="submit" name="add-room-submit" class="btn btn-info btn-round btn-wd">Save</button>
</div>
}
CONTROLLER
[HttpPost]
public ActionResult create_conference(HttpPostedFileBase file)
{
var path = "";
if (file != null)
{
if (file.ContentLength > 0)
{
//for checking uploaded file is image or not
if(Path.GetExtension(file.FileName).ToLower()==".jpg"
|| Path.GetExtension(file.FileName).ToLower()==".png"
|| Path.GetExtension(file.FileName).ToLower()==".gif"
|| Path.GetExtension(file.FileName).ToLower()==".jpeg")
{
path = Path.Combine(Server.MapPath("~/assets/img/conference-img"), file.FileName);
file.SaveAs(path);
ViewBag.UploadSuccess = true;
}
}
}
return View();
//return Redirect("rooms");
}
Don't read it as base64 using the fileReader or using a iframe...
Simply turn the form element into a FormData and send that to the server.
A good idea is not trying to specify method/url in the javascript keep it as general as possible and have the html markup do what it was meant to do (defining things) then you can use this function for more forms and it got a more graceful degration if javascript where turned of
function turnFormToAjax(evt) {
evt.preventDefault()
var form = evt.target
var fd = new FormData(fd)
fetch(form.target, {method: form.method, body: fd})
.then(function(res) {
// done uploading
})
}
document.querySelector('form').onsubmit = turnFormToAjax
Convert to base64 and ajax call it. Make sure the backend converts it back to an image file before saving it.
I've done it with jquery in the past.
This is the important part:
I've done it with jquery. This is the important part.
$(document).ready(function() {
$('#imageFile').change(function(evt) {
var files = evt.target.files;
var file = files[0];
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById('preview').src = e.target.result;
};
reader.readAsDataURL(file);
// console.log(file.name)
var filename = file.name
console.log(filename);
}
});
make sure filename sends.
You can upload image using iframe, using iframe and ajax image will upload without page refresh.
You can try using my sample.
HTML:
<form id="registerFormValidation" name="registerFormValidation" action="" method="POST" enctype="multipart/form-data" >
<div id="main">
<input name="imgInp" id="imgInp" size="27" type="file" />
<input type="button" name="action" value="Upload" onclick="upload()"/>
<iframe id='my_iframe' name='my_iframe' src="">
</iframe>
</div>
</form>
This is my JS:
function upload()
{
//'my_iframe' is the name of the iframe
document.getElementById('registerFormValidation').target = 'my_iframe';
document.getElementById('registerFormValidation').submit();
}
And For Server side you can use simple Ajax method or Custom method.If you use ajax method then action will be action="javascript:submitForm();" and if you use custom method then you can use your function name.
I have an hta file that writes to a text file using a form and some javascript.
The form's text field has id of keyword_id which is used by the JS, and directory is the value of the hidden field.
How do I change the JS to only create TEST.txt when user clicks submit?
The code also opens a new C: window everytime I click submit, what's with that?
Here is the html form & javascript code:
HTML:
<div class="tab-content">
<div id="signup">
<h1>Type any keyword(s):</h1>
<form action="/" method="post">
<div class="top-row">
<div class="field-wrap">
<label>
<span class="req"></span>
</label>
<input type="text" required autocomplete="off" id="keyword_id" />
<input type="hidden" name="write" value="C:\Users\ME\Desktop\TEST.txt" id="write_id"/>
<button type="submit" onclick="Writedata()" class="myButton"/>Auto Search</button>
</div>
</div>
Javascript
<script language="javascript">
function Writedata() {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var write_id;
write_id = document.getElementById('write_id').value ;
var s = fso.CreateTextFile(write_id, true);
s.WriteLine(document.getElementById('keyword_id').value);
s.Close();
}
</script>
You've <form action="/" method="post"> and the opened C folder is a response to the form submission.
Most likely you actually don't need the form to be submitted, hence you can omit the attributes in the form tag, and prevent the submission by changing the button type to "button". It's also possible to prevent the default action of button type="submit" by doing this:
function Writedata () {
:
window.event.returnValue = false;
window.event.cancelBubble = true;
}
on my html I have this tag for user browse a file from their computer, like this
*<form action="SamePageUpload.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="FINISH" onClick="echoHello()">
</form>*
by hit Submit button is clicked it will trigger 'echoHello()' js function, I want to pass the image to a php file SamePageUpload.php
*
<script>
function echoHello()
{
var url = "SamePageUpload.php";
var cv = ????;
$.post(url, {contentVar: cv}, function(data){
$("#alertDiv").html(data).show();
});
}
</script>*
but I don't know what ???? should asign to cv, I want to know what's the variable that represent the image file user choose? Please help, thank you