Keep track of the user's email address as they complete the form

I currently use a Google Form to gather information from employees who work in remote locations

Emp No *
Punch *
Customer details / mode or travel

All the data collected is stored in a Google spreadsheet structured as follows:

Timestamp   Emp No  Punch   Remark  Name    GeoCode GeoAddress  Email

With a certain script, I am able to capture the GPS coordinates of the users. I created a web app where anyone, even without an account, can access it and click the link.

However, there are a few issues I am facing:

I wish to store the email ID (or employee number) of the user filling out the form. Unfortunately, the email ID does not get captured. It only works when I fill out the form myself. How can I capture this information for all users without requiring them to authenticate the script?

If the GPS information is missing (empty), I want to display a different message on the HTML page. Is there a way to do this?

Below is the relevant code:

function doGet() {
    return HtmlService.createHtmlOutputFromFile("Index");
}
//
function getLoc(value) {
  var destId = FormApp.getActiveForm().getDestinationId() ;
  var ss = SpreadsheetApp.openById(destId) ;
  var respSheet = ss.getSheetByName("Location");
  var numResponses = respSheet.getLastRow();
  var currentemail = Session.getActiveUser().getEmail();
  var c=value[0]; var d=value[1];
  var e=c + "," + d ;
  //respSheet.getRange(numResponses,6).setValue(e);
  //respSheet.getRange(numResponses,8).setValue(currentemail);
  var response = Maps.newGeocoder().reverseGeocode(value[0], value[1]);
  var f= response.results[0].formatted_address;
  //respSheet.getRange(numResponses,7).setValue(f);
  respSheet.getRange(numResponses,6,1,3 ).setValues([[ e, f, currentemail ]]);
}
//

index.html

<!DOCTYPE html>
<html>
<script>
(function getLocation() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition);
      }
})()      
function showPosition(position){
 var a= position.coords.latitude;
 var b= position.coords.longitude;
 var c=[a,b]
 getPos(c)
 function getPos(value){
 google.script.run.getLoc(value);
 }
}

</script>
<body>
<p>Please ensure your GPS is on to record your location. You can generate the report from website to check. Pl. close this window (version 3)</p>
</body>
</html>

Answer №1

After receiving a query

I am looking to store the email ID (or employee number) of the individual filling out the form. However, I am facing issues with capturing the email ID in the form submission process. Although it works when I fill out the form myself, it does not work for other users. I am seeking a method to capture this information without requiring all users to authenticate the script or be logged in. Is there an alternative approach that can achieve this?

If you are using a web application built with Google Apps Script to automatically retrieve user email IDs, you have the option to configure the application to run as the user executing it rather than yourself. However, if you prefer not to utilize this functionality, then you will need to implement your own authentication mechanism.

Regarding the inquiry raised

In cases where the GPS location is not captured and remains empty, I aim to display a distinct message on the HTML page. How can this be accomplished?

You can address this by employing a JavaScript conditional expression

function getLocation() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition);
    } else {
      alert('Can\'t get the position');
    }
})() 

function showPosition(position){
 var a= position.coords.latitude;
 var b= position.coords.longitude;
 var c=[a,b];
 getPos(c);
 function getPos(value){
 google.script.run.getLoc(value);
 }
}

The provided code snippet uses alert, but utilizing the DOM is also an option.

Additional Resources

Answer №2

Successfully created a comprehensive solution using only HTML, without relying on Google Forms. Also implemented an alert message functionality. However, the "Login" feature is still non-functional.

Code.gs

This script executes a form and stores the responses in designated columns within a Google Sheet. It offers faster performance compared to Google Forms, requiring only one click on the "Submit" button. The use of "append row" prevents data jumbling between rows, eliminating previous issues with data consistency.


/* @Include JavaScript and CSS Files */
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
  .getContent();
}

