How to automatically assign/generate/increment an ID number into Google Form responses, so that respondents can access their own forms based on it? - email

I would like to set up a (Google) form-filling system, that essentially has to be accessed and filled two times (before and after the completion of a project). I would like to create a form one can return to by filling in an ID number.
For that, I would need a script that automatically generates an ID number for each respondent. I have found 'Google Apps Script for Form, Generate Unique ID Number', but I couldn't get it to work (I am not good at scripting yet). I would like to be able to decide how the ID numbers are generated (for example to have non-numeric characters as well, e.g. XYZ000000001, XYZ00000002, XYZ00000003, etc.)
The reason I want to do this is so that respondents can access their own responses based on the ID assigned to Them. I found two possible solutions, but again, I can't manage them. One code is the 'Class FormResponse' that fetches the existent information (if I understand it well enough), and the other is 'Generate unique Form URL for each respondent' which generates a unique URL for each respondent. That would work fine, but I still need the IDs for easier data maintenance.
This is a lot of code and I'm not sure if it makes sense to combine all of it. Perhaps there is an easier way to achieve what I want with a way simpler script. I will break down the process as I imagine it, into steps:
Send a form to AA#zive.com,BB#zive.com,CC#zive.com.
For example, BB only has a project planned, so BB receives the form which asks: Is Your project planned or completed?
BB chooses the first option and fills in the details.
BB gets a unique ID which is inserted into the first column of the responses.
The ID is sent back in a response email to BB (perhaps the linked script can be tweaked to send the unique ID).
After a couple of months, BB has completed the project, so BB goes back to the form, either via the same email sent in step 1, or the same form embedded on a website.
BB now chooses the second option, since the project is completed.
The form asks for the ID number, BB fills it.
All of BB's answers now go to the row with the matching ID, overwriting certain fields if necessary...
I am aware that this might be a bit complex, but any even partial answer accompanied by some snippets of code would be highly appreciated. I will gladly share it once I manage to compile the whole idea. :)

Google Forms doesn't allow respondents to search previous sent responses. The only way that they can access a previously submitted response is by the edit response URL. To get this URL programmatically, use getEditResponseUrl.
You could send this URL by an email. For details see How to add "Edit Response" link to Google Forms emails?

Related

Is there a way to create an output form based on Google Sheets data?

What I want to make
Is this possible?
I'd like to create an output form that reads data from a Google Sheets spreadsheet. In the form, users would enter a few values (entering their name and some ID number, for example) and view the corresponding information in the connected spreadsheet but not any other information in the sheet. Something like an output form in Microsoft Access. I'm hoping there's a way to accomplish this in Google Sheets using existing tools and maybe some scripting.
More generally, though, any way to create this type of 'limited visibility' on a per-user basis for Google Sheets data would be useful. (The 'protect sheet' function in the menu doesn't accomplish this; see below.)
For reference, my specific use case at the moment is as a teacher and wanting a way for students to see specific information related to them from my student information spreadsheet but while not revealing other students' information. I would have a simple form where they enter a name and maybe some personalized code that I give them so they can see their attendance record or something else. For my purposes, I don't need the form to be extremely secure as none of the information is all that sensitive (although more secure is better), but I don't want to be just putting all the information there in front of them by giving them access to the entire sheet.
What I've tried so far
I made a new spreadsheet file with two sheets; one sheet was visible to function as a form, and the second sheet was not visible (which I accomplished via the 'protect' menu option). I used importrange() to read in the relevant data from my primary spreadsheet to the new spreadsheet's non-visible sheet. On the visible sheet, students entered their name from a drop-down and entered their student ID as validation. If the student's name and ID matched, the first sheet did a vlookup() to read in information from the protected sheet and some information from their student record.
Here's what I made, in case my description doesn't make sense: https://drive.google.com/open?id=1cHO2jzMh1mkXvlLh-M4eYqN7v11t95-GnfWqL5IwQ14&authuser=0
This had two problems, one small and one big.
The small problem was that every student could see the "form" sheet at the same time. If two students opened the spreadsheet at the same time they would see any information that the other student had entered. I handled this by writing a simple script to automatically reset the "form's" input cells after 20 seconds. Also, any time the form was opened by a new person, the "form's" output cells were erased. So, obviously not a brilliant solution, but for my purposes, this was mostly good enough.
The big problem was that Google's own preview viewer (built into Google Drive and the like) ignores protected ranges and sheets and displays the entire contents a spreadsheet. (Normally, protected sheets are not visible at all and don't appear in the list of sheets at the bottom of the screen unless the viewer has access to them.)
In my case this meant included the protected one that shouldn't have been visible at all, rendered as if it were a print preview, meaning the students were actually able to view all of the other students' data in one big table.
Are you familiar with Web Apps?
An Apps Script Web App allows you among others to output selected Google Document contents into a browser.
Hereby, you can use the method Session.getActiveUser() to obtain the email of the user and dynamically adjust the data the user is going to obtain in function of his email (BTW, you can also use Session.getActiveUser() in the spreadsheet, to detect the user automatically instead of asking him for his name).
Simple example workflow:
Replace in column A student names through student emails (the Gmail addresses with which the users authenticate their sessions and access Google Sheets)
Bind to the spreadsheet a script with a content similar to the following:
function doGet(){
var ss=SpreadsheetApp.getActive().getSheetByName('Data');
var range=ss.getDataRange();
var values=range.getValues();
var user=Session.getActiveUser();
var output="";
for(var i=1;i<ss.getLastRow();i++){
if(values[i][0]==user){
for(var j=1;j<ss.getLastColumn();j++){
output+=(values[i][j])+" ";
}
}
}
return ContentService.createTextOutput(JSON.stringify(output));
}
Make sure that you have a doGet() function and a return statement.
After running the script once manually to trigger authorization flow, deploy it as a Web App - executing it as User accessing the web app and giving access to Anyone (unless desired otherwise).
Copy the URL of your WebApp and forward it to your student.
When the student open the URL in their browser - they will obtain their results - provided their email is listed in the sheet.
Please note that the code provided is a simple sample, that retrieves
all data and outputs it as a string. Feel free to modify the script
e.g. retrieving only columns of interest and outputting the data as a
html table, rather than a simple string.

