Specifying form for 'on form submit' trigger - javascript

I have two google forms, which send data to two tabs in a single spreadsheet.
I have set up a script with two functions. I would like the first function to run on submission of the first form. And, the second function to run on submission of the second form.
Problem is: when setting up a trigger onformsubmit, it does not allow you to specify which form.
Therefore, whenever completing the first form, it runs both functions.
Question: how can I restrict the functions from running only when the specific form is submitted?

As I suggested in the comments, you can determine the origin of the form submission by analyzing the response object's content.
Here is a basic example to illustrate : it will send you an email to tell which form has been submitted but you can of course use the same condition test to select the action you want to run.
function formSubmitOriginTest(e){
// Logger.log(JSON.stringify(e));
// example value : {"namedValues":{"Untitled Question 2":["test"],"Timestamp":["8/17/2014 11:22:47"]},"values":["8/17/2014 11:22:47","test"],"source":{},"range":{"rowStart":3,"rowEnd":3,"columnEnd":2,"columnStart":1},"authMode":{}}
if(e.namedValues["Untitled Question 2"]!=undefined){// only form B has one question with this exact title, that's enough to identify it.
MailApp.sendEmail(Session.getActiveUser().getEmail(),'form B has been submitted','');// optionally include the answers in the email body if you want
}else{
MailApp.sendEmail(Session.getActiveUser().getEmail(),'form A has been submitted','');// optionally include the answers in the email body if you want
}
}

Another way this can be done is by looking at the sheet name that comes in the response's event object via the range property. Here's an example of how I determined the form that triggered the submission:
// set the sheet name that stores the form responses you care about here:
function getSourceSheetName() { return 'Form Responses 1'; }
function submit(eventObj) {
var range = eventObj.range;
var eventSourceSheetName = range.getSheet().getName();
var givenSourceSheetName = getSourceSheetName();
// if the source sheet (from form response sheet) is not the same as the specified form response sheet, quit (return) so extra forms don't trigger the code
if (eventSourceSheetName.toUpperCase() !== givenSourceSheetName.toUpperCase() ) {
Logger.log('A different form just submitted data - quit code');
return;
}
// you now know which form submitted the response, so do whatever you want!
// ... your code goes here
}
Basically, this code grabs the name of the sheet that the Form response comes from via range.getSheet().getName(). Next, it checks if that name is a specified name we're looking for (specified in the function getSourceSheetName().
I think it's also possible to get the active sheet name via:
eventObj.source.getActiveSheet().getName();
In case you don't want to use "Range".
I hope this helps!

I was just looking at some documentation and found this:
Documentation forForm
It states:
Creates and returns a FormTriggerBuilder tied to the given form.
Also:
var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
ScriptApp.newTrigger('myFunction')
.forForm(form)
.onFormSubmit()
.create();
onFormSubmit
That code seems to be tied to a specific form.

Related

How to only enable submit function, when smth in dropdown is slected

I am building a web app and have a question to my drop down menu.
The goal is, that the data can only be submitted, when a number is selected in the dropdown menu.
Just check if the dropdown is set or not should be enough. If the input of the request is invalid, the correct response would be a 400.
app.get('/lbc.js', (req, res) => {
if (req.body.dropdown === undefined || req.body.dropdown === null)
res.status(400).send({ message: "Drop down was not selected" });
return;
}
// continue with whatever you want if submit is possible
}
Your frontend needs to handle this response as well, because now it probably won't make a distinction when it works or not. So if you'd capture the submit event of the form, you could send the request yourself using the fetch api, and do different things for a 200 (when the response succeeded) or something like a 400 (request failed).
EDIT:
You can read up on how to create and handle submit events here:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event
Here you can read how you can send webrequests through javascript:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
These are the steps you need to do:
Put an id on your form, e.g. <form id="myForm" ... >
Start a JavaScript tag i.e. <script> </script>
Within these tags, first get the form reference:
const form = document.findElementById("myForm");
Put a submit event listener on it like how they do in the link
In the event handler function, send the request, and deal with the response (show message if error, do something else if success for instance).
EDIT april 7th:
About your code and your comments I have the following to say:
You have created 2 forms, one for your dropdown and one for your button. Both of them should be in the same <form></form> tag. When you click your submit button, all <input> fields will be sent to whereever your form submits to.
You seem to need to check if all fields are filled in correctly before you send the data to your server. Like I said in my previous answer, you need to create a script that will do this. In this link you can read again in a simple way how to do such a thing
Checking if a field has a value is again done by obtaining the element through it's id. E.g. if you have an input like: <input type="text" id="firstName" name="firstName" />, you can obtain the value of this field in javascript as such: const valueFromField = document.getElementById("firstName").value;
Hopefully this will give you some hints to make some new steps.
In my humble opinion it would probably be a good idea for you to do some basic javascript tutorials to give you some insight on how that stuff works.
According to the given details, Try this.
You can check the value and perform your actions as below.
if(req.body && req.body.dropdown) {
res.send('submit is possible')
} else {
res.send('Please select the amount!')
}
Also use, POST method route
app.post('/test', function (req, res) {
res.send('POST request to the homepage')
})
Read more about Express.js routing

