Issue with setTimeout Function in Google App Script

I am working with a standard Google App Html form that collects data and stores it in a spreadsheet. Below are the details of the files:

HTML Form:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">

    <?!= include("css");?>
  </head>
  <body>
    <h2>Feedback Form</h2>
    <div id="message"></div>

  <!--- BUTTON New registration --->
    <br /><input id="button-responder" type ="button" value = "New registration"   
            onclick="submitResponder('button-responder'),
            submitTransition('message');" style="display:none;" />

  <!--- FORM --->   
   <form id="my-form">
    <br /><input id="name" type="text" name="name" placeholder="Your Name">
    <br /><input id="email" type="email" name="email" placeholder="Your Email">
    <br /><textarea id="comment" rows="10" cols="40" name="comment"></textarea>
   <!--- BUTTON submitForm ---> 
    <br /><input id="btn" type="button" value="Submit"
            onclick="submitForm(this.parentNode),
            document.getElementById('my-form').style.display='none',
            submitResponder('button-responder'),submitTransition('message');" />
   </form>
    <?!= include("test-js");?>  
  </body>
</html>

Google Script:

function doGet(request) {
  return HtmlService.createTemplateFromFile('index')
      .evaluate();
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}


function submitData(form) {
  var subject='New Feedback';
  var body=Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s', form.name,form.email,form.comment);

  var folderId = "my-folder-ID";

  var blob = Utilities.newBlob(body, MimeType.HTML, form.name).getAs(MimeType.PDF);
  var file = DriveApp.getFolderById(folderId).createFile(blob);

  return Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s<br />
  PDF: <a target="_blank" href="%s">see your PDF file</a>',  
  form.name,form.email,form.comment,file.getUrl());

function userClicked(userInfo){
  var url = "https://docs.google.com/spreadsheets/d/my-spreadsheet-ID";
  var ss = SpreadsheetApp.openByUrl(url);
  var ws = ss.getSheetByName("Data");
  ws.appendRow([userInfo.name, userInfo.email, userInfo.comment]);
}

test-js

<script>

  function submitForm(form) {
    google.script.run
     .withSuccessHandler(function(value){
       document.getElementById('message').innerHTML = value;
       document.getElementById('name').value = '';
       document.getElementById('email').value = '';
       document.getElementById('comment').value = '';
      }) 
      .submitData(form);
  }

  function submitResponder() {
    var x = document.getElementById("button-responder");
    var xx = document.getElementById("my-form");
    var xxx = document.getElementById("message");
    if (x.style.display === "none") {
      x.style.display = "block";
      xx.style.display = "none";
      xxx.style.display = "block";
    } else {
      x.style.display = "none";
      xx.style.display = "block";
      xxx.style.display = "none";
    }
  }


  function submitTransition() {
    setTimeout(function() {
     document.getElementById('message').style.color = 'blue';}, 2500);
  }


document.getElementById("btn").addEventListener("click",doStuff);
  
  function doStuff(){
    var userInfo = {}
    userInfo.name = document.getElementById("name").value;
    userInfo.email = document.getElementById("email").value;
    userInfo.comment = document.getElementById("comment").value;
  

    google.script.run.userClicked(userInfo);
    document.getElementById("name").value= "";
    document.getElementById("email").value= "";
    document.getElementById("comment").value= "";     
  }

</script>

css:

<style>

 #message {
  color: transparent;
 }

</style>

QUESTION

In the Google Script file, the function

function submitData(form)

and in the test-js file, the function

function doStuff()

work effectively but with a delay of approximately 2.5 seconds. Furthermore, for the function in the Google Script file,

return Utilities.formatString

to display the results (name - email - comment - PDF Url), a 2.5-second waiting period is needed.

Functions as variables.

The function in the test-js file,

function submitResponder()

displays fields associated with the ID (message) along with variables like

name: example-name
email: example-email
comment: example-comment
PDF: see your example-PDF file

as well as the field linked to the ID (button-responder) displaying the "New registration" button.