Using ninja forms, how can I persist field values across pages?

I have a form on the home page of quotedjobs.com that I would like to persist the field values of across pages.
For example: A user enters some values in fields, such as job title (textbox), job type (list) and job description (text field). Underneath that I ask users to register on the site, but they have the option to click a link to allow them to login if they are already members.
What I would like to be able to do, is to redirect users to another form that is a copy, but allows them to login instead of register, but keep hold of the values that they entered in the title, type and description form of the previous page so they aren't losing their work.
I have seen the ninja_forms_processing variable in the docs, but I'm not clear on how to use that.
TL;DR - You can't.
As it was slim pickings here, I sent an email over to support. Got this response:
Hello,
At this time this use case is not possible in Ninja Forms. The plugin is currently unable to transfer data from field to field or between forms.
I’m sorry that we do not have a better solution for you at this time.
Thank you,

Why does GET pre-fill data trump POST data, and is there a simple way to reverse this?

In my mod_perl2 app, on one page I link to with ?form_field_name=pre_fill_value tacked onto the URI if I want to pre-fill a particular form field for the user. However, the form itself is just <form method=post>, which posts back to the current page, GET query and all. I expected that Apache2::Request's param() routine would serve up either only the POST data, or the POST data first. Instead, it seems the GET data is given precedence, i.e., the prefill is honoured over the manually-user-fixed data.
The easy fix is to add action= and the current URI without the GET query, but I'm wondering why it was designed this way, and if there's a sneaky way around it, like some mod_perl2 option that would give POST data precedence. However, the easy fix can actually cause problems if un-overridden GET query values are expected to be passed on. So this workaround quickly grows, but why is it even this way in the first place?

FormMail.pl 1.93 Multiple URl contact Form

I am using FormMail.pl version 1.93 for form submission. I have asked this question before for FormMail 3.14m1 but now I am using FormMail.pl version 1.93
I have a single contact-us form and what I would like to do is use this single form such as contactus.html (not multiple copies of this form) everywhere on my website as my site has different contact-us sections based on the department.
Let's say the contact-us form for marketing should email to technical#mydomain.com, contact-us form for sales should email to sales#mydomain.com, HR's contact-us form should email to hr#mydomain.com.
How can I use the single form while redirecting the submission to the appropriate department email address?
I am using FormMail.pl Version 1.93 for email submission
FormMail 1.93 seems to be the version from Matt's Script Archive. The programs from that site are badly written, potentially buggy and (as you have, no doubt, discovered for yourself) unsupported. Even Matt Wright himself no longer recommends their use.
You would be better advised to use the versions from the nms project. It sounds like you were using nms' version 3.14m1, but stopped for some reason. Why is that?
No matter which version you use, your problem is basically the same. In pretty much any version of FormMail the email recipient is either hard-coded in the program or derived from a form input (often a hidden form input) on the HTML page. If you're using the same installation of the program for different email addresses you can't hard-code the address within the program (for, hopefully, obvious reasons). So you're left with getting the address from the HTML page.
But you say you want to use the same form for different contact addresses. I'm not sure how you think this is going to work. How does the form know how it is being used? Are you perhaps embedding the form within various pages using iframes? I suppose it might be possible to change the value of the recipient form input depending on how the form is being accessed. You'd need to do this with Javascript.
The recommended way to approach this is to have a single copy of the FormMail program which is called from several different HTML forms.

MVC2 Routing and Security: How to securely pass parameters?

I'm a relative MVC noob coming from WebForms. I think I have a pretty good grasp of MVC with a couple exceptions, and I think I may have broken the pattern. I'm gonna try to keep this short, so I'm assuming that most of what I am asking is relatively obvious.
Let's say I have a news site with articles. In that case, a URL in the form of mynewssite.com/Articles/123 works just great because I don't care who views which article. The user can change the ArticleID in the URL to whatever they want and pull up that article. In my case, however, I only want the user to be able to view/edit data entities (articles, or whatever) that belong to them. To achieve this, I am using their UserID (GUID) as a foreign key in the database, and displaying a list of their data for them to choose from. Here comes the problem... when they click on the link that is created by Url.Action("Edit", New With {.id = item.id}) (I'm not using ActionLink because I need to add HTML content inside the link), the id shows up as a querystring parameter. I could add a route for it, but the id would still show up in the URL for them to tamper with. The obvious implication is that by tampering with the URL, they could view/edit any entity that they want.
What am I missing?
Is there a good way to pass the parameters without adding them on the URL? I know that I could put them in a form on the page and submit the form, but that seems cumbersome for my example, and I'm using jQuery.ajax in places that seems to conflict with this idea.
I could also check their UserID against the data in the Edit method, but that also seems cumbersome, too.
Is this question too broad? Please let me know what specifics you need. Thanks.
Even in Winforms, you would have to add special logic on each request to filter only the articles that the user owns. I don't see why MVC should be any different. Sure, you can use web.config to deny access to given url's, but not when you use a single page that takes a parameter of what data to show.
Your best bet is probably to filter this at the database level. By adding a where clause that includes the user id, then the app will return a "no records found" sort of error, and you can do whatever you want with it.
You could use forms authentication. This way when the user authenticates an encrypted cookie will be emitted which will contain his username which cannot be tampered with. Then you could verify whether the currently connected user has authorizations to edit this article.