How to use onOpen trigger to populate current Date field on Google Forms [duplicate]

I have an existing Google Form in which there is a TextItem with a title "Which location was this performed at?".
Whenever the form is loaded (opened), I need to set a location value (loc) to this existing textbox and show it to the user.
function populateMemberIds(loc){
var form = FormApp.openById(formUrl);
var questions = form.getItems();
for (var i=0; i<questions.length; i++){
if(questions[i].getTitle()=="Which location was this performed at?"){
var textItem = questions[i].asTextItem();
//I get stuck here
}
}
I already setup the openForm trigger which allows to run the populateMemberIds function to be run on each form load. Again, what I need is to change the value of the "Your answer" section of the text item with the location value (loc).
I would appreciate any help.
You can't modify a form response filled by a user, you can either create a form response programmatically or edit a response after being submitted. The onOpen form trigger runs when someone opens the form to edit it rather than answer it [1]:
This event does not occur when a user opens a form to respond, but
rather when an editor opens the form to modify it.
Moreover, triggers functions comes with an event parameter already defined [1] so you can't set your own function parameter(s) as you're doing with your loc parameter.
EDIT
You can programmatically create and submit a form response [2], from which you can also get a URL with a prefilled form for the user to finish [3].
function populateMemberIds(loc){
var form = FormApp.openById("[FORM-ID]");
var questions = form.getItems();
var response = form.createResponse();
for (var i=0; i<questions.length; i++){
if(questions[i].getTitle()=="title form"){//Which location was this performed at?"){
var textItem = questions[i].asTextItem();
var itemResponse = textItem.createResponse(loc) ;
response.withItemResponse(itemResponse);
}
}
//Submit programmatically the form response
response.submit();
//URL with prefilled form response
Logger.log(response.toPrefilledUrl());
}
function test () {
populateMemberIds("US");
}
[1] https://developers.google.com/apps-script/guides/triggers/events#google_forms_events
[2] https://developers.google.com/apps-script/reference/forms/form-response
[3] https://developers.google.com/apps-script/reference/forms/form-response#toprefilledurl
The onOpen Google Apps Script triggers (simple and installable) for Google Forms are executed only when the form is opened in the form editor, not when the form is opened by using the view / edit response links.
There are two ways to "prefill" a Google Forms response:
Use the prefilled response URL
Create a response programmatically, then use the editResponseUrl
Related
Is it possible to 'prefill' a google form using data from a google spreadsheet?
How to generate a pre-filled form URL for Google Form

How to detect Event Listeners and their actions on input fields

I have purchased a booking plugin (wordpress) to add to a site.
https://wpamelia.com/
I cannot show the site I am working on, but here a demo from plugin developers
https://sports.wpamelia.com/#book
Once you have chosen your date and time, you end up on a form with input fields.
I was able to pre-fill this form with data that I could pass via the URL.
My URL would look something like this: https://sports.wpamelia.com/?first=Jim&last=Tester&email=something%40something.com&phone=0222222222#book
But here is the problem:
Even though I managed to use jQuery to pre-fill the input fields of the form, as soon as I click confirm the fields' content is erased and the error "Please enter... " appears for each of them.
So again:
STEP 1: I open the booking page with an URL containing data in the query string
STEP 2: Using jQuery, I manage to pre-fill the form that appears after having chosen date and time (first name, last name ...)
STEP 3: I click "Confirm"
RESULT: all the fields are empty and for each one the error message "Please enter first name" (etc..) appears
I've messaged the plugin developers. Only answer was that there is indeed no functionality to take the data from the Query String into the form fields yet.
MY QUESTIONS:
1) How could I find out, with chrome inspector or other tools, why exactly the content I pre-fill into the form is ignored?
---> I've tried things like getEventListeners in the chrome inpector's console, but I don't really see how to get information out of that
2) Would anyone know what the issue is and/or how I could bypass it?
---> there is a lot of javascript from the plugin developers behind that and something is expecting manual entering of the data into the fields...
---> but even when trying to fake manual entering with things like $(this).trigger("change").val(function(i,val){return 'aaaa';}); this didn't solve the problem....
(If anyone is interested, I can post later my javascript/jQuery functionality to get the form fields pre-filled with data from Query String... interesting code as you have to wait until the fields appear for jQuery to recognise them..)
Thanks so much for any help!
cheers
Admino
#Admino - this may not be the best solution and I know this is an old question so you may not need it now but after not finding a better one it at least worked for me.
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
function valueOutput(element) {
element.dispatchEvent(new Event('input'));
}
jQuery(function() {
jQuery(document).on('change', 'input', function(e) {
valueOutput(e.target);
});
// you may want to perform more validations here if needed
// just checking here if email is present (but not checking for valid email address)
var fname = getUrlVars()["first"];
var lname = getUrlVars()["last"];
var email = getUrlVars()["email"];
var phone = getUrlVars()["phone"];
var custom1 = getUrlVars()["custom1"]; // you know this field label is Order Number
if (email.length > 0) {
// run an interval until the elements are present on the page (form displayed)
var checkInputs = setInterval(function() {
if (jQuery('.amelia-app-booking label[for="customer.email"]').length > 0) {
var em = jQuery('.amelia-app-booking label[for="customer.email"]').closest('.el-form-item').find('.el-input__inner');
// this checks to see if an Amelia customer is already present
if (em.val() == '') {
em.prop('value', email).val(email).trigger('change');
jQuery('.amelia-app-booking label[for="customer.firstName"]').closest('.el-form-item').find('.el-input__inner').prop('value', fname).val(fname).trigger('change');
jQuery('.amelia-app-booking label[for="customer.lastName"]').closest('.el-form-item').find('.el-input__inner').prop('value', lame).val(lame).trigger('change');
jQuery('.amelia-app-booking label[for="customer.phone"]').closest('.el-form-item').find('.el-input-group__prepend').siblings('.el-input__inner').prop('value', phone).val(phone).trigger('change');
}
// for custom fields I check the label text to find the correct input
if (custom1 != '') {
jQuery('.amelia-app-booking label:contains("Order Number")').closest('.el-form-item').find('.el-input__inner').prop('value', custom1).val(custom1).trigger('change');
}
// form info is updated so clear the interval
clearInterval(checkInputs);
}
}, 500);
}
});
You may want to try a different method than url params to sync this info so it's not so public in the url string. This code may not need both the prop and val jquery setters but I just left them for you to try. Hope it helps (and to others I'm open to a better solution)!