Upon loading the index.html page, initially, the form and the "submit" button appear. After editing the fields and clicking on submit, the form disappears, the "New registration" button shows up, and after around 2.5 seconds, the updated fields (name, email, etc.) are displayed.

By clicking on the "New registration" button below, the form reappears without reloading the page, simply by adjusting the display property.

However, an issue arises when re-editing the fields and clicking on submit-form again, the previously edited fields show up immediately before updating with the latest changes.

To address this, the function

function submitTransition () { setTimeout (function () { document.getElementById ('message'). style.color = 'blue';}, 2500); }

is used, combined with the CSS styling:

#message { color: transparent; }

An effective solution is sought to hide the display of the old fields until the new updates are completed.

Your input on solving this problem would be greatly appreciated. Thank you in advance.

Answer №1

  • To display the texts and button for "New registration" after clicking the "submit" button and completing the submitData script.

If I understand correctly, would this modification work?

The issue is that google.script.run runs asynchronously. This means that actions like

document.getElementById('my-form').style.display='none'
,
submitResponder('button-responder')
, and submitTransition('message') are executed before the submitData script is finished.

Modified script:

Please make the following modifications to your script.

From:

<br /><input id="btn" type="button" value="Submit"
        onclick="submitForm(this.parentNode),
        document.getElementById('my-form').style.display='none',
        submitResponder('button-responder'),submitTransition('message');" />

To:

<br /><input id="btn" type="button" value="Submit" onclick="submitForm(this.parentNode)" />

And

From:

function submitForm(form) {
  google.script.run
   .withSuccessHandler(function(value){
     document.getElementById('message').innerHTML = value;
     document.getElementById('name').value = '';
     document.getElementById('email').value = '';
     document.getElementById('comment').value = '';
    }) 
    .submitData(form);
}

To:

function submitForm(form) {
  google.script.run
   .withSuccessHandler(function(value){
     document.getElementById('message').innerHTML = value;
     document.getElementById('name').value = '';
     document.getElementById('email').value = '';
     document.getElementById('comment').value = '';

     document.getElementById('my-form').style.display='none';  // Added
     submitResponder('button-responder');  // Added
     submitTransition('message');  // Added
    }) 
    .submitData(form);
}

By making these changes, you can also eliminate the need for setTimeout as follows.

From:

function submitTransition() {
  setTimeout(function() {
   document.getElementById('message').style.color = 'blue';}, 2500);
}

To:

function submitTransition() {
  document.getElementById('message').style.color = 'blue';
}

Reference

If my interpretation of your question is incorrect and this is not the desired outcome, I apologize.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to connect the user-input data with text in a span element?

Recently, I've started learning Vue.js and I'm facing an issue with binding data from an input field to a span element. Instead of appending the data, it's showing me undefined Here is the code snippet: new Vue({ el: "#app", data: { ...

What is the method to apply custom styles (CSS) to individual options within a jQuery UI selectmenu?

When working with an HTML form that includes a select element, I encountered a design challenge. <select id='myselect'> <option value='1'>1</option> <option value='2'>2</option> ... <option va ...

Hide one div when another is toggled

Once an image is clicked, a div appears using toggle. I want the initial div to disappear when the second one toggles, and tried using the .css function in JavaScript for this purpose. However, it only applies to the first case as it receives information f ...

Having trouble accessing the input class with jQuery

When I click the "Reset To Default Settings" button in my form, I want to clear the default colors in my 4 color pickers. Each of them has an input type text field with the class anyicon-form-colorpicker. To achieve this, I locate the <a> tag and use ...

Utilize AJAX to fetch and display the response from a Node JS route directly onto an HTML page

At the moment, I am retrieving client-side HTML/JS inputs (var1 and var2) which are then sent to server-side Node JS. The input values are stored in variables through an AJAX post call made to a specific route. What I want now is to define the values of v ...

How can I access a component variable within a foreach loop in Typescript?