/* @Process Form */
function processForm(formObject) {
  var url = "https://docs.google.com/spreadsheets/d/...../edit#gid=52499297";
  var ss = SpreadsheetApp.openByUrl(url);
  var ws = ss.getSheetByName("Location");
  var response = Maps.newGeocoder().reverseGeocode(formObject.lat, formObject.long);
  var address= response.results[0].formatted_address;
  ws.appendRow(
    [
      new Date(),
      formObject.empno,
      formObject.punch,
      formObject.rem,
      "",
      formObject.lat+","+formObject.long,
      address
    ]
  );
}



Index.html

This file contains the survey questions.

<!DOCTYPE html>
<html>

<head>
    <base target="_top">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <?!= include('JavaScript'); ?>
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col-6">
                <form id="myForm" onsubmit="handleFormSubmit(this);">
                    <p class="h4 mb-4 text-left">Record Attendance and Location</p>

                    <div class="form-group">
                        <label for="empno">Emp No - <a href="https://docs.google.com/spreadsheets/d/1yhcUpfhvyPcWyDkwglJRJwMn7VnBYEHaAjz959JC0wk/edit#gid=0">Click to see list</a></label>
                        <input type="number" class="form-control" id="empno" name="empno"  min="1" max="9999999"  required>
                    </div>

                    <div class="form-group">
                        <label for="punch">Punch (Select one)</label>
                        <select class="form-control" id="punch" name="punch" required>
                            <option selected disabled hidden style='display: none' value=''></option>
                            <option value="In">In</option>
                            <option value="Out">Out</option>
                            <option value="Started">Started</option>
                            <option value="Reached">Reached</option>
                        </select>
                    </div>

                    <div class="form-group">
                        <label for="rem">Remark</label>
                        <input type="text" class="form-control" id="rem" name="rem">
                    </div>


                    <div class="form-group">
                        <input type="hidden" class="form-control" id="lat" name="lat">
                        <input type="hidden" class="form-control" id="long" name="long">
                    </div>

                    <button type="submit" class="btn btn-primary btn-block">Submit</button>
                </form>

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

</html>


JavaScript.html

This file handles the processing of user responses.

<script>
    function showPosition() {
        navigator.geolocation.getCurrentPosition(showMap);
    }

    function showMap(position) {
        // Get location data
        var lat = position.coords.latitude;
        var geo1 = document.getElementById("lat");
        geo1.value = lat;
        var long = position.coords.longitude;
        var geo2 = document.getElementById("long");
        geo2.value = long;
    }

    // Prevent forms from submitting.
    function preventFormSubmit() {
        var forms = document.querySelectorAll('form');
        for (var i = 0; i < forms.length; i++) {
            forms[i].addEventListener('submit', function(event) {
                event.preventDefault();
            });
        }
    }
    window.addEventListener('load', preventFormSubmit);
    window.addEventListener('load', showPosition);

    function handleFormSubmit(formObject) {
        google.script.run.processForm(formObject);
        document.getElementById("myForm").reset();
        alert('Data saved successfully');
        
    }
</script>

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

Simple JavaScript numeric input field

Hey there, I'm a beginner learning JavaScript. I'm currently working on creating a program that adds numbers input through text fields. If you want to check out the HTML code, visit this link on JS Fiddle: http://jsfiddle.net/fCXMt/ My questio ...

Injecting a component in Angular 2 using an HTML selector

When I tried to access a component created using a selector within some HTML, I misunderstood the hierarchical provider creation process. I thought providers would look for an existing instance and provide that when injected into another component. In my ...

Ways to implement a placeholder height for images on a webpage with varying heights using HTML

I'm facing an issue with an image on my website that has a dynamic width and height as defined by the following CSS: .sm_item_image { width:100%; height:auto; max-width:400px; } The problem arises when the image takes some time to load, ...

What is the best way to target the specific DIV using a jQuery selector?

My dynamic div is filled with other divs... <div id="wrapper"> </div> //javascript for(//lots of times){ var d = document.cloneNode('divModel'); d.foo = {//a lot of stuff }; document.getChildById('wrapper').append ...

What is the method for generating dynamic objects from configuration data with Ext JS?