How do I pass a value from an HTML form submission to a Google Sheet and back to HTML in a Google Apps Script Web App

I'm trying to create a basic time clock web app.
So far, I'm using this script to create this web app which takes the input values and puts them in this spreadsheet for the time stamping part.
I need it to use one of the values from the form and perform a lookup in this sheet (take the longId and find me the name) and return the (name) value to the html page as a verification for the end user that they were identified correctly. Unfortunately, I don't know enough to grasp what I'm doing wrong. Let me know if I need to provide more info.
Edit 1
I'm thinking that I wasn't clear enough. I don't need the user info from entry, I need the user from a lookup. The user will be entering their ID anonymously, I need to match the ID to their info, and bring the info back for them to verify.
Edit 2
Using the link provided by Br. Sayan, I've created this script using this spreadsheet as above to test one piece of this. The web app here spits out: undefined. It should spit out "Student 3" Still not sure what I'm doing wrong.
One way for the next button to grab the student input field:
<input type="submit" onclick="studentName(document.getElementById('student').value)" value="Next..."/>
That sends the value to this func in Javascript.html:
function studentName(value) {
google.script.run
.withSuccessHandler(findSuccess)
.findStudent(value);
}
Which sends it to a findStudent(value) in Code.gs
You do the lookup and the return value goes back to findSuccess( result ) back in Javascript.html. Handle the result from there.
Also consider keeping the stock preventDefault() code that comes with the Web App template in the Help > Welcome Screen.
Please try this one:
(source: technokarak.com)
Also please have a look at:
Retrieve rows from spreadsheet data using GAS
EDIT:
Please make these changes in your function and let us know.
function findValue() {
var data = SpreadsheetApp.openById("15DRZRQ2Hcd7MNnAsu_lnZ6n4kiHeXW_OMPP3squbTLE").getSheetByName("Volatile Data").getDataRange().getValues();
for(i in data) {
if(data[i][3] == 100000003) {
Logger.log("yes");
Logger.log(data[i][0]);
var student = [];
student.push(data[i][0]);
return student;
}
}
}
It is a complicated answer, I have had a lot of success with:
function process(object){
var user = Session.getActiveUser().getEmail();
var key = object.Key;
send(key);
}
function send(k){
var ss =
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastR = ss.GetLastRow();
ss.GetRange(lastR,1).SetValue(k);
}
On your html button you will need to have inside the tags
onClick="google.script.run
.withSuccessHandler(Success)
.process(this.parentNode);"
In order for this to work, obviously you will need to have your fields named accordingly.
Edit: The only thing I did not include in the code was a Success handler, which will be in your html of the GAS script. This should point you in a direction that can resolve that.
Hope this helps.