Can anyone please explain how I can access a component variable within a foreach loop? Check out my code on Plunker public exampleVariable:number; test(){ console.log('fired'); var x =[1,2,3,4]; x.forEach(function (e){ th ...

How can I retrieve the value of a JavaScript variable using Ajax?

Hello everyone! I've been a long-time user of various programming forums, but this is my first time posting. Lately, I created a really simple browser-based game, and when I say simple, I mean it's incredibly basic. The whole game logic resides ...

Passport local authentication: the deserializeUser function was not invoked

I've been experimenting with passport-local authentication in a test app and I've run into an issue. For some reason, the deserializeUser function is not being called when I send a post request using Postman, but it never gets called when the pos ...

Customize the border width and color of a specific column in HighCharts based on dynamic data

I am looking to dynamically change the border width and color of only one column in a basic column chart. Here is an example: var chartingOptions = { chart: { renderTo: 'container', type: 'column' }, xAxis: { categories: [ ...

What is the solution to prevent a CSS flex column from expanding to fill the width in a row with three

I am trying to create a flex row with three columns, but when I only have two columns in the row, the second column gets pushed to the right side. You can see this issue in the image below. https://i.sstatic.net/cVVqB.png In the image, the red lines indi ...

What is causing the recurring appearance of the 'prompt'?

Edit: I made a silly mistake in this question that I didn't catch before. Now, I'm unable to delete it. PLEASE DISREGARD. I recently built a basic website by following a tutorial. It essentially performs two simple tasks: 1). Changes the image ...

Utilizing getImageData and putImageData in the Canvas Puzzle Project

Below is the code I've written to interact with my canvas: function clickBox() //Function to retrieve cell coordinates on the grid. { var xRectFill = 0; var yRectFill = 0; var rectFillArrayX = []; var rectFillArrayY = []; var mo ...

Exploring the PayPal Checkout JavaScript SDK's CreateOrder call and interpreting the response

I am currently exploring how to use the JavaScript SDK to display PayPal payment buttons on a website. I am new to working with JSON and REST API calls, so I am facing some challenges in implementing this. The createOrder function is running smoothly and ...

Having trouble with Knockout Js Array.removeAll() function not functioning as expected?

let values = ko.observableArray([....]); values.removeAll(); The scenario involves 'values' holding selected options from dynamically generated dropdowns using knockout. The goal is to clear all user selections. Unfortunately, the provided code ...

Which software is recommended for converting Sass to CSS on a Linux operating system?

Just starting out with Sass and I've run into a snag. Currently following a tutorial that utilizes Scout as the Sass compiler for generating CSS. The issue is that Scout is compatible only with Windows and Mac, while I work on Ubuntu Linux. Any reco ...

Develop a Yeoman generator that incorporates API calls

After successfully creating a Yeoman generator, I now have the task of adding two additional questions to it. I already have these questions in place async prompting() { const prompts = [ { name: "appName", message: "Proje ...

What is the best way to maintain the selected radio button on the following page using PHP?

Image of My Project I am working with a file and need some assistance. I want to ensure that when a user selects an answer, the radio button value remains unchanged if they click back. Can someone please help me with this? while( $row = mysqli_fetch_arra ...

Issue with the save-button in inlineNav of JQGrid not functioning properly after adding a second row for free

We have encountered an issue with adding new rows to several Free JQGrids. When clicking on the ADD icon in inlineNav, a new row appears and clicking the SAVE icon for the first time works correctly. However, when trying to add a second row, the Save butto ...

Identify Unintended Javascript Modifications in Ajax Request

We have developed a unique Javascript file for our clients to utilize. This innovative snippet captures a screenshot of the website it is executed on and then securely transmits it back to our server using jQuery.post() Given the sensitive nature of our i ...

How can I create a mipmap for a planet using three.js?

Recently, I delved into the realm of mipmapping and its definition, but I find myself uncertain about how to effectively implement this technique in three.js. After exploring a couple of examples like: and also this one: Both examples appear to utilize ...