Working with Ext Js to develop a dynamic web application can be quite challenging. When making an AJAX call to fetch data from the server, it's often unclear what the data will be until it is received. While some examples suggest adding dynamic object ...

How can I switch the visibility of two A HREF elements by clicking on one of them?

Let me break it down for you in the simplest way possible. First off, there's this <a href="#" id="PAUSE" class="tubular-pause">Pause</a> and then we have a second one <a href="#" id="PLAY" class="tubular-play">Play</a> Al ...

Encountering an Internal Server error with Mongoose in Node.js

My latest project is a web application designed for photo sharing. One particular route in the app is responsible for retrieving and displaying photos from all users in the following array. This is the route: router.get('/getphotos',function(r ...

Retrieving and securely storing information using fetch() on authenticated REST services

Currently, I have successfully set up a React application that communicates with a REST backend which is built using Python and Flask. The specific functionality I have achieved involves downloading data from a database and saving it as a CSV file through ...

Customizing multi select in MUIv5 AutoComplete feature

My current challenge involves using the mui Autocomplete multi-select component. I'm having trouble getting it to function according to my specific requirements. Essentially, I need to set default selected values passed as props from the Parent compon ...

Tips on displaying the appropriate object value in a text field based on the selection from a dropdown menu

In my Ruby on Rails form, I have a dropdown menu with various category names: <td> <div class="div1"> <%= f.collection_select(:category_id, Category.all, :name, id: 'category_select', :include_blank => & ...

Using ASP.net MVC 4 to Implement Validation with Bootstrap Modal and PartialView

After switching from a simple View with validation to using a bootstrap modal and PartialView in my application, I encountered some issues. The client-side validation no longer works and the server-side validation redirects me to a new page instead of disp ...

Accessing a specific attribute of an object contained within an array

Currently, I am utilizing Vue.js in my project and have implemented a method that involves comparing values from two different arrays. array1: [{ name: 'test1', somevar: true }, { name: 'test2', somevar: false }] array2: ['test1 ...

What is the best way to select an element based on its relationship to another Element object using a selector?

I am currently developing a small library in which I require the ability to select a relative element to the targeted element using the querySelector method. For instance: HTML <div class="target"></div> <div class="relative"></div& ...

Show the current phone number with the default flag instead of choosing the appropriate one using the initial country flag in intl-tel-input

Utilizing intl-tel-input to store a user's full international number in the database has been successful. However, when attempting to display the phone number, it correctly removes the country code but does not select the appropriate country flag; ins ...

Refreshing the page resolves unhandled errors that occur when an item is removed from local storage

I'm currently working on adding a logout button to my website. I have the user's token saved in local storage, but when the logout button is clicked and the token is removed from local storage, an error occurs upon redirecting back to the login p ...

The issue of NextAuth in connection with Spotify failing to display the user's profile picture

I have recently implemented NextAuth v4 and encountered an issue after authenticating with Spotify. Despite successfully retrieving user information from Spotify, I seem to be missing access to the user's profile picture. Here is the data I receive fr ...

Tips for concealing the Bottom bar action in React Native

Currently facing an issue with React Native - I need to hide the bottom action bar located just below my tab bar navigation. I'm trying to create a clone of the Disney + App and this particular problem has me stuck: Here's the bottom part of my ...

Enhance your website with jQuery's animate() feature for dynamic

My current implementation of jQuery's animate function looks like this: var css1 = { display: "block", marginTop: 20 }; var direction = "marginTop"; $(element).animate(css1, 150, 'swing'); I've noticed the marginTop ...

Updating with Setstate

Refreshing the page with Setstate, registering twice and doubling the count of both heads and tails counter every time on click instead of adding just +1 class CoinFlip extends Component { constructor(props) { super(props); ...

What is the recommended way to emphasize an input field that contains validation errors using Trinidad (JSF)?

Trinidad currently displays error messages and highlights labels of failed inputs after client-side form validation. However, I need to directly highlight the input fields themselves. Is there a way to achieve this without resorting to a hack like attach ...