Andrea Volontè
Andrea Volontè

Reputation: 85

Form "required" attribute in form input field not causing anything to happen

I'm Andrew from Italy, I'm trying to adapt a script I've found on line. It's a script that creates an HTML form and uploads answers in a spreadsheet.

This is the tutorial from wich I've started:

GS CODE:

var dropBoxId = "XXXXXXXXXXXXXXXX"; // Drive ID of 'dropbox' folder
var logSheetId = "XXXXXXXXXXXXXXXXX"; // Drive ID of log spreadsheet

function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}

function uploadFiles(formObject) {
try {
// Create a file in Drive from the one provided in the form
var folder = DriveApp.getFolderById(dropBoxId);
var blob = formObject.myFile;    
var file = folder.createFile(blob);    
file.setDescription("Uploaded by " + formObject.myName);

// Open the log and record the new file name, URL and name from form
var ss = SpreadsheetApp.openById(logSheetId);
var sheet = ss.getSheets()[0];
sheet.appendRow([file.getName(), file.getUrl(), formObject.myName, formObject.email]);

// Return the new file Drive URL so it can be put in the web app output
return file.getUrl();
} catch (error) {
return error.toString();
}
}

HTML code:

<form id="myForm">
  <input type="text" name="myName" placeholder="insert your name"/>
  <input type="email" name="email" autocomplete="on" placeholder="mail ">
  <input name="myFile" type="file" />
  <input type="button" value="send"
      onclick="google.script.run
          .withSuccessHandler(updateUrl)
          .withFailureHandler(onFailure)
          .uploadFiles(this.parentNode)" />
</form>

<div id="output"></div>

<script>
    function updateUrl(url) {
        var div = document.getElementById('output');
        div.innerHTML = '<a href="' + url + '">All done</a>';
    }
    function onFailure(error) {
        alert(error.message);
    }
</script>

<style>
  input { display:block; margin: 20px; }
</style>

I want to make some field required.

I've tried with

<input type="text" name="myName" required>

but nothing happened.

What can I do? Is there an easy solution?

thanks!! Andrea

EDIT After some suggestions I've updated the HTML code:

NEW HTML CODE:

<form id="myForm" onsubmit="google.script.run
          .withSuccessHandler(updateUrl)
          .withFailureHandler(onFailure)
          .uploadFiles(this)">

  <input type="text" name="myName" placeholder="insert your name" required />
  <input type="email" name="email" autocomplete="on" placeholder="mail ">
  <input name="myFile" type="file" />
  <input type="submit" value="send"/>

</form>

<div id="output"></div>

<script>
    function updateUrl(url) {
        var div = document.getElementById('output');
        div.innerHTML = '<a href="' + url + '">All done</a>';
    }
    function onFailure(error) {
        alert(error.message);
    }
</script>

<style>
  input { display:block; margin: 20px; }
</style>

Now if I don't upload any files the required function works correctly and the spreadsheet is updated. If I attach a file when I click the button the page refresh and the link of the script change in this way:

https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXXXXX/dev?myName=FirstName&email=mymail%40mail.com&myFile=File1.txt

I've added some Logger.log in the GS code in this way:

var dropBoxId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Drive ID of 'dropbox' folder
var logSheetId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Drive ID of log spreadsheet
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(formObject) {
try {
// Create a file in Drive from the one provided in the form
var folder = DriveApp.getFolderById(dropBoxId);
var blob = formObject.myFile;    
var file = folder.createFile(blob);    
file.setDescription("Uploaded by " + formObject.myName);
  Logger.log('blob : ' + blob)
  Logger.log('myName : ' + formObject.myName)

// Open the log and record the new file name, URL and name from form
var ss = SpreadsheetApp.openById(logSheetId);
var sheet = ss.getSheets()[0];
sheet.appendRow([file.getName(), file.getUrl(), formObject.myName, formObject.email]);

// Return the new file Drive URL so it can be put in the web app output
return file.getUrl();
} catch (error) {
return error.toString();
}
}

This is the output if I don't upload any files:

[15-05-26 09:33:47:789 CEST] blob : FileUpload
[15-05-26 09:33:47:789 CEST] myName : myFirstName

If I attach a file the log is totally blank.

I can't understand where the problem is.

Upvotes: 1

Views: 3352

Answers (1)

Alan Wells
Alan Wells

Reputation: 31300

The code you are using does not have a "submit" type input (input tag displayed as a submit button). The button in the form you are using is an input tag of the type "button".

<input type="button">

The required attribute will not work with an input type of "button". It will work with an input tag of type "submit".

<input type="submit">

StackOverflow - Difference between button and submit

But what exactly does "submit" do? An input tag of the type "submit" causes whatever action is specified in the form tag to be executed or alternatively, causes the onsubmit to trigger:

<form action="urlToInvoke">

onsubmit:

<form onsubmit="myFunction()">

Your input form has no action or onsubmit attribute:

<form id="myForm">

In your form, the google.script.run function is called from input tag of the type "button".

Current set up:

  <input type="button" value="send"
  onclick="google.script.run
      .withSuccessHandler(updateUrl)
      .withFailureHandler(onFailure)
      .uploadFiles(this.parentNode)" />

If you want to try to get the required functionality to work, here's what you can try:

Change the input type to "submit":

<input type="submit">

Put the google.script.run code into an onsubmit attribute of the form:

<form id="myForm" onsubmit="google.script.run
      .withSuccessHandler(updateUrl)
      .withFailureHandler(onFailure)
      .uploadFiles(this)">

Make sure that you change this.parentNode to this. Using just the this keyword alone refers to whatever element it's being used in. When the onsubmit was being executed from the button, the button is a child of the form. In that case, it was necessary to get the parent, which is the form, to pass to the function, thus this.parentNode.

Upvotes: 4

Related Questions