Check the form has saved or not in CRM 2011 Javascript

I'm writing a Javascript to call external link on click of custom ribbon button in CRM 2011 entity form. In javascript I'm checking the form is dirty or not. If the form is dirty,(means some fields are modified by user) then JScript will save the form forcefully using Xrm.Page.data.entity.save(). But, when the mandatory fields have not filled, force save will not be happened and I have to show some custom message to fill those fields, terminate the flow of control and should not open the external link. How to get whether the form has saved or not..?
Piece of code as below:
function buttonOnClick() {
if (Xrm.Page.data.entity.getIsDirty())
{
Xrm.Page.data.entity.save();
}
else
{
window.open('http://www.google.com', 'name', 'width=900,height=800');
}
}
When you say 'form has been saved' do you mean for the first time? If so you can query the form type:-
Xrm.Page.ui.getFormType();
(Is it in Create or Update for example). If the form is already in Update mode then you can check if the form is dirty as you say. If you want to know which mandatory fields have not been completed you can also potentially loop over the attributes on the form and query whether they are Business Required or not:-
Xrm.Page.data.entity.attributes.get("myAttribute").getRequiredLevel();
and add this to a warning message to the user.
You could add your own OnSave method to validate the fields and return a value based on whether they are valid or not.
e.g.
Xrm.Page.data.entity.addOnSave(function() {
var isValid = VerifyOnSave();
if (isValid) {
//continue
}
else {
//show errors, cancel save
}
);
function VerifyOnSave()
{
//<insert validation logic here>
return true;
}
That doesn't explicitly tell you the form saved, but lets you know whether the form is valid, which may or may not be close enough.
You could try this way:
var entitySaved;
function OnLoad(){
entitySaved=false;
}
function OnSave(){
entitySaved=true;
}
function myFunction(){
if(entitySaved){
//do your logic here
}
}
Of course, you will have to add the form events from your CRM solution, by clicking in form properties.

Categories

Resources